// timeline.jsx — Roadmap / Gantt view for epics & sprints

const TL_ROW_H = 44;      // epic row height
const TL_PROJ_H = 29;     // project group header height

// Zoom → px per week
const TL_ZOOMS = {
  week:    { label: "Week",    pxPerWeek: 120 },
  month:   { label: "Month",   pxPerWeek: 54 },
  quarter: { label: "Quarter", pxPerWeek: 28 },
};

// ── Header (sticky) ─────────────────────────────────────────────
function TLHeaderRight({ pxPerWeek }) {
  return (
    <div className="tl-head-right" style={{ width: TL_WEEKS.length * pxPerWeek }}>
      <div className="tl-quarters">
        {TL_QUARTERS.map(q => (
          <div key={q.q} className="tl-q-cell" style={{ width: q.span * pxPerWeek }}>
            {q.label}
          </div>
        ))}
      </div>
      <div className="tl-months">
        {TL_MONTHS.map((m, i) => (
          <div key={i} className="tl-m-cell" style={{ width: m.span * pxPerWeek }}>
            <span>{m.month}</span>
            {i === 0 || TL_MONTHS[i-1].quarter !== m.quarter
              ? <span className="tl-m-year">2026</span>
              : null}
          </div>
        ))}
      </div>
    </div>
  );
}

// ── Left rail ─────────────────────────────────────────────────
function TLLeft({ groups, activeId, onHover }) {
  return (
    <div className="tl-chart-left">
      <div className="tl-head-left">
        <div className="tl-head-title">Initiatives</div>
        <div className="tl-head-sub">{TL_EPICS.length} epics · {groups.length} projects</div>
      </div>
      {groups.map(g => (
        <React.Fragment key={g.project.id}>
          <div className="tl-proj-group">
            <span className="tl-proj-dot" style={{ background: g.project.color }}/>
            <span className="tl-proj-name">{g.project.name}</span>
            <span className="tl-proj-count">{g.epics.length}</span>
          </div>
          {g.epics.map(ep => {
            const owner = PEOPLE.find(p => p.id === ep.owner);
            return (
              <div key={ep.id}
                   className={`tl-epic-row ${activeId === ep.id ? "is-active" : ""}`}
                   onMouseEnter={() => onHover?.(ep.id)}
                   onMouseLeave={() => onHover?.(null)}>
                <span className="tl-epic-handle" style={{ background: ep.color }}/>
                <span className="tl-epic-name">{ep.title}</span>
                {owner && <span className="tl-epic-owner"><Avatar person={owner} size="sm"/></span>}
              </div>
            );
          })}
        </React.Fragment>
      ))}
    </div>
  );
}

