// Ticket Forensics Gantt · lead feature.
// End-to-end per-ticket timeline. Each stage segment splits into active work
// (solid) vs queue / wait (diagonal hatch). Below each ticket bar: a thin AI /
// hand-written authorship band. Commits dot the dev/rework segments.

// Long-form phase names for the stage hover tooltip.
const GANTT_STAGE_LONG = { dev: 'Development', review: 'Code review', rework: 'Rework', bug: 'Bug fix', deploy: 'Deploy' };

function GanttForensics({ navigate, rows, days, startDay, compact = false, showWindowChip = false }) {
  // Window-size pref drives the default rows when none are passed in.
  const [weeks, setWeeks] = useWindowPref('gantt', DATA.DEFAULT_WEEKS);

  // Window: startDay (negative = past) to startDay + days
  const defaultRows = rows || DATA.ganttRowsFor(weeks);
  rows = defaultRows;
  days = days || DATA.ganttDays;
  startDay = startDay !== undefined ? startDay : DATA.ganttStartDay;
  // Anchor today (day 0) at the right edge of the timeline.
  if (startDay < 0) days = -startDay;

  const [hoverCommit, setHoverCommit] = useState(null);
  const [hoverSeg, setHoverSeg] = useState(null);
  const [tooltipPos, setTooltipPos] = useState({ x: 0, y: 0 });
  const [openCommit, setOpenCommit] = useState(null);

  const trackRef = useRef(null);
  const dayWidthPct = 100 / days;

  // Map dayOffset → percentage from start of track
  const toPct = (d) => Math.max(0, Math.min(100, ((d - startDay) / days) * 100));

  // Build axis labels · every 7 days for readability
  const axisLabels = [];
  const step = days >= 21 ? 7 : 4;
  for (let i = 0; i <= days; i += step) {
    const d = startDay + i;
    let label;
    if (d === 0) label = 'today';
    else if (d < 0) label = `${-d}d ago`;
    else label = `+${d}d`;
    axisLabels.push({ d, label, pct: (i / days) * 100 });
  }
  // Ensure "today" anchors the right edge of the axis when the window ends at day 0.
  if (startDay + days === 0 && !axisLabels.some(l => l.d === 0)) {
    axisLabels.push({ d: 0, label: 'today', pct: 100 });
  }

  return (
    <div className="card gantt-card" style={{ '--gantt-days': days }}>
      <div className="card-head" style={{ padding: 0, marginBottom: 10 }}>
        <div>
          <div className="ch-eyebrow">Ticket forensics · last {showWindowChip ? weeks * 7 : Math.round(days)} days window</div>
          <div className="ch-title" style={{ marginTop: 4 }}>
            <Icon name="git-branch" size={13} />
            <span>End-to-end lifecycle</span>
          </div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <span className="mono" style={{ color: 'var(--text-3)', fontSize: 11 }}>
            Click bar → ticket · hover stage / commit → details
          </span>
          {showWindowChip && <WindowSizeChip value={weeks} onChange={setWeeks} />}
        </div>
      </div>

      <div className="gantt">
        {/* Header row with day axis */}
        <div className="gantt-head" style={{ position: 'relative' }}>
          <div style={{ padding: '0 4px' }}>Ticket</div>
          <div style={{ position: 'relative', height: 18 }}>
            {axisLabels.map((l, i) => (
              <span key={i} style={{
                position: 'absolute',
                left: l.pct + '%',
                transform: l.pct >= 100 ? 'translateX(-100%)' : undefined,
                color: l.d === 0 ? 'var(--accent)' : 'var(--text-3)',
                fontWeight: l.d === 0 ? 600 : undefined,
              }}>{l.label}</span>
            ))}
          </div>
        </div>

        {/* Rows */}
        {rows.map(t => {
          const dev = DATA.devById(t.assignee);
          const totalLen = t.history.reduce((a, s) => a + (s.endDay - s.startDay), 0);
          const aiSum = (t.commits || []).reduce((a, c) => a + (c.aiPct || 0), 0);
          const aiAvg = t.commits && t.commits.length ? Math.round(aiSum / t.commits.length) : 0;
          return (
            <div key={t.id} className="gantt-row">
              <div className="gantt-row-label">
                <div className="grl-top">
                  <span className="grl-key">{t.id}</span>
                  {dev && <Avatar initials={dev.initials} size={18} />}
                </div>
                <div className="grl-title" title={t.title}>{t.title}</div>
                <div className="grl-bottom">
                  <span className="tag mono tone-accent">AI {aiAvg}%</span>
                  <span className="mono" style={{ fontSize: 10, color: 'var(--text-3)' }}>{(t.commits || []).length} commits</span>
                </div>
              </div>

              <div className="gantt-track" ref={trackRef}>
                <div className="gt-bg" />
                {/* Dashed day gridlines */}
                <div className="gt-grid">
                  {Array.from({ length: days }).map((_, i) => <span key={i} />)}
                </div>

                {/* Stage segments */}
                {t.history.map((seg, i) => {
                  const left = toPct(seg.startDay);
                  const width = toPct(seg.endDay) - toPct(seg.startDay);
                  if (width <= 0) return null;
                  // Use exclusive end so commits on a segment boundary don't get double-counted.
                  // Allow inclusive end on the final segment so trailing commits aren't dropped.
                  const isLast = i === t.history.length - 1;
                  const segCommits = (t.commits || []).filter(c =>
                    c.dayOffset >= seg.startDay && (isLast ? c.dayOffset <= seg.endDay : c.dayOffset < seg.endDay)
                  );
                  const segAi = segCommits.length
                    ? Math.round(segCommits.reduce((a, c) => a + (c.aiPct || 0), 0) / segCommits.length)
                    : null;
                  const showLabel = segAi !== null && width >= 3;
                  return (
                    <div key={i} className="gantt-bar"
                         style={{ left: `calc(${left}% + 2px)`, width: `calc(${width}% - 4px)`, minWidth: 14 }}
                         onClick={() => navigate('#/ticket/' + t.id)}
                         onMouseEnter={(e) => {
                           setHoverSeg({ seg, segAi, ticketId: t.id });
                           const r = e.currentTarget.getBoundingClientRect();
                           const tr = trackRef.current?.getBoundingClientRect();
                           setTooltipPos({ x: r.left - (tr?.left || 0) + 8, y: -48 });
                         }}
                         onMouseLeave={() => setHoverSeg(null)}>
                      <div className={`gantt-seg seg-${seg.stage}`} style={{ flexBasis: '100%' }} />
                      {showLabel && <span className="gantt-seg-ai">AI {segAi}%</span>}
                    </div>
                  );
                })}

                {/* Commits */}
                {(t.commits || []).map((c, ci) => {
                  const cx = toPct(c.dayOffset);
                  return (
                    <div key={ci}
                         className={`gantt-commit ${c.aiPct > 50 ? 'is-ai' : ''}`}
                         style={{ left: cx + '%', '--cx': cx + '%' }}
                         onMouseEnter={(e) => {
                           setHoverCommit({ commit: c, ticket: t });
                           const r = e.currentTarget.getBoundingClientRect();
                           const tr = trackRef.current?.getBoundingClientRect();
                           setTooltipPos({ x: r.left - (tr?.left || 0) + 10, y: -90 });
                         }}
                         onMouseLeave={() => setHoverCommit(null)}
                         onClick={(e) => { e.stopPropagation(); setOpenCommit({ commit: c, ticketId: t.id }); }}
                    />
                  );
                })}

                {/* Stage tooltip · names the phase under the cursor */}
                {hoverSeg && hoverSeg.ticketId === t.id && (
                  <div className="stage-tip" style={{ left: tooltipPos.x, top: tooltipPos.y }}>
                    <div className="st-name">
                      <span className="st-swatch" style={{ background: `var(--ph-${hoverSeg.seg.stage})` }} />
                      <span>
                        {GANTT_STAGE_LONG[hoverSeg.seg.stage] || hoverSeg.seg.stage}
                        {hoverSeg.seg.stage === 'bug' && hoverSeg.seg.caughtAt ? ` · caught in ${hoverSeg.seg.caughtAt}` : ''}
                      </span>
                    </div>
                    <div className="st-meta">
                      {hoverSeg.seg.activeDays}d active
                      {hoverSeg.seg.queueDays ? ` · ${hoverSeg.seg.queueDays}d queue` : ''}
                      {hoverSeg.segAi !== null ? ` · AI ${hoverSeg.segAi}%` : ''}
                    </div>
                  </div>
                )}

                {/* Commit tooltip */}
                {hoverCommit && hoverCommit.ticket.id === t.id && (
                  <div className="commit-tip" style={{ left: tooltipPos.x, top: tooltipPos.y }}>
                    <div className="ct-head">
                      <Icon name="git-commit" size={12} />
                      <span className="mono" style={{ fontSize: 10, color: 'var(--text-3)' }}>{hoverCommit.commit.sha.slice(0, 7)}</span>
                    </div>
                    <div className="ct-msg">{hoverCommit.commit.message}</div>
                    <div className="ct-meta">
                      <span style={{ color: 'var(--accent)' }}>AI {hoverCommit.commit.aiPct}%</span>
                      {hoverCommit.commit.tool && hoverCommit.commit.tool !== 'none' && (
                        <>
                          <span>·</span>
                          <span><Icon name="bot" size={10} style={{ verticalAlign: 'middle' }} /> {hoverCommit.commit.tool}</span>
                        </>
                      )}
                      {hoverCommit.commit.tool === 'none' && (
                        <>
                          <span>·</span>
                          <span style={{ color: 'var(--human)' }}><Icon name="pen" size={10} style={{ verticalAlign: 'middle' }} /> hand-written</span>
                        </>
                      )}
                    </div>
                    <div className="ct-files">
                      {hoverCommit.commit.files.map((f, fi) => <span key={fi}>{f}</span>)}
                    </div>
                  </div>
                )}
              </div>
            </div>
          );
        })}
      </div>

      <div className="gantt-legend">
        <div className="gantt-legend-item"><span className="gantt-legend-swatch seg-dev" /> Dev</div>
        <div className="gantt-legend-item"><span className="gantt-legend-swatch seg-review" /> Review</div>
        <div className="gantt-legend-item"><span className="gantt-legend-swatch seg-rework" /> Rework</div>
        <div className="gantt-legend-item"><span className="gantt-legend-swatch seg-bug" /> Bug</div>
        <div className="gantt-legend-item"><span className="gantt-legend-swatch seg-deploy" /> Deploy</div>
      </div>
      {openCommit && <CommitDetail commit={openCommit.commit} ticketId={openCommit.ticketId} onClose={() => setOpenCommit(null)} />}
    </div>
  );
}

window.GanttForensics = GanttForensics;
