// tab-performance.jsx — 7-day heatmap + sortable leaderboard, with optional
// week-projection view. The view modes:
//   actual     — past + today rendered from kpi entries; future days dimmed.
//   projection — past + today same as actual; future days = committed × pace
//                (current week only — last week's projection is meaningless).

const { useState: pUseState, useMemo: pUseMemo } = React;

// Per-cell projection. Reuses the same shading rules as actual cells but
// styles future cells with reduced opacity + italic so the eye distinguishes
// real numbers from estimates.
function projectFutureCell(s, idx, today, pace) {
  if (!s) return null;
  if (idx <= today) return null;
  if (s.isLeave || s.isDayOff) return null;
  const committed = s.committed || 0;
  if (committed <= 0 || !pace || pace <= 0) return null;
  return Math.round(committed * pace);
}

function PerformanceHeatmap({ members, onLog, viewMode }) {
  const today = window.YD.TODAY_IDX;
  const DAYS = window.YD.DAYS;
  const projecting = viewMode === 'projection' && (window.YD.weekOffset === 0);

  // Cell colour reflects RESOURCES vs DAILY TARGET. The daily target is
  // expectedPace × committed_hours for that day — so a 5h-committed
  // annotator with expected pace 144 has a target of 720 resources. If
  // they hit 720, they're green; whether it took them 4, 5 or 6 hours
  // doesn't matter. Below target → amber. Cells with resources but no
  // commitment (off-day bonus work) treated as purple.
  const cellStyle = (s, kpi, idx, expectedPace) => {
    const res = (kpi && kpi.resources) || 0;
    const isToday = idx === today;

    if (!s) return { bg: '#fafafa', color: '#d1d5db', label: '—' };

    if (s.isLeave || s.status === 'On Leave') {
      return res > 0
        ? { bg: '#f5f3ff', color: '#7c3aed', label: fmtK(res) }
        : { bg: '#eff6ff', color: '#1d4ed8', label: 'leave' };
    }
    if (s.isDayOff) {
      return res > 0
        ? { bg: '#f5f3ff', color: '#7c3aed', label: fmtK(res) }
        : { bg: '#fafafa', color: '#d1d5db', label: 'off' };
    }
    if (s.isPending || s.status === 'Pending') return { bg: '#fafafa', color: '#d1d5db', label: '—' };

    // Have they hit their daily target? committed × expectedPace.
    if (res > 0) {
      const committed = s.committed || 0;
      const target = committed * (expectedPace || 0);
      const metTarget = target > 0 ? res >= target : true; // no target = can't punish
      if (metTarget) {
        return { bg: '#bbf7d0', color: '#14532d', label: fmtK(res) }; // dark green
      }
      return { bg: '#fffbeb', color: '#b45309', label: fmtK(res) };   // amber — below target
    }

    if (s.isMissed) return { bg: '#fef2f2', color: '#b91c1c', label: '✗' };
    if (isToday) return { bg: '#fafafa', color: '#9ca3af', label: 'today' };
    return { bg: '#fef2f2', color: '#b91c1c', label: '✗' };
  };

  // Project a future cell. Returns the same {bg,color,label} shape but with
  // a `projected` flag so the renderer can dim it.
  const projCell = (s, idx, pace, expectedPace) => {
    const proj = projectFutureCell(s, idx, today, pace);
    if (proj == null) {
      // No projection (off / leave / not committed) — render as the empty
      // future cell pattern.
      if (s && (s.isLeave || s.isDayOff)) return cellStyle(s, null, idx, expectedPace);
      return { bg: '#fafafa', color: '#d1d5db', label: '—' };
    }
    return { bg: '#eef2ff', color: '#3730a3', label: fmtK(proj), projected: true };
  };

  return (
    <table className="perf-hm">
      <thead>
        <tr>
          <th className="name">Annotator</th>
          {DAYS.map((d, i) => <th key={d} className={'d' + (i === today ? ' today' : '')}>{d}</th>)}
          <th className="num">Pace</th>
          <th className="num">Week total</th>
          {projecting && <th className="num">Projected</th>}
          <th className="num">vs Target</th>
          <th/>
        </tr>
      </thead>
      <tbody>
        {members.map(m => {
          const weekPct = m.weeklyTarget > 0 ? Math.round(m.resources / m.weeklyTarget * 100) : 0;
          // Project remaining hours × current pace per day, sum and add to
          // resources already done.
          let projectedRemaining = 0;
          if (projecting) {
            (m.dailyShifts || []).forEach((s, i) => {
              const p = projectFutureCell(s, i, today, m.pace);
              if (p != null) projectedRemaining += p;
            });
          }
          const projectedTotal = m.resources + projectedRemaining;
          const projectedPct = m.weeklyTarget > 0 ? Math.round(projectedTotal / m.weeklyTarget * 100) : 0;
          return (
            <tr key={m.email}>
              <td className="name">
                <div className="flex ac g8">
                  <Avatar name={m.name} size={24}/>
                  <div>
                    <div className="nm">{m.name}</div>
                    <div className="rl">
                      {m.role}
                      {m.severity !== 'ok' && m.severity !== 'leave' && <span style={{ marginLeft: 6 }}><SevDot sev={m.severity} size={6}/></span>}
                    </div>
                  </div>
                </div>
              </td>
              {(m.dailyShifts || []).map((s, i) => {
                const isFuture = projecting && i > today;
                const st = isFuture
                  ? projCell(s, i, m.pace, m.expectedPace)
                  : cellStyle(s, m.dailyKpi && m.dailyKpi[i], i, m.expectedPace);
                return (
                  <td key={i} className={'cell-td' + (i === today ? ' today' : '')}>
                    <div
                      className="cell"
                      style={{
                        background: st.bg,
                        color: st.color,
                        opacity: st.projected ? 0.75 : 1,
                        fontStyle: st.projected ? 'italic' : 'normal',
                      }}>
                      {st.label}
                    </div>
                  </td>
                );
              })}
              <td className="num mono">{m.pace || 0}</td>
              <td className="num mono" style={{ fontWeight: 700 }}>{fmtK(m.resources)}</td>
              {projecting && (
                <td className="num mono" style={{ fontWeight: 700, color: '#3730a3' }}>
                  {projectedRemaining > 0 ? fmtK(projectedTotal) : fmtK(m.resources)}
                </td>
              )}
              <td className="num">
                {m.weeklyTarget > 0 ? (
                  <div className="weekpct">
                    <div className="weekpct-bar">
                      <div className="weekpct-fill" style={{ width: Math.min(100, projecting ? projectedPct : weekPct) + '%', background: (projecting ? projectedPct : weekPct) >= 100 ? '#15803d' : (projecting ? projectedPct : weekPct) >= 80 ? '#b45309' : '#b91c1c' }}/>
                    </div>
                    <span className="mono">{projecting ? projectedPct : weekPct}%</span>
                  </div>
                ) : <span className="meta">—</span>}
              </td>
              <td style={{ textAlign: 'right' }}>
                <button className="btn btn-sm" onClick={() => onLog([m])}>+ Log</button>
              </td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

function TabPerformance({ weekOffset, setWeekOffset }) {
  const td = window.YD.TEAM;
  const [sortKey, setSortKey] = pUseState('resources');
  const [viewMode, setViewMode] = pUseState('actual'); // 'actual' | 'projection'
  const [limit, setLimit] = pUseState(30);
  const [logTarget, setLogTarget] = pUseState(null);
  const [toast, setToast] = pUseState(null);

  const isCurrentWeek = (window.YD.weekOffset ?? weekOffset ?? 0) === 0;

  const sorted = pUseMemo(() => {
    return [...td.members].sort((a, b) => {
      if (sortKey === 'pace') return (b.pace || 0) - (a.pace || 0);
      if (sortKey === 'name') return a.name.localeCompare(b.name);
      if (sortKey === 'missed') return (b.missed + b.incomplete) - (a.missed + a.incomplete);
      // Sort by projected total when projection view is active.
      if (sortKey === 'resources' && viewMode === 'projection' && isCurrentWeek) {
        return (b._projected || b.resources || 0) - (a._projected || a.resources || 0);
      }
      return (b.resources || 0) - (a.resources || 0);
    });
  }, [sortKey, viewMode, isCurrentWeek]);

  // Team totals for the projection KPI tile.
  const today = window.YD.TODAY_IDX;
  const teamProjectedRemaining = pUseMemo(() => {
    if (!isCurrentWeek) return 0;
    let sum = 0;
    for (const m of td.members) {
      (m.dailyShifts || []).forEach((s, i) => {
        const p = projectFutureCell(s, i, today, m.pace);
        if (p != null) sum += p;
      });
    }
    return sum;
  }, [td.members, today, isCurrentWeek]);

  const visible = sorted.slice(0, limit);
  const bySev = window.YD.BY_SEVERITY;
  const belowPace = bySev.critical.length + bySev.high.length + bySev.watch.length;
  const projecting = viewMode === 'projection' && isCurrentWeek;

  return (
    <div className="page">
      <PageHeader
        eyebrow={`Week of ${window.YD.weekLabel || 'this week'}`}
        title="Performance"
        subtitle={`${td.memberCount} annotators · team pace ${td.teamPace}/hr`}
        actions={
          <div className="flex g8 ac">
            <div className="segbar">
              <button
                className={isCurrentWeek ? 'active' : ''}
                onClick={() => setWeekOffset && setWeekOffset(0)}>
                This week
              </button>
              <button
                className={!isCurrentWeek ? 'active' : ''}
                onClick={() => setWeekOffset && setWeekOffset(-1)}>
                Last week
              </button>
            </div>
            <button className="btn">Export CSV</button>
          </div>
        }/>

      <div className="kpi-row" style={{ display: 'grid', gridTemplateColumns: projecting ? 'repeat(4, 1fr)' : 'repeat(3, 1fr)' }}>
        <div className="kpi-tile">
          <div className="lbl">Team pace</div>
          <div className="val">{td.teamPace || 0}</div>
          <div className="sub">vs {td.expectedPace || '—'} expected · {td.benchmarkPace || '—'} benchmark</div>
        </div>
        <div className="kpi-tile">
          <div className="lbl">Week resources</div>
          <div className="val">{fmtK(td.totalResources)}</div>
          <div className="sub">WTD across team</div>
        </div>
        {projecting && (
          <div className="kpi-tile">
            <div className="lbl">Week projection</div>
            <div className="val" style={{ color: '#3730a3' }}>{fmtK(td.totalResources + teamProjectedRemaining)}</div>
            <div className="sub">+{fmtK(teamProjectedRemaining)} from remaining shifts at current pace</div>
          </div>
        )}
        <div className="kpi-tile">
          <div className="lbl">Below pace</div>
          <div className="val" style={{ color: '#b45309' }}>{belowPace}</div>
          <div className="sub">{td.memberCount > 0 ? Math.round(belowPace / td.memberCount * 100) : 0}% of active roster</div>
        </div>
      </div>

      <div className="card">
        <div className="card-hd card-hd-bottomline">
          <h2>{projecting ? 'Per-annotator projection · this week' : '7-day resources per annotator'}</h2>
          <div className="flex g8 ac">
            {isCurrentWeek && (
              <div className="segbar">
                <button className={viewMode === 'actual' ? 'active' : ''} onClick={() => setViewMode('actual')}>Actual</button>
                <button className={viewMode === 'projection' ? 'active' : ''} onClick={() => setViewMode('projection')}>Projection</button>
              </div>
            )}
            <div className="segbar">
              <button className={sortKey === 'resources' ? 'active' : ''} onClick={() => setSortKey('resources')}>Top producers</button>
              <button className={sortKey === 'pace' ? 'active' : ''} onClick={() => setSortKey('pace')}>By pace</button>
              <button className={sortKey === 'missed' ? 'active' : ''} onClick={() => setSortKey('missed')}>Most missed</button>
              <button className={sortKey === 'name' ? 'active' : ''} onClick={() => setSortKey('name')}>A–Z</button>
            </div>
          </div>
        </div>
        {projecting && (
          <div className="card-bd" style={{ paddingTop: 0, paddingBottom: 0 }}>
            <div className="meta" style={{ padding: '8px 0' }}>
              Future cells (italic, indigo) = committed hours × annotator's current pace. Past cells = actual resources logged.
            </div>
          </div>
        )}
        <div className="card-bd" style={{ padding: 0 }}>
          <PerformanceHeatmap members={visible} onLog={setLogTarget} viewMode={viewMode}/>
          {sorted.length > limit && (
            <div className="pt-more">
              <button className="btn" onClick={() => setLimit(limit + 30)}>
                Show {Math.min(30, sorted.length - limit)} more · {sorted.length - limit} hidden
              </button>
            </div>
          )}
        </div>
      </div>

      {toast && <div className="toast">{toast}</div>}
      {logTarget && (
        <ActionModal
          targets={logTarget}
          onClose={() => setLogTarget(null)}
          onSaved={(count) => {
            setLogTarget(null);
            setToast(`Logged action for ${count} ${count === 1 ? 'person' : 'people'}`);
            setTimeout(() => setToast(null), 2400);
          }}/>
      )}
    </div>
  );
}

Object.assign(window, { TabPerformance });
