// tab-quality.jsx — Lead's QC dashboard.
//
// Shows a sortable roster of annotators with their quality % over a chosen
// window (this week / last week / month / all). Each row expands to reveal
// the per-resource drill-down: previous → current diff for every attribute
// the reviewer changed, plus TASQ deep-links to the original and corrected
// versions of the record.
//
// Replaces legacy/YendaDashboard_Standalone.gs `_loadAllQCData` consumers.

const { useState: qUseState, useEffect: qUseEffect, useMemo: qUseMemo } = React;

// Threshold tones for the quality bar. The legacy app didn't band-color
// these; we add subtle red/amber/green bands to make sub-90 stand out.
function qualityTone(q) {
  if (q == null) return { color: '#6b7280', bg: '#f3f4f6' };
  if (q >= 95)  return { color: '#15803d', bg: '#f0fdf4' };
  if (q >= 90)  return { color: '#1d4ed8', bg: '#eff6ff' };
  if (q >= 80)  return { color: '#b45309', bg: '#fffbeb' };
  return { color: '#b91c1c', bg: '#fef2f2' };
}

function PeriodChip({ active, onClick, label }) {
  return (
    <button
      onClick={onClick}
      className={'chip chip-mini' + (active ? ' active' : '')}
      style={{
        background: active ? '#111' : '#fff',
        color: active ? '#fff' : '#374151',
        border: `1px solid ${active ? '#111' : '#e5e7eb'}`,
        padding: '6px 12px',
        fontSize: 12,
        fontWeight: 600,
        cursor: 'pointer',
      }}>
      {label}
    </button>
  );
}

