/* global React */
// redlines.jsx — unified redline strip + chip.
//
// A redline is a structured, fixable problem the backend has detected on an entity:
//   { kind, severity, title, summary, fix?: () => void, fixLabel?, meta? }
//
// Severity:  'block' | 'warn' | 'info'
//
// Surfaces:
//   <Redlines entity={ent} kind="agreement" go={go} /> — top-of-detail strip
//   <RedlineChip count n /> — inline list-row badge
//
// Sources are pluggable: window.__REDLINE_SOURCES.push(fn(entity, kind) => Redline[])
// Built-ins are wired below for territory_conflict (agreement) and
// localization_gap (work). Add more by pushing into __REDLINE_SOURCES.
//
// Export: window.Redlines, window.RedlineChip, window.collectRedlines
(function () {
  const SEV = {
    block: { label: 'BLOCK', color: 'var(--danger)' },
    warn:  { label: 'WARN',  color: 'var(--accent)' },
    info:  { label: 'INFO',  color: 'var(--ink-3)' },
  };

  // ─────────────────────────── Source registry
  window.__REDLINE_SOURCES = window.__REDLINE_SOURCES || [];

  function collectRedlines(entity, kind) {
    if (!entity) return [];
    const out = [];
    for (const src of window.__REDLINE_SOURCES) {
      try {
        const xs = src(entity, kind) || [];
        for (const r of xs) out.push(r);
      } catch (e) { /* swallow per-source errors */ }
    }
    // Stable severity order
    const rank = { block: 0, warn: 1, info: 2 };
    out.sort((a, b) => (rank[a.severity] ?? 9) - (rank[b.severity] ?? 9));
    return out;
  }

  // ─────────────────────────── Built-in: territory conflict on agreement
  window.__REDLINE_SOURCES.push(function territoryConflictSource(ag, kind) {
    if (kind !== 'agreement' || !ag || !window.TerritoryEngine) return [];
    const list = window.AGREEMENTS || [];
    const others = list.filter(x => x.id !== ag.id);
    const mk = (a) => (a.territories || []).map((t, i) => ({
      id: `${a.id}#${i}`, agreementId: a.id, name: a.id,
      selection: { mode: t.code === 'WW' ? 'world' : 'list', codes: t.code === 'WW' ? [] : [t.code], excludes: t.excluded || [] },
      rights: (t.rights || '').split(/[+,/·]/).map(s => s.trim()).filter(Boolean),
      start: a.start, end: a.end,
    }));
    const rows = [...mk(ag), ...others.flatMap(mk)];
    return window.TerritoryEngine.findConflicts(rows)
      .filter(c => c.a.startsWith(ag.id + '#') || c.b.startsWith(ag.id + '#'))
      .slice(0, 3)
      .map(c => {
        const otherId = c.a.startsWith(ag.id + '#') ? c.b.split('#')[0] : c.a.split('#')[0];
        return {
          kind: 'territory_conflict',
          severity: c.isos.length > 5 ? 'block' : 'warn',
          title: `Territory overlap with ${otherId}`,
          summary: `${c.isos.length} ISO · ${c.rights.join('+')} · resolve before next statement run`,
          fixLabel: 'Open ↔',
          fix: (go) => go && go('agreement', { id: otherId }),
          meta: { otherId, isos: c.isos, rights: c.rights },
        };
      });
  });

  // ─────────────────────────── Built-in: localization gap on work
  window.__REDLINE_SOURCES.push(function localizationGapSource(work, kind) {
    if (kind !== 'work' || !work) return [];
    // Synth: any work with iswc that doesn't have at least 2 alt-titles flags as gap
    const titles = work.altTitles || work.alt_titles || [];
    if (Array.isArray(titles) && titles.length >= 2) return [];
    const gaps = [
      { market: 'KR', script: 'Hangul',        loss: 4_812 },
      { market: 'JP', script: 'Katakana',      loss: 2_104 },
      { market: 'CN', script: 'Simp. Chinese', loss: 1_580 },
    ];
    return gaps.slice(0, 1).map(g => ({
      kind: 'localization_gap',
      severity: 'warn',
      title: `Missing ${g.market} title (${g.script})`,
      summary: `Estimated $${g.loss.toLocaleString()}/yr leakage from ${g.market} society payouts`,
      fixLabel: 'Translate',
      fix: (go) => go && go('localization', { tab: 'scripts' }),
      meta: g,
    }));
  });

  // ─────────────────────────── <Redlines entity kind go />
  function Redlines({ entity, kind, go, max }) {
    const redlines = collectRedlines(entity, kind);
    if (!redlines.length) return null;
    const shown = max ? redlines.slice(0, max) : redlines;
    const block = shown.some(r => r.severity === 'block');
    const tone = block ? 'var(--danger)' : 'var(--accent)';
    return (
      <div style={{
        border: `1px solid ${tone}`,
        background: `color-mix(in oklab, ${tone} 8%, var(--bg))`,
        padding: '12px 14px', marginBottom: 14,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
          <span className="ff-mono upper" style={{
            fontSize: 9, padding: '2px 6px', background: tone, color: 'var(--bg)',
            letterSpacing: '.12em', fontWeight: 600,
          }}>{redlines.length} REDLINE{redlines.length > 1 ? 'S' : ''}</span>
          <span className="ff-mono num" style={{ fontSize: 11, color: 'var(--ink-2)' }}>
            {redlines.filter(r => r.severity === 'block').length} block ·{' '}
            {redlines.filter(r => r.severity === 'warn').length} warn ·{' '}
            {redlines.filter(r => r.severity === 'info').length} info
          </span>
          <span style={{ flex: 1 }} />
          <button onClick={() => go && go('inbox', { tab: 'tasks' })} className="ff-mono upper"
            style={{ fontSize: 9, letterSpacing: '.1em', padding: '4px 8px',
              background: 'transparent', border: '1px solid var(--ink-3)', cursor: 'pointer' }}>
            ALL IN INBOX →
          </button>
        </div>
        {shown.map((r, i) => {
          const sev = SEV[r.severity] || SEV.info;
          return (
            <div key={i} style={{
              display: 'grid', gridTemplateColumns: '70px 1fr 110px',
              gap: 10, padding: '6px 0', alignItems: 'center', fontSize: 12,
              borderTop: i ? '1px solid var(--rule-soft)' : 'none',
            }}>
              <span className="ff-mono upper" style={{
                fontSize: 9, color: sev.color, letterSpacing: '.1em',
                border: `1px solid ${sev.color}`, padding: '2px 6px', textAlign: 'center',
              }}>{sev.label}</span>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontWeight: 600, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{r.title}</div>
                <div style={{ fontSize: 11, color: 'var(--ink-3)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{r.summary}</div>
              </div>
              {r.fix && (
                <button onClick={() => r.fix(go)} className="ff-mono upper" style={{
                  fontSize: 9, letterSpacing: '.1em', padding: '6px 8px',
                  background: 'var(--ink)', color: 'var(--bg)', border: 0, cursor: 'pointer',
                }}>{(r.fixLabel || 'Fix').toUpperCase()} →</button>
              )}
            </div>
          );
        })}
      </div>
    );
  }

  // ─────────────────────────── Inline chip for list rows
  function RedlineChip({ entity, kind }) {
    const n = collectRedlines(entity, kind).length;
    if (!n) return null;
    return (
      <span className="ff-mono upper" title={`${n} redline${n > 1 ? 's' : ''}`}
        style={{
          fontSize: 9, padding: '2px 5px', background: 'var(--danger)', color: 'var(--bg)',
          letterSpacing: '.1em', fontWeight: 600,
        }}>◆ {n}</span>
    );
  }

  window.Redlines = Redlines;
  window.RedlineChip = RedlineChip;
  window.collectRedlines = collectRedlines;
})();