// ── Bars/deps body ─────────────────────────────────────────────
function TLBody({ groups, pxPerWeek, activeId, onHover, onBarClick }) {
  const totalW = TL_WEEKS.length * pxPerWeek;

  // Compute absolute y for each epic (for dep arrows)
  const yById = {};
  let y = 0;
  groups.forEach(g => {
    y += TL_PROJ_H;
    g.epics.forEach(ep => {
      yById[ep.id] = y + TL_ROW_H / 2;
      y += TL_ROW_H;
    });
  });
  const totalH = y;

  // Epic lookup
  const epicById = Object.fromEntries(TL_EPICS.map(e => [e.id, e]));
  const visibleIds = new Set(groups.flatMap(g => g.epics.map(e => e.id)));

  return (
    <div className="tl-body" style={{ width: totalW, minHeight: totalH }}>
      {/* Sprint ribbons across the very top */}
      {TL_SPRINTS.map(s => {
        const left = Math.max(0, s.start * pxPerWeek);
        const right = Math.min(TL_WEEKS.length, s.end) * pxPerWeek;
        const width = Math.max(0, right - left);
        if (width <= 0) return null;
        return (
          <div key={s.id}
               className={`tl-sprint-ribbon ${s.active ? "is-active" : ""} ${s.end <= TL_TODAY_WEEK ? "is-past" : ""}`}
               style={{ left, width }}>
            {s.label}
          </div>
        );
      })}

      {/* Week grid */}
      <div className="tl-week-lines"
           style={{
             backgroundImage: `linear-gradient(to right, var(--divider) 1px, transparent 1px)`,
             backgroundSize: `${pxPerWeek}px 100%`,
             backgroundRepeat: "repeat",
           }}/>

      {/* Today line */}
      <div className="tl-today-line" style={{ left: TL_TODAY_WEEK * pxPerWeek }}/>

      {/* Rows */}
      {groups.map(g => (
        <React.Fragment key={g.project.id}>
          <div className="tl-proj-group-row"/>
          {g.epics.map(ep => {
            const left = ep.start * pxPerWeek;
            const width = Math.max(28, (ep.end - ep.start) * pxPerWeek - 4);
            const fillW = width * ep.progress;
            const owner = PEOPLE.find(p => p.id === ep.owner);
            return (
              <div key={ep.id} className="tl-epic-lane">
                <div className={`tl-bar is-${ep.status}`}
                     style={{ left, width, background: ep.color }}
                     onMouseEnter={() => onHover?.(ep.id)}
                     onMouseLeave={() => onHover?.(null)}
                     onClick={() => onBarClick?.(ep)}>
                  <div className="tl-bar-fill" style={{ width: fillW }}/>
                  <div className="tl-bar-label">
                    <span className={`tl-bar-status ${ep.status}`}/>
                    <span>{ep.title}</span>
                  </div>
                  <span className="tl-bar-pct">{Math.round(ep.progress * 100)}%</span>
                  {owner && pxPerWeek >= 40 && (
                    <span className="tl-bar-owner"><Avatar person={owner} size="sm"/></span>
                  )}
                </div>
                {/* Milestones */}
                {ep.milestones?.map((m, i) => (
                  <div key={i} className="tl-milestone"
                       data-label={m.label}
                       style={{ left: m.week * pxPerWeek - 7 }}/>
                ))}
              </div>
            );
          })}
        </React.Fragment>
      ))}

      {/* Dependency arrows */}
      <svg className="tl-deps" width={totalW} height={totalH}>
        <defs>
          <marker id="tl-dep-arrow" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="7" markerHeight="7" orient="auto">
            <path d="M0,0 L8,4 L0,8 Z" className="tl-dep-head"/>
          </marker>
        </defs>
        {TL_DEPS.map((d, i) => {
          const from = epicById[d.from], to = epicById[d.to];
          if (!from || !to) return null;
          if (!visibleIds.has(from.id) || !visibleIds.has(to.id)) return null;
          const x1 = from.end * pxPerWeek - 2;
          const y1 = yById[from.id];
          const x2 = to.start * pxPerWeek;
          const y2 = yById[to.id];
          const midX = x1 + Math.max(14, (x2 - x1) / 2);
          const path = `M ${x1} ${y1} C ${midX} ${y1}, ${midX} ${y2}, ${x2} ${y2}`;
          return <path key={i} d={path} markerEnd="url(#tl-dep-arrow)"/>;
        })}
      </svg>
    </div>
  );
}