function MistakeRow({ m }) {
  const [expanded, setExpanded] = qUseState(false);
  const attrCount = (m.attributes || []).length;
  return (
    <div style={{ borderTop: '1px solid var(--line-2)', padding: '10px 14px' }}>
      <div className="flex jb ac" style={{ cursor: 'pointer' }} onClick={() => setExpanded(!expanded)}>
        <div className="flex g8 ac" style={{ minWidth: 0, flex: 1 }}>
          <span style={{ display: 'inline-block', width: 12, color: '#9ca3af' }}>{expanded ? '▾' : '▸'}</span>
          <span className="mono" style={{ fontSize: 12, color: '#6b7280' }}>{m.day || '—'}</span>
          <span style={{ fontSize: 13, fontWeight: 600 }}>{m.project || '(no project)'}</span>
          <span className="meta" style={{ fontSize: 11 }}>resource {m.resourceId}</span>
          <span className="chip chip-mini" style={{
            background: '#fef2f2', color: '#b91c1c', borderColor: 'transparent',
          }}>
            {attrCount} {attrCount === 1 ? 'change' : 'changes'}
          </span>
        </div>
        <div className="flex g6">
          {m.prevLink && (
            <a className="btn btn-sm" href={m.prevLink} target="_blank" rel="noopener" onClick={(e) => e.stopPropagation()}>
              Original
            </a>
          )}
          {m.qcLink && (
            <a className="btn btn-sm btn-dark" href={m.qcLink} target="_blank" rel="noopener" onClick={(e) => e.stopPropagation()}>
              Corrected
            </a>
          )}
        </div>
      </div>
      {expanded && (
        <div style={{ marginTop: 10, marginLeft: 24, paddingLeft: 12, borderLeft: '2px solid #fecaca' }}>
          {(m.attributes || []).map((a, i) => (
            <div key={i} style={{ marginBottom: 8, fontSize: 13 }}>
              <div style={{ fontWeight: 700, color: '#374151' }}>{a.task || '(unknown task)'}</div>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginTop: 4 }}>
                <div style={{ background: '#fef2f2', padding: '6px 10px', borderRadius: 6, color: '#7f1d1d' }}>
                  <div className="meta" style={{ fontSize: 10, marginBottom: 2 }}>Annotator entered</div>
                  <div className="mono" style={{ fontSize: 12, wordBreak: 'break-word' }}>{a.previous}</div>
                </div>
                <div style={{ background: '#f0fdf4', padding: '6px 10px', borderRadius: 6, color: '#14532d' }}>
                  <div className="meta" style={{ fontSize: 10, marginBottom: 2 }}>Reviewer changed to</div>
                  <div className="mono" style={{ fontSize: 12, wordBreak: 'break-word' }}>{a.current}</div>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function AnnotatorRow({ row }) {
  const [expanded, setExpanded] = qUseState(false);
  const tone = qualityTone(row.quality);
  return (
    <div className="card" style={{ marginBottom: 8 }}>
      <div
        className="flex jb ac"
        style={{ padding: '12px 14px', cursor: 'pointer' }}
        onClick={() => setExpanded(!expanded)}>
        <div className="flex g10 ac" style={{ minWidth: 0, flex: 1 }}>
          <span style={{ display: 'inline-block', width: 14, color: '#9ca3af' }}>{expanded ? '▾' : '▸'}</span>
          <Avatar name={row.name} size={28}/>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontWeight: 700 }}>{row.name}</div>
            <div className="meta" style={{ fontSize: 11 }}>
              {row.totalChecked} checked · {row.totalMistakes} with changes
              {row.topFailingTask && (
                <> · top issue <b style={{ color: '#b45309' }}>{row.topFailingTask}</b> ({row.topFailingErrorRate}%)</>
              )}
            </div>
          </div>
        </div>
        <div className="flex g8 ac">
          <span className="chip chip-mini" style={{
            background: tone.bg, color: tone.color, borderColor: 'transparent',
            fontFamily: 'Inconsolata, monospace', fontWeight: 700, fontSize: 13,
            padding: '4px 12px',
          }}>
            {row.quality.toFixed(2)}%
          </span>
        </div>
      </div>
      {expanded && (
        <div style={{ borderTop: '1px solid var(--line)' }}>
          {row.byTask.length > 0 && (
            <div style={{ padding: '10px 14px', background: '#fafafa', borderBottom: '1px solid var(--line-2)' }}>
              <div className="meta" style={{ fontSize: 11, marginBottom: 6 }}>Failure breakdown by task</div>
              <div className="flex g6" style={{ flexWrap: 'wrap' }}>
                {row.byTask.slice(0, 8).map((t) => (
                  <span key={t.taskName} className="chip chip-mini" style={{
                    background: t.errorRate >= 20 ? '#fef2f2' : t.errorRate >= 5 ? '#fffbeb' : '#f0fdf4',
                    color: t.errorRate >= 20 ? '#b91c1c' : t.errorRate >= 5 ? '#b45309' : '#15803d',
                    borderColor: 'transparent',
                  }}>
                    {t.taskName} · {t.errorRate}% ({t.mistakes}/{t.checked})
                  </span>
                ))}
              </div>
            </div>
          )}
          {row.mistakes.length === 0 ? (
            <div className="meta" style={{ padding: 24, textAlign: 'center' }}>No changed resources in this window.</div>
          ) : (
            row.mistakes.map((m) => <MistakeRow key={m.resourceId} m={m}/>)
          )}
        </div>
      )}
    </div>
  );
}

function TabQuality() {
  const [data, setData] = qUseState(null);
  const [loading, setLoading] = qUseState(true);
  const [error, setError] = qUseState(null);
  const [period, setPeriod] = qUseState('this-week');
  const [search, setSearch] = qUseState('');
  const [sortKey, setSortKey] = qUseState('quality'); // quality | checked | mistakes
  const team = window.YD?.TEAM?.teamName || '';

  qUseEffect(() => {
    setLoading(true);
    setError(null);
    window.YDApp.call('getQcDataForLead', { team, window: period })
      .then((d) => { setData(d); setLoading(false); })
      .catch((e) => { setError(e.message || String(e)); setLoading(false); });
  }, [team, period]);

  const filteredRows = qUseMemo(() => {
    const rows = (data?.rows || []).slice();
    if (sortKey === 'checked') rows.sort((a, b) => b.totalChecked - a.totalChecked);
    else if (sortKey === 'mistakes') rows.sort((a, b) => b.totalMistakes - a.totalMistakes);
    else rows.sort((a, b) => a.quality - b.quality);
    const q = search.trim().toLowerCase();
    if (!q) return rows;
    return rows.filter((r) =>
      (r.name || '').toLowerCase().includes(q) || (r.email || '').toLowerCase().includes(q),
    );
  }, [data, sortKey, search]);

  const tone = qualityTone(data?.teamQuality);

  return (
    <div className="page">
      <PageHeader
        eyebrow="Quality"
        title={loading ? 'Loading quality data…' : `${team} quality`}
        subtitle={
          error ? 'Failed to load' :
          loading ? '' :
          `${data.teamChecked.toLocaleString()} resources checked · ${data.teamMistakes.toLocaleString()} with reviewer changes · ${data.windowFrom} → ${data.windowTo}`
        }/>

      {error && (
        <div className="card"><div className="card-bd" style={{ color: '#b91c1c' }}>{error}</div></div>
      )}

      {!loading && !error && (
        <>
          <div className="row g16" style={{ marginBottom: 12 }}>
            <div className="card f1">
              <div className="card-bd flex jb ac">
                <div>
                  <div className="meta">Team quality</div>
                  <div style={{
                    fontFamily: 'Inconsolata, monospace', fontSize: 32, fontWeight: 700, color: tone.color,
                  }}>
                    {data.teamQuality.toFixed(2)}%
                  </div>
                </div>
                <div className="flex g6">
                  <PeriodChip active={period === 'this-week'} onClick={() => setPeriod('this-week')} label="This week"/>
                  <PeriodChip active={period === 'last-week'} onClick={() => setPeriod('last-week')} label="Last week"/>
                  <PeriodChip active={period === 'month'} onClick={() => setPeriod('month')} label="Last 30d"/>
                  <PeriodChip active={period === 'all'} onClick={() => setPeriod('all')} label="All time"/>
                </div>
              </div>
            </div>
          </div>

          <div className="card" style={{ marginBottom: 12 }}>
            <div className="card-bd flex jb ac" style={{ flexWrap: 'wrap', gap: 8 }}>
              <input
                className="modal-input"
                style={{ width: 260 }}
                placeholder="Search annotator…"
                value={search}
                onChange={(e) => setSearch(e.target.value)}/>
              <div className="flex g6 ac">
                <span className="meta" style={{ fontSize: 11 }}>Sort:</span>
                <PeriodChip active={sortKey === 'quality'}  onClick={() => setSortKey('quality')}  label="Worst quality"/>
                <PeriodChip active={sortKey === 'mistakes'} onClick={() => setSortKey('mistakes')} label="Most changes"/>
                <PeriodChip active={sortKey === 'checked'}  onClick={() => setSortKey('checked')}  label="Most checked"/>
              </div>
            </div>
          </div>

          {filteredRows.length === 0 ? (
            <div className="card"><div className="card-bd meta" style={{ textAlign: 'center', padding: 30 }}>
              {search ? 'No annotators match the search.' : 'No QC data for this window. Try widening the period.'}
            </div></div>
          ) : (
            filteredRows.map((row) => <AnnotatorRow key={row.email} row={row}/>)
          )}
        </>
      )}
    </div>
  );
}

Object.assign(window, { TabQuality });
