// QC inbox: second-eye review queue
function QcNotesPreview({ notes }) {
  const [expanded, setExpanded] = useState(false);
  if (!notes || notes.length === 0) return null;
  return (
    <div style={{marginLeft: 52, padding: '0 16px 12px'}}>
      <button
        onClick={() => setExpanded(v => !v)}
        style={{
          display: 'inline-flex', alignItems: 'center', gap: 5,
          fontSize: 11, color: 'var(--muted)', background: 'none',
          border: 'none', padding: '2px 0', cursor: 'pointer',
          fontFamily: 'inherit',
        }}
      >
        <Icon name="flag" size={11}/>
        {notes.length} {notes.length === 1 ? 'note' : 'notes'}
        <span style={{opacity: 0.6}}>{expanded ? '▲' : '▼'}</span>
      </button>
      {expanded && (
        <div style={{marginTop: 6, display: 'flex', flexDirection: 'column', gap: 4}}>
          {notes.map((n, i) => (
            <div key={i} style={{
              fontSize: 12, color: 'var(--ink-2)',
              background: 'var(--warn-2)',
              border: '1px solid var(--warn)',
              borderRadius: 'var(--radius)',
              padding: '6px 10px',
              lineHeight: 1.5,
            }}>
              {n.content}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function QcInbox({ people, onOpen, currentUser, onUpdate, onUpdateProfile, locks = {} }) {
  const [opened, setOpened] = useState(() => new Set());
  const [confirmed, setConfirmed] = useState(() => new Set());
  const [showOnlyApprovable, setShowOnlyApprovable] = useState(false);

  const currentUserId = currentUser?.id || currentUser?._id || currentUser?.user_id;

  const items = useMemo(() => {
    const out = [];
    for (const p of people) {
      // Profile attributes (country / category)
      for (const attrKey of ['country', 'category']) {
        const attr = p.profile?.[attrKey];
        if (attr && attr.status === 'verified') {
          out.push({
            person: p,
            type: 'profile',
            attrKey,
            attr,
            key: `${p.id}:${attrKey}`,
          });
        }
      }
      // Handles
      for (const pl of PLATFORMS) {
        const handles = p.handles[pl.id];
        const handlesArray = Array.isArray(handles) ? handles : [handles];
        
        handlesArray.forEach((handle, handleIndex) => {
          if (handle.status === 'verified') {
            out.push({ 
              person: p,
              type: 'handle',
              platform: pl, 
              handle: handle, 
              handleIndex,
              key: `${p.id}:${pl.id}:${handleIndex}` 
            });
          }
        });
      }
    }
    return out;
  }, [people]);

  const visibleItems = useMemo(() => {
    if (!showOnlyApprovable) return items;
    return items.filter(it => {
      if (it.type === 'handle') return !(it.handle.verified_by && currentUserId && currentUserId === it.handle.verified_by);
      if (it.type === 'profile') return !(it.attr.verified_by && currentUserId && currentUserId === it.attr.verified_by);
      return true;
    });
  }, [items, showOnlyApprovable, currentUserId]);

  const markOpened = (key) => setOpened(s => { const n = new Set(s); n.add(key); return n; });
  const markConfirmed = (item) => {
    const key = item.key;
    setConfirmed(s => { const n = new Set(s); n.add(key); return n; });
    
    // Call API to set status to 'qc'
    if (item.type === 'handle') {
      onUpdate(item.person.id, item.platform.id, item.handleIndex, h => ({ ...h, status: 'qc' }));
    } else if (item.type === 'profile') {
      onUpdateProfile(item.person.id, item.attrKey, a => ({ ...a, status: 'qc' }));
    }
  };

  return (
    <>
      <div className="filters">
        <div style={{display: 'flex', alignItems: 'center', gap: 8}}>
          <Icon name="lock" size={14} stroke="var(--muted)"/>
          <div style={{fontSize: 13, fontWeight: 500}}>Four-eye QC queue</div>
          <Pill kind="info">{items.length} awaiting second reviewer</Pill>
        </div>
        <div className="spacer"/>
        <label style={{display:'flex', alignItems:'center', gap:8, cursor:'pointer', userSelect:'none'}}>
          <span style={{
            display:'inline-flex', alignItems:'center',
            width:34, height:20, borderRadius:10,
            background: showOnlyApprovable ? 'var(--accent)' : 'var(--border-2)',
            transition:'background .2s',
            padding:2, boxSizing:'border-box', flexShrink:0,
          }}
            onClick={() => setShowOnlyApprovable(v => !v)}
            role="switch"
            aria-checked={showOnlyApprovable}
            tabIndex={0}
            onKeyDown={e => (e.key === ' ' || e.key === 'Enter') && setShowOnlyApprovable(v => !v)}
          >
            <span style={{
              display:'block', width:16, height:16, borderRadius:'50%',
              background:'#fff', boxShadow:'0 1px 3px rgba(0,0,0,.25)',
              transform: showOnlyApprovable ? 'translateX(14px)' : 'translateX(0)',
              transition:'transform .2s',
            }}/>
          </span>
          <span style={{lineHeight:1.4}}>
            <span style={{fontSize:12, fontWeight:500, color: showOnlyApprovable ? 'var(--accent-ink)' : 'var(--text)', transition:'color .15s'}}>
              Show only items I can approve
            </span>
            <br/>
            <span style={{fontSize:11, color:'var(--muted)'}}>
              Open account links before confirming · You can't approve handles you verified yourself
            </span>
          </span>
        </label>
      </div>

      <div className="scroll" style={{padding: 16}}>
        <div style={{display: 'grid', gap: 8}}>
          {visibleItems.map((it, idx) => {
            const key = it.key;
            const isOpened = opened.has(key);
            const isConfirmed = confirmed.has(key);

            if (it.type === 'profile') {
              const label = it.attrKey === 'country' ? 'Country' : 'Category';
              const icon = it.attrKey === 'country' ? '🌐' : '⚡';
              return (
                <div key={idx} className="pcard" style={{margin: 0, opacity: isConfirmed ? 0.5 : 1}}>
                  <div className="pcard-head">
                    <div style={{width:40, height:40, display:'flex', alignItems:'center', justifyContent:'center', fontSize:20, flexShrink:0}}>{icon}</div>
                    <div>
                      <div className="plat" style={{display:'inline-flex', alignItems:'center', gap:6}}>
                        <span>{it.person.name}</span>
                        {locks[it.person.id] && <LockChip lock={locks[it.person.id]}/>}
                        <span style={{color:'var(--muted)', fontWeight:400}}> · {label}</span>
                      </div>
                      <div className="plat-sub">Value: <strong>{it.attr.merged || '—'}</strong> · {it.attrKey === 'country' ? 'SportsNet' : 'CultureNet'}: {it.attr.sports || '—'} · MC Info: {it.attr.panel || '—'}</div>
                    </div>
                    <div className="right" style={{gap:10}}>
                      <button
                        className="btn sm"
                        onClick={() => onOpen(it.person.id)}
                        title="Edit this person's profile"
                      >
                        <Icon name="edit" size={11}/> Edit
                      </button>
                      {(() => {
                        const selfVerified = it.attr.verified_by && currentUser?.id && it.attr.verified_by === currentUser.id;
                        return (
                          <button
                            className="btn ok sm"
                            disabled={isConfirmed || selfVerified}
                            onClick={() => { markOpened(key); markConfirmed(it); }}
                            title={selfVerified ? `You verified this ${label.toLowerCase()} — a second reviewer must confirm` : `QC approve the ${label.toLowerCase()} for ${it.person.name}`}
                          >
                            <Icon name="check" size={12}/> {isConfirmed ? 'Confirmed' : selfVerified ? 'Need 2nd reviewer' : 'Confirm'}
                          </button>
                        );
                      })()}
                    </div>
                  </div>
                  <QcNotesPreview notes={it.person.meta?.notes}/>
                </div>
              );
            }

            const href = `https://${URL_ROOT[it.platform.id]}${it.handle.merged}`;
            const noAccount = !it.handle.merged;
            return (
              <div key={idx} className="pcard" style={{margin: 0, opacity: isConfirmed ? 0.5 : 1}}>
                <div className="pcard-head">
                  <Tile platform={it.platform.id} status="verified" size="lg"/>
                  <div>
                    <div className="plat" style={{display:'inline-flex', alignItems:'center', gap:6}}>
                      <span>{it.person.name}</span>
                      {locks[it.person.id] && <LockChip lock={locks[it.person.id]}/>}
                      <span style={{color: 'var(--muted)', fontWeight: 400}}>
                        · {it.platform.name}
                        {Array.isArray(people.find(p => p.id === it.person.id)?.handles[it.platform.id]) && 
                         people.find(p => p.id === it.person.id)?.handles[it.platform.id].length > 1 && 
                         ` #${it.handleIndex + 1}`}
                      </span>
                    </div>
                    <div className="plat-sub">{it.person.category} · {it.person.country || '—'}</div>
                  </div>
                  <div className="right" style={{gap: 10}}>
                    {noAccount ? (
                      <span style={{
                        display: 'inline-flex', alignItems: 'center', gap: 5,
                        fontSize: 12, fontWeight: 600,
                        color: 'var(--err)',
                        padding: '4px 10px',
                      }}>
                        No account
                      </span>
                    ) : (
                      <span className="mono" style={{fontSize: 12, color: 'var(--muted)'}}>
                        {URL_ROOT[it.platform.id]}{it.handle.merged}
                      </span>
                    )}
                    <button
                      className="btn sm"
                      onClick={() => onOpen(it.person.id)}
                      title="Edit this person's handles"
                    >
                      <Icon name="edit" size={11}/> Edit
                    </button>
                    {noAccount ? null : (
                      <a
                        className={`btn sm ${isOpened ? 'ok' : 'primary'}`}
                        href={href}
                        target="_blank"
                        rel="noreferrer"
                        onClick={() => markOpened(key)}
                        title={isOpened ? "You've viewed this account" : 'Required: open and review the account'}
                      >
                        {isOpened ? <><Icon name="check" size={11}/> Opened</> : <>Open account <Icon name="ext" size={11}/></>}
                      </a>
                    )}
                    {(() => {
                      const isSelfVerified = !!(it.handle.verified_by && currentUserId && currentUserId === it.handle.verified_by);
                      return (
                        <button
                          className="btn ok sm"
                          disabled={(!noAccount && !isOpened) || isConfirmed || isSelfVerified}
                          onClick={() => { if (noAccount) markOpened(key); markConfirmed(it); }}
                          title={isSelfVerified ? 'You verified this — a second reviewer must confirm' : (!noAccount && !isOpened ? 'Open the account first' : 'Confirm this handle')}
                        >
                          <Icon name="check" size={12}/> {isConfirmed ? 'Confirmed' : isSelfVerified ? 'Need 2nd reviewer' : 'Confirm'}
                        </button>
                      );
                    })()}
                  </div>
                </div>
                {!noAccount && !isOpened && !isConfirmed && (
                  <div style={{padding: '0 16px 12px', marginLeft: 52, fontSize: 11, color: 'var(--muted)'}}>
                    Open the account page to enable confirmation.
                  </div>
                )}
                {noAccount && !isConfirmed && (
                  <div style={{padding: '0 16px 12px', marginLeft: 52, fontSize: 11, color: 'var(--err)'}}>
                    No {it.platform.name} account exists for this person.
                  </div>
                )}
                <QcNotesPreview notes={it.person.meta?.notes}/>
              </div>
            );
          })}
          {items.length === 0 && (
            <div className="empty">
              <div className="big">Inbox zero</div>
              Nothing waiting for a second reviewer. Nice.
            </div>
          )}
        </div>
      </div>
    </>
  );
}

// Export modal
function ExportModal({ people, filters, teamStats = [], fetchLogs, onClose, onToast }) {
  const [exports, setExports] = useState({
    people: true,
    userLog: true,
    teamActivity: true,
  });
  const [exporting, setExporting] = useState(false);
  const [scope, setScope] = useState('all');
  const toggleExport = (k) => setExports(e => ({ ...e, [k]: !e[k] }));

  const selectedExportCount = Object.values(exports).filter(Boolean).length;

  const doExport = async () => {
    if (!exports.people && !exports.userLog && !exports.teamActivity) {
      onToast('Select at least one export option.');
      return;
    }

    setExporting(true);

    // Determine which records to export based on scope
    let rows = people;
    if (scope === 'complete') {
      rows = people.filter(p => computeCounts(p, PLATFORMS).complete);
    } else if (scope === 'filtered' && filters) {
      if (filters.q) {
        const q = filters.q.toLowerCase();
        rows = rows.filter(p => p.name.toLowerCase().includes(q) || p.category.toLowerCase().includes(q));
      }
      if (filters.status !== 'all') {
        rows = rows.filter(p => {
          const c = computeCounts(p, PLATFORMS);
          const pc = computeProfileCounts(p);
          const profDone = pc.qc === pc.total;
          if (filters.status === 'complete') return c.complete && profDone;
          if (filters.status === 'review')   return c.unverified > 0 || c.missing > 0 || pc.unverified > 0;
          if (filters.status === 'qc')       return (c.verified > 0 || pc.verified > 0) && !(c.complete && profDone);
          if (filters.status === 'attrs')    return pc.unverified > 0 || pc.verified > 0;
          return true;
        });
      }
      if (filters.source !== 'all') rows = rows.filter(p => p.source === filters.source);
    }

    // Some people have more than one handle for the same platform (e.g. an old
    // account plus a new one) — give each platform as many columns as its
    // most-populated row needs, so no handle gets silently dropped.
    const platformHandles = (p, platform) => (p.handles?.[platform.id] || []).filter(h => h?.merged);
    const platformColumnCount = {};
    PLATFORMS.forEach(platform => {
      platformColumnCount[platform.id] = rows.reduce((max, p) => Math.max(max, platformHandles(p, platform).length), 1);
    });

    // Build header for People sheet: name, MEPP ID, one (or more) URL column(s) per platform.
    // MEPP ID isn't part of today's /people payload — comes through as p.mepp_id
    // if/when the backend adds it; left blank otherwise.
    const header = ['Name', 'MEPP ID'];
    PLATFORMS.forEach(platform => {
      const count = platformColumnCount[platform.id];
      for (let i = 0; i < count; i++) {
        header.push(count > 1 ? `${platform.name} ${i + 1}` : platform.name);
      }
    });

    const dataRows = rows.map(p => {
      const row = [p.name, p.mepp_id || ''];

      PLATFORMS.forEach(platform => {
        const handles = platformHandles(p, platform);
        const count = platformColumnCount[platform.id];
        for (let i = 0; i < count; i++) {
          const handle = handles[i];
          row.push(handle ? `https://${URL_ROOT[platform.id]}${handle.merged}` : '');
        }
      });

      return row;
    });

    const wb = XLSX.utils.book_new();
    const addSheet = (sheetName, sheetHeader, sheetRows) => {
      const ws = XLSX.utils.aoa_to_sheet([sheetHeader, ...sheetRows]);
      XLSX.utils.book_append_sheet(wb, ws, sheetName);
    };

    if (exports.people) {
      addSheet('People', header, dataRows);
    }

    if (exports.userLog) {
      let logs = [];
      if (typeof fetchLogs === 'function') {
        try {
          const res = await fetchLogs({ limit: 2000, skip: 0 });
          logs = Array.isArray(res?.data) ? res.data : [];
        } catch (err) {
          console.error('Failed to fetch logs for export:', err);
          onToast('Could not fetch user log data. Exporting other selected sheets.');
        }
      }

      const logHeader = ['Log ID', 'User', 'Person', 'Person ID', 'Platform', 'Status Change', 'Timestamp'];
      const logRows = logs.map(l => [
        l.id || '',
        l.user_name || '',
        l.person_name || '',
        l.person_id || '',
        l.platform || '',
        l.status_change || '',
        l.timestamp || '',
      ]);
      addSheet('User Activity Log', logHeader, logRows);
    }

    if (exports.teamActivity) {
      const teamHeader = ['User ID', 'Name', 'Email', 'Role', 'Total Changes', 'Verified', 'QC', 'No Account'];
      const teamRows = (teamStats || []).map(m => [
        m.user_id || '',
        m.name || '',
        m.email || '',
        m.role || '',
        m.total_changes ?? 0,
        m.verified_count ?? 0,
        m.qc_count ?? 0,
        m.non_existing_count ?? 0,
      ]);
      addSheet('Team Statistics', teamHeader, teamRows);
    }

    const dateTag = new Date().toISOString().slice(0, 10);
    const fileName = `social_handles_export_${dateTag}.xlsx`;
    XLSX.writeFile(wb, fileName);

    onToast(`Exported ${selectedExportCount} sheet${selectedExportCount !== 1 ? 's' : ''} — ${fileName}`);
    setExporting(false);
    onClose();
  };

  return (
    <div className="modal-bg" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h2>Export data</h2>
          <button className="btn ghost icon close" onClick={onClose}><Icon name="x" size={14}/></button>
        </div>
        <div className="modal-body">
          <div style={{marginBottom: 14}}>
            <div style={{fontSize: 11, textTransform: 'uppercase', color: 'var(--muted)', letterSpacing: '.06em', marginBottom: 6}}>Export options</div>
            <div style={{display: 'grid', gap: 10}}>
              {/* People section with nested scope selector */}
              <div>
                <label className="checkrow">
                  <input type="checkbox" checked={exports.people} onChange={() => toggleExport('people')}/>
                  People
                </label>
                {exports.people && (
                  <div style={{marginTop: 8, marginLeft: 24, paddingLeft: 8, borderLeft: '2px solid var(--surface-2)'}}>
                    <div style={{fontSize: 10, textTransform: 'uppercase', color: 'var(--muted)', letterSpacing: '.06em', marginBottom: 6}}>Scope</div>
                    <div style={{display: 'flex', gap: 6, flexWrap: 'wrap'}}>
                      <button className={`chip ${scope==='all'?'active':''}`} onClick={() => setScope('all')}>All records <span className="count">{people.length}</span></button>
                      <button className={`chip ${scope==='complete'?'active':''}`} onClick={() => setScope('complete')}>Complete only</button>
                    </div>
                    <div style={{fontSize: 11, color: 'var(--muted)', marginTop: 6}}>
                      Columns: Name, MEPP ID, and one URL column per platform (extra numbered columns appear when someone has more than one handle for that platform; blank if no handle).
                    </div>
                  </div>
                )}
              </div>

              {/* User Activity Log */}
              <label className="checkrow">
                <input type="checkbox" checked={exports.userLog} onChange={() => toggleExport('userLog')}/>
                <div>
                  <div>User Activity Log</div>
                  <div style={{fontSize: 11, color: 'var(--muted)', marginTop: 2}}>Status changes by user and date</div>
                </div>
              </label>

              {/* Team Statistics */}
              <label className="checkrow">
                <input type="checkbox" checked={exports.teamActivity} onChange={() => toggleExport('teamActivity')}/>
                <div>
                  <div>Team Statistics</div>
                  <div style={{fontSize: 11, color: 'var(--muted)', marginTop: 2}}>Activity summary per team member</div>
                </div>
              </label>
            </div>
          </div>

          <div style={{marginTop: 14, padding: 10, background: 'var(--surface-2)', borderRadius: 6, fontSize: 12, color: 'var(--muted)', display:'flex', alignItems:'center', gap: 8}}>
            <Icon name="export" size={12}/> One Excel file will be created with one sheet per selected option.
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn" onClick={onClose}>Cancel</button>
          <button className="btn primary" onClick={doExport} disabled={exporting || selectedExportCount === 0}>
            <Icon name="export" size={13}/> {exporting ? 'Exporting...' : 'Export .xlsx'}
          </button>
        </div>
      </div>
    </div>
  );
}

// Tweaks panel
function TweaksPanel({ tweaks, setTweaks, onClose }) {
  const ACCENTS = [
    { id: 'indigo',  value: '#4F46E5', soft: '#EEF2FF', ink: '#312E81' },
    { id: 'emerald', value: '#059669', soft: '#D1FAE5', ink: '#064E3B' },
    { id: 'rose',    value: '#E11D48', soft: '#FFE4E6', ink: '#881337' },
    { id: 'amber',   value: '#D97706', soft: '#FEF3C7', ink: '#78350F' },
    { id: 'stone',   value: '#1C1917', soft: '#F5F5F4', ink: '#1C1917' },
  ];
  return (
    <div className="tweaks">
      <div style={{display:'flex', alignItems:'center', marginBottom: 6}}>
        <h3 style={{margin: 0}}>Tweaks</h3>
        <button className="btn ghost icon sm" style={{marginLeft: 'auto'}} onClick={onClose}><Icon name="x" size={12}/></button>
      </div>
      <div className="tweak-row">
        <label>Density</label>
        <div className="seg">
          {['compact','default','comfortable'].map(d => (
            <button key={d} className={tweaks.density === d ? 'on' : ''} onClick={() => setTweaks({...tweaks, density: d})}>{d}</button>
          ))}
        </div>
      </div>
      <div className="tweak-row">
        <label>Theme</label>
        <div className="seg">
          {['light','dark'].map(d => (
            <button key={d} className={tweaks.theme === d ? 'on' : ''} onClick={() => setTweaks({...tweaks, theme: d})}>{d}</button>
          ))}
        </div>
      </div>
      <div className="tweak-row">
        <label>Accent</label>
        <div className="accent-dots">
          {ACCENTS.map(a => (
            <button key={a.id}
              className={tweaks.accent === a.id ? 'on' : ''}
              style={{'--c': a.value}}
              onClick={() => setTweaks({...tweaks, accent: a.id})}
              title={a.id}
            />
          ))}
        </div>
      </div>
      <div className="tweak-row">
        <label>QC badge</label>
        <div className="seg">
          <button className={tweaks.qcBadge === 'on' ? 'on' : ''} onClick={() => setTweaks({...tweaks, qcBadge: 'on'})}>on</button>
          <button className={tweaks.qcBadge === 'off' ? 'on' : ''} onClick={() => setTweaks({...tweaks, qcBadge: 'off'})}>off</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { QcInbox, ExportModal, TweaksPanel });
