// Team Activity log - shows team member status and activity
function ActivityLogView({ teamActivity = [], teamStats = [], fetchLogs, onOpen }) {
  const PAGE_SIZE = 20;

  const [allLogs, setAllLogs] = useState([]);
  const [logPage, setLogPage] = useState(0);
  const [logSearch, setLogSearch] = useState('');
  const [logLoading, setLogLoading] = useState(false);
  const [isRefreshing, setIsRefreshing] = useState(false);

  // Fetch all logs once on mount
  useEffect(() => {
    if (!fetchLogs) return;
    let cancelled = false;
    setLogLoading(true);
    fetchLogs()
      .then(data => { if (!cancelled) setAllLogs(data.data || []); })
      .catch(err => console.error('Failed to load logs:', err))
      .finally(() => { if (!cancelled) setLogLoading(false); });
    return () => { cancelled = true; };
  }, [fetchLogs]);

  // Manual refresh handler
  const handleRefresh = async () => {
    if (!fetchLogs || isRefreshing) return;
    let cancelled = false;
    setIsRefreshing(true);
    try {
      const data = await fetchLogs();
      if (!cancelled) setAllLogs(data.data || []);
    } catch (err) {
      console.error('Failed to refresh logs:', err);
    } finally {
      if (!cancelled) setIsRefreshing(false);
    }
  };

  // Client-side filter
  const filteredLogs = useMemo(() => {
    const q = logSearch.toLowerCase();
    if (!q) return allLogs;
    return allLogs.filter(e =>
      (e.person_name || '').toLowerCase().includes(q) ||
      (e.user_name || '').toLowerCase().includes(q) ||
      (e.platform || '').toLowerCase().includes(q) ||
      (e.status_change || '').toLowerCase().includes(q)
    );
  }, [allLogs, logSearch]);

  const totalPages = Math.ceil(filteredLogs.length / PAGE_SIZE);
  const pageLogs = filteredLogs.slice(logPage * PAGE_SIZE, (logPage + 1) * PAGE_SIZE);

  // Debounce search input
  const debounceRef = useRef(null);
  const handleSearchInput = (val) => {
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => {
      setLogPage(0);
      setLogSearch(val.trim());
    }, 200);
  };

  const STATUS_LOG_META = {
    verified:     { label: 'Verified',    cls: 'lsc-verified' },
    qc:           { label: 'QC',          cls: 'lsc-qc' },
    'non-existing': { label: 'No account', cls: 'lsc-absent' },
    unverified:   { label: 'Unverified',  cls: 'lsc-unverified' },
    missing:      { label: 'Missing',     cls: 'lsc-unverified' },
  };

  const platformLabel = (p) => {
    const found = (window.PLATFORMS || []).find(pl => pl.id === p);
    return found ? found.name : (p ? p.charAt(0).toUpperCase() + p.slice(1) : '—');
  };

  return (
    <>
      <div className="filters">
        <div style={{display:'flex', alignItems:'center', gap:8}}>
          <Icon name="clock" size={14} stroke="var(--muted)"/>
          <div style={{fontSize:13, fontWeight:500}}>Team Activity</div>
          <Pill kind="info">{teamStats.length} team members</Pill>
        </div>
        <button 
          className="btn ghost sm" 
          onClick={handleRefresh}
          disabled={isRefreshing}
          title="Refresh event log"
        >
          <Icon name={isRefreshing ? "loader" : "refresh"} size={13}/>
          {isRefreshing ? 'Refreshing…' : 'Refresh'}
        </button>
      </div>

      <div className="scroll">
        {/* === Work done overview === */}
        <div className="report-section">
          <h2>Work done</h2>
          <div className="sub">Total status changes logged per team member.</div>
          {teamStats.length === 0 ? (
            <div style={{color:'var(--muted)', fontSize:13, padding:'12px 0'}}>No statistics available.</div>
          ) : (
            <div className="user-summary-grid">
              {teamStats.map(member => {
                const initials = member.name.split(' ').map(n => n.charAt(0)).join('').toUpperCase();
                return (
                  <div key={member.user_id} className="user-summary">
                    <div className="us-head">
                      <span className="avatar xs">{initials}</span>
                      <div style={{minWidth:0, flex:1}}>
                        <div style={{fontSize:13, fontWeight:600, color:'var(--ink)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{member.name}</div>
                        <div style={{fontSize:11, color:'var(--muted)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{member.email}</div>
                      </div>
                      <span className="team-role">{member.role}</span>
                    </div>
                    <div className="us-stack">
                      <div>
                        <span className="us-lab">Total</span>
                        <b style={{color: 'var(--ink)'}}>{member.total_changes}</b>
                      </div>
                      <div>
                        <span className="us-lab">Verified</span>
                        <b style={{color: member.verified_count > 0 ? '#1D4ED8' : 'var(--muted)'}}>{member.verified_count}</b>
                      </div>
                      <div>
                        <span className="us-lab">QC</span>
                        <b style={{color: member.qc_count > 0 ? '#15803D' : 'var(--muted)'}}>{member.qc_count}</b>
                      </div>
                      <div>
                        <span className="us-lab">No account</span>
                        <b style={{color: member.non_existing_count > 0 ? '#991B1B' : 'var(--muted)'}}>{member.non_existing_count}</b>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>

        {/* === Event log === */}
        <div className="report-section" style={{paddingBottom: 40}}>
          <h2 style={{margin:'0 0 4px'}}>Event log</h2>
          <div style={{display:'flex', alignItems:'center', gap:12, marginBottom:12}}>
            <div className="sub" style={{margin:0}}>All status changes recorded by the team.</div>
            <div style={{flex:1}}/>
            <div className="log-search-input-wrap" style={{flex:'0 1 280px'}}>
              <Icon name="search" size={13} stroke="var(--muted)"/>
              <input
                className="log-search-input"
                placeholder="Search person, user, platform…"
                onChange={e => handleSearchInput(e.target.value)}
              />
            </div>
          </div>

          {/* Table */}
          <div className="log-table-wrap">
            <table className="log-table">
              <thead>
                <tr>
                  <th>User</th>
                  <th>Status</th>
                  <th>Person · Platform</th>
                  <th>When</th>
                </tr>
              </thead>
              <tbody>
                {logLoading ? (
                  <tr><td colSpan={4} className="log-empty"><Icon name="loader" size={14}/> Loading…</td></tr>
                ) : pageLogs.length === 0 ? (
                  <tr><td colSpan={4} className="log-empty">No log entries found.</td></tr>
                ) : pageLogs.map(entry => {
                  const initials = (entry.user_name || '?').split(' ').map(n => n.charAt(0)).join('').toUpperCase().slice(0, 2);
                  const sm = STATUS_LOG_META[entry.status_change] || { label: entry.status_change, cls: 'lsc-unverified' };
                  return (
                    <tr key={entry.id} className="log-tr">
                      <td className="log-td-user">
                        <span className="avatar xs" style={{flexShrink:0}}>{initials}</span>
                        <span className="log-username">{entry.user_name}</span>
                      </td>
                      <td><span className={`log-status-chip ${sm.cls}`}>{sm.label}</span></td>
                      <td>
                        <button className="log-person-btn" onClick={() => onOpen && onOpen(entry.person_id)}>
                          <span style={{fontWeight: 500}}>{entry.person_name || entry.person_id}</span>
                        </button>
                        <span className="log-td-platform"> · {platformLabel(entry.platform)}</span>
                      </td>
                      <td className="log-td-since">{entry.since}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>

          {/* Pagination */}
          <div className="log-pagination">
            <button className="btn ghost sm" disabled={logPage === 0} onClick={() => setLogPage(p => p - 1)}>
              <Icon name="chevL" size={13}/> Prev
            </button>
            <span className="log-page-info">{filteredLogs.length === 0 ? '0 entries' : `${logPage * PAGE_SIZE + 1}–${Math.min((logPage + 1) * PAGE_SIZE, filteredLogs.length)} of ${filteredLogs.length}`}</span>
            <button className="btn ghost sm" disabled={logPage >= totalPages - 1} onClick={() => setLogPage(p => p + 1)}>
              Next <Icon name="chevR" size={13}/>
            </button>
          </div>
        </div>

      </div>
    </>
  );
}

function SourceQualityView({ people }) {
  const [tab, setTab] = useState('SportsTool');
  const [country, setCountry] = useState('all');

  const pool = useMemo(() => Array.isArray(people) ? people.filter(p => p.source === tab) : [], [people, tab]);
  const countries = useMemo(() => Array.from(new Set(pool.map(p => p.country))).sort(), [pool]);

  const filtered = useMemo(() => country === 'all' ? pool : pool.filter(p => p.country === country), [pool, country]);

  const overall  = useMemo(() => score(filtered), [filtered]);
  const byCat    = useMemo(() => groupScore(filtered, 'category'), [filtered]);
  const byCountry= useMemo(() => groupScore(pool,      'country'),  [pool]);
  const byPlat   = useMemo(() => platformScore(filtered), [filtered]);

  function platformScore(list) {
    const out = {};
    for (const pl of PLATFORMS) out[pl.id] = { id: pl.id, name: pl.name, total:0, correct:0, corrected:0, wrong:0, missing:0 };
    for (const p of list) {
      for (const pl of PLATFORMS) {
        const h = p.handles[pl.id];
        const row = out[pl.id]; row.total++;
        const src = p.source === 'SportsTool' ? h.sports : h.panel;
        const locked = h.status === 'qc' || h.status === 'verified';
        if (h.status === 'non-existing') continue;
        if (locked && src && h.merged === src) row.correct++;
        else if (locked && src && h.merged !== src) { row.corrected++; row.wrong++; }
        else if (locked && !src && h.merged) row.missing++;
      }
    }
    return out;
  }

  function score(list) {
    const s = { people:list.length, slots:0, correct:0, corrected:0, wrong:0, missing:0, absent:0, mismatches:0, locked:0 };
    for (const p of list) for (const pl of PLATFORMS) {
      const h = p.handles[pl.id]; s.slots++;
      const src = p.source === 'SportsTool' ? h.sports : h.panel;
      const isLocked = h.status === 'qc' || h.status === 'verified';
      if (h.status === 'non-existing') { s.absent++; continue; }
      if (isLocked) s.locked++;
      if (isLocked && src && h.merged === src) s.correct++;
      else if (isLocked && src && h.merged !== src) { s.corrected++; s.wrong++; }
      else if (isLocked && !src && h.merged) s.missing++;
      if (h.sports && h.panel && h.sports !== h.panel) s.mismatches++;
    }
    return s;
  }

  function groupScore(list, key) {
    const groups = {};
    for (const p of list) {
      const k = p[key] || '—';
      if (!groups[k]) groups[k] = [];
      groups[k].push(p);
    }
    return Object.entries(groups).map(([k, arr]) => ({ key: k, ...score(arr) }));
  }

  const qpct = (s) => s.locked ? Math.round(s.correct / s.locked * 100) : 0;

  // Pain points
  const worstCat     = byCat.slice().filter(x => x.locked >= 2).sort((a,b) => qpct(a) - qpct(b))[0];
  const bestCat      = byCat.slice().filter(x => x.locked >= 2).sort((a,b) => qpct(b) - qpct(a))[0];
  const worstCountry = byCountry.slice().filter(x => x.locked >= 2).sort((a,b) => qpct(a) - qpct(b))[0];
  const worstPlatform= Object.values(byPlat).slice().filter(x => (x.correct+x.corrected+x.missing) >= 2).sort((a,b) => {
    const qa = (a.correct+a.corrected+a.missing) ? a.correct/(a.correct+a.corrected+a.missing) : 1;
    const qb = (b.correct+b.corrected+b.missing) ? b.correct/(b.correct+b.corrected+b.missing) : 1;
    return qa - qb;
  })[0];

  const overallQ = qpct(overall);

  return (
    <>
      <div className="filters">
        <div className="seg" style={{marginRight:8}}>
          <button className={tab==='SportsTool'?'on':''} onClick={() => setTab('SportsTool')}>SportsTool</button>
          <button className={tab==='CultureTool'?'on':''} onClick={() => setTab('CultureTool')}>CultureTool</button>
        </div>
        <div style={{fontSize:12, color:'var(--muted)', marginRight:4}}>Country:</div>
        <select className="select-inline" value={country} onChange={e => setCountry(e.target.value)}>
          <option value="all">All countries ({pool.length})</option>
          {countries.map(c => <option key={c} value={c}>{c}</option>)}
        </select>
        <div className="spacer"/>
        <Pill kind="info">{filtered.length} records · {overall.slots} handle slots</Pill>
      </div>

      <div className="scroll">
        {/* Headline */}
        <div className="report-grid" style={{gridTemplateColumns:'2fr 1fr 1fr 1fr'}}>
          <div className="metric accent">
            <span className="m-label">Quality as delivered</span>
            <span className="m-val" style={{fontSize:40, color: overallQ>=80?'var(--ok)':overallQ>=50?'var(--warn)':'var(--err)'}}>{overallQ}%</span>
            <span className="m-sub">{overall.correct} of {overall.locked} locked handles were correct from {tab}</span>
            <div className="stack" style={{marginTop:8}}>
              <span style={{flex: overall.correct,   background:'#16A34A'}}/>
              <span style={{flex: overall.corrected, background:'#F59E0B'}}/>
              <span style={{flex: overall.missing,   background:'#DC2626'}}/>
            </div>
          </div>
          <div className="metric">
            <span className="m-label">Needed correction</span>
            <span className="m-val" style={{color:'var(--warn)'}}>{overall.corrected}</span>
            <span className="m-sub">outdated or wrong in {tab}</span>
          </div>
          <div className="metric">
            <span className="m-label">We had to add</span>
            <span className="m-val" style={{color:'var(--err)'}}>{overall.missing}</span>
            <span className="m-sub">handles missing from {tab}</span>
          </div>
          <div className="metric">
            <span className="m-label">Mismatches w/ other source</span>
            <span className="m-val">{overall.mismatches}</span>
            <span className="m-sub">disagreed with {tab === 'SportsTool' ? 'Panel' : 'SportsTool'}</span>
          </div>
        </div>

        {/* Where the pain is */}
        <div className="report-section">
          <h2>Where the pain is</h2>
          <div className="sub">Concentrations of bad data — start fixing here.</div>
          <div className="pain-grid">
            <PainCard icon="flag" label="Worst category"
              primary={worstCat ? worstCat.key : '—'}
              value={worstCat ? qpct(worstCat) + '%' : ''}
              sub={worstCat ? worstCat.correct + ' of ' + worstCat.locked + ' correct · ' + worstCat.missing + ' missing, ' + worstCat.corrected + ' fixed' : 'Not enough data'}
              tone="err"/>
            <PainCard icon="flag" label="Worst country"
              primary={worstCountry ? worstCountry.key : '—'}
              value={worstCountry ? qpct(worstCountry) + '%' : ''}
              sub={worstCountry ? worstCountry.people + ' records · ' + worstCountry.locked + ' locked handles' : 'Not enough data'}
              tone="err"/>
            <PainCard icon="flag" label="Worst platform"
              primary={worstPlatform ? worstPlatform.name : '—'}
              value={worstPlatform ? Math.round(worstPlatform.correct/(worstPlatform.correct+worstPlatform.corrected+worstPlatform.missing)*100) + '%' : ''}
              sub={worstPlatform ? worstPlatform.missing + ' missing, ' + worstPlatform.corrected + ' needed fix' : ''}
              tone="err" platform={worstPlatform?.id}/>
            <PainCard icon="check" label="Strongest category"
              primary={bestCat ? bestCat.key : '—'}
              value={bestCat ? qpct(bestCat) + '%' : ''}
              sub={bestCat ? bestCat.correct + ' of ' + bestCat.locked + ' correct' : ''}
              tone="ok"/>
          </div>
        </div>

        {/* By category */}
        <div className="report-section">
          <h2>By category</h2>
          <div className="sub">Which parts of {tab} are strongest and weakest.</div>
          <GroupTable rows={byCat} qpct={qpct} labelCol="Category"/>
        </div>

        {/* By country */}
        <div className="report-section">
          <h2>By country</h2>
          <div className="sub">Geographic pockets of bad data.</div>
          <GroupTable rows={byCountry.filter(r => r.people > 0)} qpct={qpct} labelCol="Country"/>
        </div>

        {/* By platform */}
        <div className="report-section" style={{paddingBottom:40}}>
          <h2>By platform</h2>
          <div className="sub">Where {tab} tends to fall short per channel.</div>
          <div className="panel wide">
            <table className="platform-table">
              <thead>
                <tr>
                  <th>Platform</th>
                  <th>Correct</th>
                  <th>Needed fix</th>
                  <th>Missing, we added</th>
                  <th style={{width:160}}>Quality</th>
                </tr>
              </thead>
              <tbody>
                {PLATFORMS.map(pl => {
                  const r = byPlat[pl.id];
                  const locked = r.correct + r.corrected + r.missing;
                  const q = locked ? Math.round(r.correct / locked * 100) : 0;
                  return (
                    <tr key={pl.id}>
                      <td><div className="pcell"><Tile platform={pl.id} status="verified"/>{r.name}</div></td>
                      <td style={{color: r.correct ? 'var(--ok)' : 'var(--muted-2)'}}>{r.correct}</td>
                      <td style={{color: r.corrected ? 'var(--warn)' : 'var(--muted-2)'}}>{r.corrected}</td>
                      <td style={{color: r.missing ? 'var(--err)' : 'var(--muted-2)'}}>{r.missing}</td>
                      <td>
                        <div className="pcell" style={{justifyContent:'flex-end'}}>
                          <span style={{fontVariantNumeric:'tabular-nums', fontWeight:500, color: q>=80?'var(--ok)':q>=50?'var(--warn)':'var(--err)'}}>{locked ? q+'%' : '—'}</span>
                          <span className="pbar"><span style={{width:(locked?q:0)+'%', background: q>=80?'var(--ok)':q>=50?'var(--warn)':'var(--err)'}}/></span>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </>
  );
}

function PainCard({ icon, label, primary, value, sub, tone, platform }) {
  return (
    <div className={`pain-card tone-${tone}`}>
      <div className="pain-head">
        <Icon name={icon} size={12}/>
        <span className="pain-label">{label}</span>
      </div>
      <div className="pain-main">
        {platform && <Tile platform={platform} status="verified" size="lg"/>}
        <div style={{minWidth:0}}>
          <div className="pain-primary">{primary}</div>
          <div className="pain-sub">{sub}</div>
        </div>
        {value && <div className="pain-value">{value}</div>}
      </div>
    </div>
  );
}

function GroupTable({ rows, qpct, labelCol }) {
  const sorted = rows.slice().sort((a,b) => qpct(a) - qpct(b));
  return (
    <div className="panel wide">
      <table className="platform-table">
        <thead>
          <tr>
            <th>{labelCol}</th>
            <th>Records</th>
            <th>Correct</th>
            <th>Fixed</th>
            <th>Missing</th>
            <th style={{width:160}}>Quality</th>
          </tr>
        </thead>
        <tbody>
          {sorted.map(r => {
            const q = qpct(r);
            return (
              <tr key={r.key}>
                <td style={{fontWeight:500}}>{r.key}</td>
                <td style={{color:'var(--muted)'}}>{r.people}</td>
                <td style={{color: r.correct ? 'var(--ok)' : 'var(--muted-2)'}}>{r.correct}</td>
                <td style={{color: r.corrected ? 'var(--warn)' : 'var(--muted-2)'}}>{r.corrected}</td>
                <td style={{color: r.missing ? 'var(--err)' : 'var(--muted-2)'}}>{r.missing}</td>
                <td>
                  <div className="pcell" style={{justifyContent:'flex-end'}}>
                    <span style={{fontVariantNumeric:'tabular-nums', fontWeight:500, color: r.locked === 0 ? 'var(--muted-2)' : q>=80?'var(--ok)':q>=50?'var(--warn)':'var(--err)'}}>{r.locked ? q+'%' : '—'}</span>
                    <span className="pbar"><span style={{width:(r.locked ? q : 0)+'%', background: q>=80?'var(--ok)':q>=50?'var(--warn)':'var(--err)'}}/></span>
                  </div>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

Object.assign(window, { ActivityLogView, SourceQualityView });
