/* project-planning.jsx — REDESIGNED Planning tab (Todos moved to the Board tab).
   ─────────────────────────────────────────────────────────────────────────────
   Drop-in replacement for the old project-planning.jsx. The editable todo draft
   now lives in useProjectPlanning() (project-planning-state.jsx) and is passed in
   as `planning`, shared with <ProjectBoardTab>. This file renders ONLY the
   planning surface that remains:
       Feature/section selector · Section progress (ring + tiles) · Requirements
       · Milestones (now the hero) · Documents.

   Signature (called from project-detail.jsx):
     <ProjectPlanningExec planning={planning} project={project} db={db}
        onDrawer={onDrawer} onAction={onAction} DocumentsPanel={DocumentsPanel} Inline={Inline} />

   Milestones persist immediately (unchanged contract):
     toggle  → onAction('toggleProjectMilestone',  { project, milestoneId })
     reorder → onAction('reorderProjectMilestone', { project, milestoneId, direction })
     delete  → onAction('deleteProjectMilestone',  { ...milestone, projectId })
     edit    → onDrawer('projectMilestone', milestoneId, { projectId })
     add     → onDrawer('projectMilestone', null, { projectId, planningSectionId })

   Requirements + section names live in the shared draft and save via the planning
   Save bar (rendered by the shell). Requires Icon, Panel, Pill (ui.jsx) and the
   pd-/ms-/ring-/req-block styles already in project-detail.css.
   Exports: window.ProjectPlanningExec
   ───────────────────────────────────────────────────────────────────────────── */
