// Post-PR rework · Risk Hotspots card.
// Purpose: surface *who* is asked to redo work most often (and the bad
// patterns behind it) so an EM/PM can act on the right culprit — while
// keeping evidence.
//
// Section order mirrors the Defects card (people → where → evidence):
//   1. Header — total + window filter
//   2. People — developers ranked by rework count, with bad-pattern tags
//   3. Hot modules — slim strip showing where rework concentrates
//   4. Recent evidence — condensed rework rows (max 4)

const RW_TEAM_OF_MODULE = {
  payments: 'Payments Core',
  webhooks: 'Payments Core',
  idempotency: 'Payments Core',
  auth: 'Auth & Identity',
  disputes: 'Disputes & Risk',
  refunds: 'Disputes & Risk',
  tests: null,
};
const RW_TEAM_COLOR = {
  'Payments Core': 'var(--accent)',
  'Auth & Identity': 'var(--good)',
  'Disputes & Risk': 'var(--warn)',
  'Unassigned': 'var(--text-3)',
};
const rwModuleOf = (p) => (p || '').split('/')[0] || 'other';

function ReworkStatsWidget({ navigate }) {
  const [weeks, setWeeks] = useWindowPref('reworkStats.weeks', DATA.DEFAULT_WEEKS);

  // Build rework rows from existing dummy data (mirrors prior implementation).
  const rows = useMemo(() => {
    const startOffset = -(weeks * 7 - 1);
    const endOffset = 0;
    const out = [];
    for (const t of DATA.tickets) {
      const segs = t.history || [];
      let rework = null;
      for (const s of segs) if (s.stage === 'rework') rework = s;
      if (!rework) continue;
      if (rework.endDay < startOffset || rework.startDay > endOffset) continue;

      const devSeg = segs.find(s => s.stage === 'dev');
      const commits = t.commits || [];
      const devCommits = devSeg
        ? commits.filter(c => c.dayOffset >= devSeg.startDay && c.dayOffset <= devSeg.endDay)
        : commits;
      const avgFirstPassAi = devCommits.length
        ? Math.round(devCommits.reduce((a, c) => a + (c.aiPct || 0), 0) / devCommits.length)
        : 0;
      const aiHeavyFirstPass = avgFirstPassAi >= 70;

      out.push({
        ticket: t,
        reworkSegment: rework,
        avgAi: avgFirstPassAi,
        aiHeavyFirstPass,
      });
    }
    out.sort((a, b) => Math.min(b.reworkSegment.endDay, 0) - Math.min(a.reworkSegment.endDay, 0));
    return out;
  }, [weeks]);

  const total = rows.length;
  const titleTone = total >= 6 ? 'bad' : total >= 3 ? 'warn' : 'good';

  // Aggregate signals: per author, per file, per module.
  const agg = useMemo(() => {
    const byAuthor = new Map();    // id → { count }
    const byFile = new Map();      // path → count
    const byModule = new Map();    // module → { count, files }
    for (const r of rows) {
      const a = r.ticket.assignee;
      const aRec = byAuthor.get(a) || { count: 0 };
      aRec.count++;
      byAuthor.set(a, aRec);

      const seenFiles = new Set();
      (r.ticket.commits || []).forEach(c => (c.files || []).forEach(f => seenFiles.add(f)));
      const seenModules = new Set();
      for (const f of seenFiles) {
        byFile.set(f, (byFile.get(f) || 0) + 1);
        seenModules.add(rwModuleOf(f));
      }
      for (const m of seenModules) {
        const mRec = byModule.get(m) || { count: 0, files: new Map() };
        mRec.count++;
        byModule.set(m, mRec);
      }
      // Track per-module file frequencies (use seenFiles, not multiplied by module count).
      for (const f of seenFiles) {
        const m = rwModuleOf(f);
        const mRec = byModule.get(m);
        if (!mRec) continue;
        mRec.files.set(f, (mRec.files.get(f) || 0) + 1);
      }
    }
    return { byAuthor, byFile, byModule };
  }, [rows]);

  // Developers (asked to rework) — top 4, who is reworked most.
  const devRows = useMemo(() => {
    const arr = [...agg.byAuthor.entries()].map(([id, v]) => ({ id, ...v }));
    arr.sort((a, b) => b.count - a.count);
    const maxCount = arr[0]?.count || 1;
    return arr.slice(0, 4).map(r => ({ ...r, pct: Math.round((r.count / maxCount) * 100) }));
  }, [agg.byAuthor]);

  // Hot modules — top 4 by rework-cycle count.
  const moduleRows = useMemo(() => {
    const arr = [...agg.byModule.entries()].map(([mod, v]) => {
      const topFileEntry = [...v.files.entries()].sort((a, b) => b[1] - a[1])[0];
      return {
        module: mod,
        count: v.count,
        topFile: topFileEntry ? topFileEntry[0] : null,
        topFileCount: topFileEntry ? topFileEntry[1] : 0,
        team: RW_TEAM_OF_MODULE[mod] || 'Unassigned',
      };
    });
    arr.sort((a, b) => b.count - a.count);
    const maxCount = arr[0]?.count || 1;
    return arr.slice(0, 4).map(r => ({ ...r, pct: Math.round((r.count / maxCount) * 100) }));
  }, [agg.byModule]);

  const listRows = rows.slice(0, 4);
  const filenameOnly = (p) => p.split('/').slice(-1)[0];

  const SectionLabel = ({ text, right }) => (
    <div style={{
      padding: '12px 16px 8px',
      display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
    }}>
      <span className="mono-caps" style={{ fontSize: 10, color: 'var(--text-3)', letterSpacing: '0.08em' }}>
        {text}
      </span>
      {right && <span className="mono" style={{ fontSize: 10.5, color: 'var(--text-3)' }}>{right}</span>}
    </div>
  );

  return (
    <div className="card">
      <div className="card-head">
        <div>
          <div className="ch-eyebrow">Post-PR rework · last {weeks * 7}d</div>
          <div className="ch-title" style={{ marginTop: 4 }}>
            <Icon name="shuffle" size={13} style={{ color: 'var(--' + titleTone + ')' }} />
            <span>{total} ticket{total === 1 ? '' : 's'} reworked</span>
          </div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span className="mono" style={{ color: 'var(--text-3)', fontSize: 11 }}>
            Who & where to focus
          </span>
          <WindowSizeChip value={weeks} onChange={setWeeks} options={[2, 4, 8, 12]} />
        </div>
      </div>

      {/* ─── Empty state ───────────────────────────────────────────────── */}
      {total === 0 && (
        <div style={{ borderTop: '1px solid var(--border)', padding: '14px 16px', color: 'var(--text-3)', fontSize: 12.5 }}>
          No rework cycles in this window · clean run
        </div>
      )}

      {/* ─── People · who is reworked most ─────────────────────────────── */}
      {total > 0 && (
        <div style={{ borderTop: '1px solid var(--border)', padding: '12px 16px 14px' }}>
          <div className="mono-caps" style={{ fontSize: 10, color: 'var(--text-3)', letterSpacing: '0.08em', marginBottom: 10 }}>
            Developers · most reworked
          </div>
          <div style={{ display: 'grid', gap: 10 }}>
            {devRows.map(d => {
              const dev = DATA.devById(d.id);
              if (!dev) return null;
              return (
                <div
                  key={d.id}
                  className="clickable"
                  onClick={() => navigate('#/profile/' + d.id)}
                  style={{ cursor: 'pointer', display: 'grid', gridTemplateColumns: '24px minmax(0,1fr) auto', gap: 10, alignItems: 'center' }}
                  title={`${dev.name} · ${d.count} reworked`}
                >
                  <Avatar initials={dev.initials} size={22} />
                  <div style={{ minWidth: 0 }}>
                    <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 6 }}>
                      <span style={{ fontSize: 12.5, color: 'var(--text)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                        {dev.name}
                      </span>
                      <span className="mono" style={{ fontSize: 11.5, color: 'var(--text-2)', flex: '0 0 auto' }}>{d.count}</span>
                    </div>
                    <div style={{ height: 4, background: 'var(--surface-3)', borderRadius: 2, marginTop: 5, overflow: 'hidden' }}>
                      <div style={{ width: d.pct + '%', height: '100%', background: d.count >= 2 ? 'var(--warn)' : 'var(--accent)' }} />
                    </div>
                  </div>
                  <Icon name="chevron-right" size={12} style={{ color: 'var(--text-3)' }} />
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* ─── Hot modules strip · where ─────────────────────────────────── */}
      {moduleRows.length > 0 && (
        <div style={{ borderTop: '1px solid var(--border)', padding: '10px 16px 12px' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
            <span className="mono-caps" style={{ fontSize: 10, color: 'var(--text-3)', letterSpacing: '0.08em', flex: '0 0 auto' }}>
              Hot modules
            </span>
            {moduleRows.map(m => {
              const color = RW_TEAM_COLOR[m.team] || 'var(--accent)';
              return (
                <span
                  key={m.module}
                  className="tag mono"
                  style={{ display: 'inline-flex', alignItems: 'center', gap: 5, color, borderColor: 'var(--border)', background: 'var(--surface-3)' }}
                  title={`${m.module}/ · ${m.count} rework cycle${m.count === 1 ? '' : 's'} · ${m.team}${m.topFile ? ' · top: ' + filenameOnly(m.topFile) : ''}`}
                >
                  <Icon name="flame" size={10} />
                  <span style={{ color: 'var(--text-2)' }}>{m.module}/</span>
                  <span style={{ color }}>·</span>
                  <span>×{m.count}</span>
                </span>
              );
            })}
          </div>
        </div>
      )}

      {/* ─── Recent evidence ────────────────────────────────────────────── */}
      {total > 0 && (
        <div style={{ borderTop: '1px solid var(--border)' }}>
          <SectionLabel
            text="Recent evidence"
            right={`${Math.min(4, listRows.length)} of ${total} · click to open ticket`}
          />
          {listRows.map(r => {
            const t = r.ticket;
            const dev = DATA.devById(t.assignee);
            const daysAgo = Math.max(0, -r.reworkSegment.endDay);
            const repeat = (agg.byAuthor.get(t.assignee)?.count || 0) >= 2;
            const ticketFiles = new Set();
            (t.commits || []).forEach(c => (c.files || []).forEach(f => ticketFiles.add(f)));
            const matchedFile = Array.from(ticketFiles).find(f => (agg.byFile.get(f) || 0) >= 2);

            const chips = [];
            if (r.aiHeavyFirstPass) chips.push({ key: 'ai', tone: 'warn', icon: 'bot', label: `AI ${r.avgAi}%` });
            if (repeat) chips.push({ key: 're', tone: 'warn', icon: 'user', label: 'Repeat' });
            if (matchedFile) chips.push({ key: 'hf', tone: 'accent', icon: 'flame', label: filenameOnly(matchedFile) });

            return (
              <div
                key={t.id}
                className="clickable"
                onClick={() => navigate('#/ticket/' + t.id)}
                style={{
                  display: 'grid',
                  gridTemplateColumns: 'minmax(0, 1fr) auto',
                  gap: 10,
                  padding: '6px 16px',
                  cursor: 'pointer',
                  borderTop: '1px solid var(--border)',
                }}
              >
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
                  <span className="mono" style={{ color: 'var(--text-3)', fontSize: 11.5, flex: '0 0 auto' }}>{t.id}</span>
                  <span style={{
                    fontSize: 12.5, color: 'var(--text)',
                    whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', minWidth: 0,
                  }} title={t.title}>
                    {t.title}
                  </span>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
                  {chips.slice(0, 3).map(c => (
                    <span key={c.key} className={`tag mono tone-${c.tone}`} style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
                      <Icon name={c.icon} size={10} />
                      <span>{c.label}</span>
                    </span>
                  ))}
                  {dev && (
                    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }} title={`Author · ${dev.name}`}>
                      <Avatar initials={dev.initials} size={20} />
                    </span>
                  )}
                  <span className="mono" style={{ fontSize: 11, color: 'var(--text-3)', minWidth: 44, textAlign: 'right' }}>
                    {daysAgo === 0 ? 'today' : daysAgo + 'd ago'}
                  </span>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

window.ReworkStatsWidget = ReworkStatsWidget;