// ── Main page ─────────────────────────────────────────────
function TimelinePage() {
  const [zoom, setZoom] = React.useState("month");
  const [projectFilter, setProjectFilter] = React.useState("all");
  const [ownerFilter, setOwnerFilter] = React.useState("all");
  const [statusFilter, setStatusFilter] = React.useState("all");
  const [hoverId, setHoverId] = React.useState(null);
  const pxPerWeek = TL_ZOOMS[zoom].pxPerWeek;
  const scrollRef = React.useRef(null);

  const filtered = TL_EPICS.filter(e => {
    if (projectFilter !== "all" && e.project !== projectFilter) return false;
    if (ownerFilter !== "all" && e.owner !== ownerFilter) return false;
    if (statusFilter !== "all" && e.status !== statusFilter) return false;
    return true;
  });

  // Group by project, preserving PROJECTS order
  const groups = PROJECTS
    .map(p => ({ project: p, epics: filtered.filter(e => e.project === p.id) }))
    .filter(g => g.epics.length);

  // Auto-scroll so Today is visible on mount / zoom change
  React.useEffect(() => {
    if (!scrollRef.current) return;
    const targetX = TL_TODAY_WEEK * pxPerWeek - 180;
    scrollRef.current.scrollTo({ left: Math.max(0, targetX), behavior: "smooth" });
  }, [pxPerWeek]);

  // KPIs
  const kActive = TL_EPICS.filter(e => e.start <= TL_TODAY_WEEK && e.end > TL_TODAY_WEEK).length;
  const kAtRisk = TL_EPICS.filter(e => e.status === "at-risk" || e.status === "off-track").length;
  const kMilestones = TL_EPICS.flatMap(e => e.milestones || []).length;
  const kDone = Math.round(
    TL_EPICS.reduce((a, e) => a + e.progress, 0) / TL_EPICS.length * 100
  );

  return (
    <div className="tl-page">
      <div className="tl-header">
        <div className="tl-title-row">
          <div>
            <div className="tl-title">Timeline</div>
            <div className="tl-sub">Epics and initiatives across Q2–Q3 2026 · today is highlighted · drag future work to reshape the roadmap</div>
          </div>
          <div className="tl-kpis">
            <div className="tl-kpi"><span className="tl-kpi-label">Active</span><span className="tl-kpi-value">{kActive}</span></div>
            <div className={`tl-kpi ${kAtRisk ? "warn" : "good"}`}><span className="tl-kpi-label">At risk</span><span className="tl-kpi-value">{kAtRisk}</span></div>
            <div className="tl-kpi"><span className="tl-kpi-label">Milestones</span><span className="tl-kpi-value">{kMilestones}</span></div>
            <div className="tl-kpi"><span className="tl-kpi-label">Avg progress</span><span className="tl-kpi-value">{kDone}%</span></div>
          </div>
        </div>

        <div className="tl-toolbar">
          <div className="tl-zoom">
            {Object.keys(TL_ZOOMS).map(z => (
              <button key={z} className={zoom === z ? "is-active" : ""} onClick={() => setZoom(z)}>
                {TL_ZOOMS[z].label}
              </button>
            ))}
          </div>

          <div className="tl-filters">
            <select className={`tl-filter ${projectFilter !== "all" ? "has-value" : ""}`}
                    value={projectFilter} onChange={e => setProjectFilter(e.target.value)}>
              <option value="all">All projects</option>
              {PROJECTS.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
            </select>
            <select className={`tl-filter ${ownerFilter !== "all" ? "has-value" : ""}`}
                    value={ownerFilter} onChange={e => setOwnerFilter(e.target.value)}>
              <option value="all">All owners</option>
              {PEOPLE.filter(p => p.status !== "deactivated").map(p => (
                <option key={p.id} value={p.id}>{p.name.split(" ")[0]}</option>
              ))}
            </select>
            <select className={`tl-filter ${statusFilter !== "all" ? "has-value" : ""}`}
                    value={statusFilter} onChange={e => setStatusFilter(e.target.value)}>
              <option value="all">All statuses</option>
              <option value="on-track">On track</option>
              <option value="at-risk">At risk</option>
              <option value="off-track">Off track</option>
            </select>
          </div>

          <div style={{ flex: 1 }}/>

          <div className="tl-legend">
            <div className="tl-legend-item"><span className="tl-legend-dot" style={{ background: "var(--success)" }}/>On track</div>
            <div className="tl-legend-item"><span className="tl-legend-dot" style={{ background: "var(--warn)" }}/>At risk</div>
            <div className="tl-legend-item"><span className="tl-legend-dot" style={{ background: "var(--danger)" }}/>Off track</div>
            <div className="tl-legend-item"><span className="tl-legend-dot" style={{ background: "#0f1729", transform: "rotate(45deg)", borderRadius: 2 }}/>Milestone</div>
          </div>
        </div>
      </div>

      <div className="tl-chart" style={{ "--tl-row-h": `${TL_ROW_H}px` }}>
        <TLLeft groups={groups} activeId={hoverId} onHover={setHoverId}/>
        <div className="tl-chart-right" ref={scrollRef}>
          <TLHeaderRight pxPerWeek={pxPerWeek}/>
          <TLBody groups={groups} pxPerWeek={pxPerWeek}
                  activeId={hoverId} onHover={setHoverId}
                  onBarClick={ep => console.log("open epic", ep.id)}/>
        </div>
      </div>
    </div>
  );
}

// ── Standalone app for the design canvas ─────────────────
function TimelineApp() {
  const [paletteOpen, setPaletteOpen] = React.useState(false);
  React.useEffect(() => {
    const on = () => setPaletteOpen(true);
    window.addEventListener("palette:open", on);
    return () => window.removeEventListener("palette:open", on);
  }, []);

  return (
    <div className="app">
      <Sidebar activeProject={null}
               onOpenTickets={() => {}}
               timelineActive={true}
               currentUserId="ay"/>
      <div className="main">
        <Topbar crumbs={[WORKSPACE.name, "Timeline", "Q2–Q3 2026"]}
                searchValue="" onSearch={() => {}}
                onOpenPalette={() => setPaletteOpen(true)}
                currentUserId="ay" people={PEOPLE}/>
        <TimelinePage/>
      </div>
      <CommandPalette open={paletteOpen} onClose={() => setPaletteOpen(false)} onNavigate={() => {}}/>
    </div>
  );
}

Object.assign(window, { TimelineApp, TimelinePage });