(function () {
  const { useState } = React;
  const { money, fmtDate, TODAY } = window.AC;
  const MODEL = window.MODEL;
  const REQUIREMENT_TYPES = ['UI/UX', 'Backend', 'Data', 'Integration', 'QA', 'Operations'];
  const REQUIREMENT_STATUSES = ['draft', 'accepted', 'implemented'];
  const decimal = (v) => { const n = Number(v); return Number.isFinite(n) ? n.toString() : '0'; };
  const milestoneEstimatedCost = (m) => (Number(m.estimatedHours) || 0) * (Number(m.hourlyRate) || 0);
  const milestoneInvoiceAmount = (m) => (Number(m.actualCost) || 0) || ((Number(m.actualHours) || 0) * (Number(m.hourlyRate) || 0)) || milestoneEstimatedCost(m);
  const today = (MODEL && MODEL.TODAY) || TODAY;

  /* progress ring — two circles only (reuses window.ProgressRing if present) */
  function Ring({ value, size = 104, stroke = 9 }) {
    if (window.ProgressRing) return <window.ProgressRing value={value} size={size} label="done" />;
    const r = (size - stroke) / 2, c = 2 * Math.PI * r, pct = Math.max(0, Math.min(1, value));
    return (
      <div className="ring" style={{ width: size, height: size }}>
        <svg width={size} height={size}>
          <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke="var(--surface-3)" strokeWidth={stroke} />
          <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke={pct >= 1 ? 'var(--pos)' : 'var(--primary)'} strokeWidth={stroke}
            strokeLinecap="round" strokeDasharray={c} strokeDashoffset={c * (1 - pct)}
            transform={`rotate(-90 ${size / 2} ${size / 2})`} style={{ transition: 'stroke-dashoffset .4s ease' }} />
        </svg>
        <div className="ring-center"><div className="ring-pct" style={{ fontSize: size * 0.26 }}>{Math.round(pct * 100)}%</div><div className="ring-sub">done</div></div>
      </div>
    );
  }

  function RequirementsPanel({ active, planning, onDrawer }) {
    const items = Array.isArray(active.requirementItems) ? active.requirementItems : [];
    const titled = items.filter((item) => item.title);
    const first = titled[0];
    const counts = REQUIREMENT_STATUSES.map((status) => ({
      status,
      count: titled.filter((item) => (item.status || 'draft') === status).length,
    })).filter((item) => item.count);
    const edit = () => onDrawer('projectRequirements', null, {
      sectionName: active.name,
      requirementItems: items,
      onApply: (form) => planning.patchSection(active.id, { requirementItems: form.items || [] }),
    });
    return (
      <Panel title="Requirements" sub={`${titled.length} item${titled.length === 1 ? '' : 's'}`}
        actions={<button className="btn sm ghost" onClick={edit}><Icon name="edit" size={14} />Edit</button>}>
        <button className="req-summary" type="button" onClick={edit}>
          <div className="req-summary-title">{first ? first.title : 'No requirements yet'}</div>
          <div className="req-summary-meta">
            {first ? <React.Fragment><span className="chip">{first.type || 'UI/UX'}</span><span className="chip">{first.priority || 'Medium'}</span></React.Fragment> : <span className="muted">Open the editor to add requirement items.</span>}
            {counts.map((item) => (
              <span className="chip" key={item.status}>{item.count} {item.status}</span>
            ))}
            {titled.length > 1 && <span className="chip">+{titled.length - 1} more</span>}
          </div>
        </button>
      </Panel>
    );
  }

  /* ---------- milestone row (unchanged contract: onAction / onDrawer) ---------- */
  function MilestoneRow({ project, milestone, todoStats, index, count, onAction, onDrawer }) {
    const m = milestone;
    const [docOver, setDocOver] = useState(false);
    const docTarget = { milestoneId: m.id };
    const docs = window.projectDocumentsFor ? window.projectDocumentsFor(project, docTarget) : [];
    const dropProps = window.projectDocumentDropProps ? window.projectDocumentDropProps(project, onAction, docTarget, setDocOver) : {};
    const invAmt = milestoneInvoiceAmount(m);
    const overdue = !m.completed && m.dueDate && String(m.dueDate) < today;
    const total = todoStats.total, done = todoStats.done;
    const pct = total ? done / total : 0;
    const canFinish = m.completed || total === 0 || done === total;
    const status = m.completed ? 'Completed'
      : todoStats.blocked > 0 ? 'Blocked'
        : total > 0 && done === total ? 'Ready to finish'
          : done > 0 ? 'Partly completed'
            : overdue ? 'Overdue' : 'Open';
    const hasEffort = m.estimatedHours > 0 || m.actualHours > 0 || m.hourlyRate > 0 || m.actualCost > 0;
    const hoursPct = m.estimatedHours > 0 ? Math.min(1, (m.actualHours || 0) / m.estimatedHours) : 0;
    return (
      <div className={'ms-row' + (m.completed ? ' done' : '') + (docOver ? ' doc-over' : '')} {...dropProps}>
        <div className="ms-row-top">
          <input className="pd-check ms-row-check" type="checkbox" title={canFinish ? 'Mark complete' : 'Finish assigned todos first'}
            disabled={!canFinish} checked={!!m.completed} onChange={() => onAction('toggleProjectMilestone', { project, milestoneId: m.id })} />
          <span style={{ flex: 1, minWidth: 0, fontWeight: 600, textDecoration: m.completed ? 'line-through' : 'none', color: m.completed ? 'var(--muted)' : 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis' }}>{m.title}</span>
          <Pill kind={status} sm />
          {m.dueDate && <span className={'chip' + (overdue ? ' warn' : '')}><Icon name="clock" size={11} />{fmtDate(m.dueDate)}</span>}
          <span className="ms-row-tools">
            <button className="icon-btn" title="Move up" disabled={index === 0} onClick={() => onAction('reorderProjectMilestone', { project, milestoneId: m.id, direction: -1 })}><Icon name="arrowUp" size={14} /></button>
            <button className="icon-btn" title="Move down" disabled={index === count - 1} onClick={() => onAction('reorderProjectMilestone', { project, milestoneId: m.id, direction: 1 })}><Icon name="arrowDown" size={14} /></button>
            <button className="icon-btn" title="Edit milestone" onClick={() => onDrawer('projectMilestone', m.id, { projectId: project.id })}><Icon name="edit" size={14} /></button>
            <button className="icon-btn" title="Delete milestone" onClick={() => onAction('deleteProjectMilestone', { ...m, projectId: project.id })}><Icon name="trash" size={14} /></button>
          </span>
        </div>
        <div className="ms-row-todos">
          {total > 0 ? (
            <React.Fragment>
              <span className="progressbar" style={{ width: 86 }}><span style={{ width: (pct * 100) + '%', background: done === total ? 'var(--pos)' : 'var(--primary)' }} /></span>
              <span className="chip">{done}/{total} todos</span>
              <span className={'chip ' + (canFinish ? 'pos' : 'warn')}>{canFinish ? 'Can finish' : 'Needs todo work'}</span>
            </React.Fragment>
          ) : <span className="muted" style={{ fontSize: 12 }}>No assigned todos.</span>}
        </div>
        <div className="ms-row-effort">
          {hasEffort ? (
            <React.Fragment>
              {m.estimatedHours > 0 && <span className="chip">Est. {decimal(m.estimatedHours)}h</span>}
              {m.actualHours > 0 && <span className="chip">Actual {decimal(m.actualHours)}h</span>}
              {m.hourlyRate > 0 && <span className="chip">{money(m.hourlyRate)}/h</span>}
              {invAmt > 0 && <span className="chip">{money(invAmt)}</span>}
              {m.estimatedHours > 0 && <span className="ms-hours" title={`${decimal(m.actualHours || 0)}h of ${decimal(m.estimatedHours)}h`}><span style={{ width: (hoursPct * 100) + '%', background: hoursPct >= 1 ? 'var(--warn)' : 'var(--primary)' }} /></span>}
            </React.Fragment>
          ) : <span className="muted" style={{ fontSize: 12 }}>No effort logged.</span>}
          {docs.map((doc) => (
            <button key={doc.id} type="button" className="chip pd-docchip" title={doc.fileName} onClick={() => onAction('openProjectDocument', { projectId: project.id, documentId: doc.id })}>
              <Icon name="doc" size={11} />{doc.fileName}
            </button>
          ))}
        </div>
      </div>
    );
  }

  /* ---------- the Planning tab ---------- */
  function ProjectPlanningExec({ planning, project, db, onDrawer, onAction, DocumentsPanel, Inline }) {
    const { draft, active, setActiveId } = planning;
    if (!active) return <Panel title="Planning"><span className="muted">No planning sections.</span></Panel>;

    const sectionMs = (project.milestones || []).filter((m) => m.planningSectionId === active.id || (!m.planningSectionId && active.position === 0));
    const doneMs = sectionMs.filter((m) => m.completed).length;
    const estH = sectionMs.reduce((s, m) => s + (Number(m.estimatedHours) || 0), 0);
    const actH = sectionMs.reduce((s, m) => s + (Number(m.actualHours) || 0), 0);
    const cats = planning.cats;
    const todoStatsByMilestone = cats.reduce((stats, cat) => {
      cat.items.forEach((item) => {
        if (!item.milestoneId) return;
        const cur = stats[item.milestoneId] || { total: 0, done: 0, blocked: 0 };
        cur.total += 1;
        if (item.done) cur.done += 1;
        if (item.status === 'Blocked' || item.status === 'Missing info') cur.blocked += 1;
        stats[item.milestoneId] = cur;
      });
      return stats;
    }, {});
    const linked = sectionMs.reduce((a, m) => { const s = todoStatsByMilestone[m.id] || { total: 0, done: 0, blocked: 0 }; a.total += s.total; a.done += s.done; a.blocked += s.blocked; return a; }, { total: 0, done: 0, blocked: 0 });
    const msPct = sectionMs.length ? doneMs / sectionMs.length : 0;

    return (
      <div className="grid pl-tab">
        {/* feature / section context */}
        <div className="pl-sectionbar">
          <span className="pl-seclabel">Feature</span>
          <div className="segmented planning-sections" style={{ flexWrap: 'wrap' }}>
            {draft.map((s) => <button key={s.id} className={s.id === active.id ? 'on' : ''} onClick={() => setActiveId(s.id)}>{s.name}</button>)}
          </div>
          <button className="btn sm ghost" onClick={planning.addFeature}><Icon name="plus" size={14} />Feature</button>
          <span style={{ flex: 1 }} />
          <span className="pl-rename"><Icon name="edit" size={12} className="faint" /><Inline value={active.name} onCommit={(v) => planning.patchSection(active.id, { name: v })} style={{ fontWeight: 600 }} /></span>
        </div>

        {/* section progress */}
        <Panel title="Section progress" sub={`${active.name} · ${doneMs}/${sectionMs.length} milestones`}>
          <div className="ring-wrap">
            <Ring value={msPct} size={104} />
            <div className="pd-tiles" style={{ flex: 1, gridTemplateColumns: 'repeat(4, 1fr)' }}>
              <div className="pd-tile"><div className="k">Milestones</div><div className="v">{doneMs}/{sectionMs.length}</div></div>
              <div className="pd-tile"><div className="k">Effort</div><div className="v">{decimal(actH)}<span className="faint" style={{ fontSize: 11 }}> / {decimal(estH)}h</span></div></div>
              <div className="pd-tile"><div className="k">Linked todos</div><div className="v">{linked.done}/{linked.total}</div></div>
              <div className="pd-tile"><div className="k">Blocked</div><div className="v" style={linked.blocked ? { color: 'var(--neg)' } : null}>{linked.blocked}</div></div>
            </div>
          </div>
        </Panel>

        {/* milestones + requirements + feature documents */}
        <div className="grid pl-cols">
          <Panel title="Milestones" sub={`${doneMs}/${sectionMs.length} done${estH ? ` · ${decimal(actH)}h of ${decimal(estH)}h` : ''}`}
            actions={<button className="btn sm ghost" onClick={() => onDrawer('projectMilestone', null, { projectId: project.id, planningSectionId: active.id })}><Icon name="plus" size={14} />Milestone</button>}>
            <div style={{ display: 'grid', gap: 8 }}>
              {sectionMs.length ? sectionMs.map((m, i) => (
                <MilestoneRow key={m.id} project={project} milestone={m} todoStats={todoStatsByMilestone[m.id] || { total: 0, done: 0, blocked: 0 }} index={i} count={sectionMs.length} onAction={onAction} onDrawer={onDrawer} />
              )) : <span className="muted" style={{ fontSize: 12 }}>No milestones in this feature yet.</span>}
              <button className="ms-add" onClick={() => onDrawer('projectMilestone', null, { projectId: project.id, planningSectionId: active.id })}><Icon name="plus" size={14} /><span style={{ color: 'var(--muted)', fontWeight: 600 }}>Add milestone</span></button>
            </div>
          </Panel>

          <RequirementsPanel active={active} planning={planning} onDrawer={onDrawer} />

          <Panel title="Feature documents" sub={active.name}>
            {window.ProjectDocumentArea
              ? <window.ProjectDocumentArea project={project} target={{ planningSectionId: active.id }} onAction={onAction} empty="No documents attached to this feature." compact />
              : <span className="muted" style={{ fontSize: 12 }}>No documents attached to this feature.</span>}
          </Panel>
        </div>

        {/* documents (existing component, full width) */}
        <DocumentsPanel project={project} onAction={onAction} />
      </div>
    );
  }

  Object.assign(window, { ProjectPlanningExec });
})();
