/* Klipzy.lv — Admin dashboard (role: admin) */
const ADMIN_NAV = [
  { key: 'panel', label: 'Pārskats', enLabel: 'Overview', icon: 'grid' },
  { key: 'users', label: 'Lietotāji', enLabel: 'Users', icon: 'users' },
  { key: 'campaigns', label: 'Kampaņas', enLabel: 'Campaigns', icon: 'megaphone' },
  { key: 'cashouts', label: 'Izmaksas', enLabel: 'Payouts', icon: 'wallet' },
  { key: 'messages', label: 'Ziņas', enLabel: 'Messages', icon: 'inbox' },
  { key: 'settings', label: 'Iestatījumi', enLabel: 'Settings', icon: 'gear' },
];

function AdminApp({ go, params, user }) {
  const lang = useLang();
  const [tab, setTab] = useState(params.tab || 'panel');
  const data = useAdminData();
  const notif = useAllNotifications();
  useEffect(() => { if (params.tab) setTab(params.tab); }, [params.tab]);
  // "Maksājumi" permission — owner enables perms.payments on the admin's
  // Firestore user doc; without it, the Izmaksas tab is hidden entirely.
  const canPayments = !!((user && user.profile && user.profile.perms && user.profile.perms.payments));
  // Count of "new" payout requests (received / not yet seen) for the nav badge.
  const [payoutBadge, setPayoutBadge] = useState(0);
  useEffect(() => {
    if (!canPayments) return;
    let ok = true;
    const load = async () => {
      try {
        if (window.KlipzyFirebase && window.KlipzyFirebase.listAllCashouts) {
          const rows = await window.KlipzyFirebase.listAllCashouts();
          if (ok) setPayoutBadge(rows.filter((r) => r.status !== 'paid' && r.status !== 'declined' && r.status !== 'failed').length);
        }
      } catch (_) {}
    };
    load();
    return () => { ok = false; };
  }, [canPayments, tab]);
  const nav = ADMIN_NAV.filter((n) => n.key !== 'cashouts' || canPayments)
    .map((n) => n.key === 'cashouts' && payoutBadge > 0 ? { ...n, badge: payoutBadge > 9 ? '9+' : payoutBadge } : n);
  // Guard the route too, in case the tab was deep-linked.
  useEffect(() => { if (tab === 'cashouts' && !canPayments) setTab('panel'); }, [tab, canPayments]);
  return (
    <div className="dash-shell" style={{ display: 'flex', height: '100%' }}>
      <Sidebar items={nav.map((n) => ({ ...n, label: lang === 'en' ? (n.enLabel || n.label) : n.label }))} active={tab} onNav={setTab} role="admin" go={go} user={user} />
      <div className="app-scroll" style={{ flex: 1 }}>
        {tab === 'panel' && <AdminPanel go={go} setTab={setTab} user={user} data={data} notif={notif} />}
        {tab === 'users' && <AdminUsers data={data} onRequested={notif.reload} />}
        {tab === 'campaigns' && <AdminCampaigns data={data} go={go} />}
        {tab === 'cashouts' && canPayments && <AdminCashouts users={data.users} />}
        {tab === 'messages' && <AdminMessages />}
        {tab === 'settings' && <SettingsStub title={tr('Iestatījumi', lang)} user={user} role="admin" />}
      </div>
    </div>
  );
}

function AdminPanel({ go, setTab, user, data, notif }) {
  const K = window.KLIPZY;
  const lang = useLang();
  const T = (s) => tr(s, lang);
  const { users, campaigns, submissions, totalViews, activity, loading } = data;
  const revenue = campaigns.reduce((s, c) => s + (c.spent || 0), 0);
  const chartViews = (activity && activity.viewsPerDay && activity.viewsPerDay.length) ? activity.viewsPerDay : K.chartData;
  const chartClips = (activity && activity.clipsPerDay && activity.clipsPerDay.length) ? activity.clipsPerDay : null;
  const activeCampaigns = campaigns.filter((c) => c.status === 'active').length;
  const recentUsers = [...users].sort((a, b) => (b.joinedTs || 0) - (a.joinedTs || 0)).slice(0, 8);

  const [refreshOpen, setRefreshOpen] = useState(false);
  const [toast, setToast] = useState('');
  // Attach the recipient's name to each notification for display.
  const byUid = {}; users.forEach((u) => { byUid[u.uid] = u.name; });
  // The notes shown as banners exclude admin-only request tickets.
  const notes = (notif && notif.notes || []).filter((n) => n.kind !== 'refreshRequest').map((n) => ({ ...n, toName: byUid[n.toUid] || '' }))
    .sort((a, b) => (a.severity === 'critical' ? -1 : 1) - (b.severity === 'critical' ? -1 : 1));
  // Brand refresh-view requests → "Zīmolu pieteikumi".
  const refreshReqs = (notif && notif.notes || []).filter((n) => n.kind === 'refreshRequest');
  const doCampaignRefresh = async (n) => {
    try { if (window.KlipzyFirebase) { await window.KlipzyFirebase.refreshCampaignViews(n.campaignId); await window.KlipzyFirebase.resolveNotification(n.id); } } catch (_) {}
    if (notif) notif.reload();
    if (data.reload) data.reload();
  };
  const resolveNote = async (n) => {
    try { if (window.KlipzyFirebase) await window.KlipzyFirebase.resolveNotification(n.id); } catch (_) {}
    if (notif) notif.reload();
  };
  // Open disputes = submissions a clipper has contested after a rejection.
  const campById = {}; campaigns.forEach((c) => { campById[c.id] = c; });
  const disputes = (submissions || []).filter((s) => s.disputed);
  const resolveDispute = async (s, uphold) => {
    const frozen = payableForSub(s, campById[s.campaignId]);
    try { if (window.KlipzyFirebase) await window.KlipzyFirebase.resolveDispute(s, uphold, frozen); } catch (_) {}
    if (data.reload) data.reload();
    if (notif) notif.reload();
  };
  const setDisputeStatus = async (s, status) => {
    try { if (window.KlipzyFirebase) await window.KlipzyFirebase.setDisputeStatus(s, status); } catch (_) {}
    if (data.reload) data.reload();
    if (notif) notif.reload();
  };
  const flagFraud = async (s) => {
    try { if (window.KlipzyFirebase) await window.KlipzyFirebase.flagFraudReview(s, 'Manuāli atzīmēts pārbaudei'); } catch (_) {}
    if (data.reload) data.reload();
    if (notif) notif.reload();
  };
  const DISPUTE_LABEL = { open: 'Atvērts', fraud_review: 'Krāpšanas pārbaude', under_review: 'Tiek izskatīts', awaiting_info: 'Gaida informāciju', resolved_clipper: 'Par labu klipotājam', resolved_brand: 'Par labu zīmolam', closed: 'Slēgts' };

  return (
    <div className="fade-in">
      <TopBar title={T('Administrācijas pārskats')} subtitle={T('Platformas darbības kopskats.')} notif={{ notes, onResolve: resolveNote }}>
        <button className="btn btn-secondary" onClick={() => setRefreshOpen(true)}><Icon d={I.refresh} size={16} /> {T('Atjaunot skatījumus')}</button>
        <button className="btn btn-primary" onClick={() => setTab('users')}>{T('Lietotāji')}</button>
      </TopBar>
      <div style={{ padding: 32, display: 'flex', flexDirection: 'column', gap: 24 }}>
        <NotifBanner notes={notes} onResolve={resolveNote} showWho />
        {refreshReqs.length > 0 && (
          <div className="card" style={{ padding: 0, overflow: 'hidden', border: '1px solid var(--accent-tint-2)' }}>
            <div className="spread" style={{ padding: '16px 22px', borderBottom: '1px solid var(--border)', background: 'var(--accent-tint)' }}>
              <h3 style={{ fontSize: 16, color: 'var(--accent-700)' }}>{T('Zīmolu pieteikumi')} ({refreshReqs.length})</h3>
              <span className="muted" style={{ fontSize: 12.5 }}>{T('Skatījumu atjaunošanas pieprasījumi')}</span>
            </div>
            <div>
              {refreshReqs.map((n) => {
                const camp = campById[n.campaignId];
                return (
                  <div key={n.id} className="spread" style={{ padding: '14px 22px', borderTop: '1px solid var(--border)', gap: 12, flexWrap: 'wrap' }}>
                    <div style={{ minWidth: 0 }}>
                      <div style={{ fontSize: 14, fontWeight: 540 }}>{camp ? camp.name : (n.campaignId || T('Kampaņa'))}</div>
                      <div className="muted" style={{ fontSize: 12.5 }}>{n.message}</div>
                    </div>
                    <button className="btn btn-primary btn-sm" style={{ flex: 'none' }} onClick={() => doCampaignRefresh(n)}><Icon d={I.refresh} size={15} /> {T('Atjaunot skatījumus')}</button>
                  </div>
                );
              })}
            </div>
          </div>
        )}
        {disputes.length > 0 && (
          <div className="card" style={{ padding: 0, overflow: 'hidden', border: '1px solid #FECACA' }}>
            <div className="spread" style={{ padding: '16px 22px', borderBottom: '1px solid var(--border)', background: '#FEF2F2' }}>
              <h3 style={{ fontSize: 16, color: '#B91C1C' }}>{T('Strīdi')} ({disputes.length})</h3>
              <span className="muted" style={{ fontSize: 12.5 }}>{T('Iesaldēti skatījumi gaida lēmumu')}</span>
            </div>
            <div>
              {disputes.map((s) => {
                const frozen = payableForSub(s, campById[s.campaignId]);
                return (
                  <div key={s.id} style={{ padding: '14px 22px', borderTop: '1px solid var(--border)', display: 'flex', flexDirection: 'column', gap: 8 }}>
                    <div className="spread" style={{ gap: 12, flexWrap: 'wrap' }}>
                      <div style={{ minWidth: 0 }}>
                        <div style={{ fontSize: 14, fontWeight: 540, display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>{s.clipper || T('Klipotājs')} · <span className="muted">{s.campaignName || '—'}</span> <span className="badge badge-amber">{T(DISPUTE_LABEL[s.disputeStatus] || 'Atvērts')}</span></div>
                        <a href={s.url} target="_blank" rel="noopener noreferrer" className="muted" style={{ fontSize: 12.5, display: 'inline-flex', alignItems: 'center', gap: 5 }}><Icon d={I.link} size={12} /> {numLv(s.viewCount || 0)} {T('skat.')} · {T('iesaldēts')} {eur(frozen)}</a>
                      </div>
                      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                        <button className="btn btn-ghost btn-sm" onClick={() => setDisputeStatus(s, 'under_review')}>{T('Izskatīt')}</button>
                        <button className="btn btn-ghost btn-sm" onClick={() => setDisputeStatus(s, 'awaiting_info')}>{T('Pieprasīt info')}</button>
                        <button className="btn btn-ghost btn-sm" style={{ color: 'var(--red)' }} onClick={() => flagFraud(s)}>{T('Krāpšanas pārbaude')}</button>
                        <button className="btn btn-secondary btn-sm" onClick={() => resolveDispute(s, true)}>{T('Uzturēt noraidījumu')}</button>
                        <button className="btn btn-primary btn-sm" onClick={() => resolveDispute(s, false)}>{T('Atcelt noraidījumu (izmaksāt)')}</button>
                      </div>
                    </div>
                    {(s.disputeReason || s.disputeEvidence) && (
                      <div style={{ background: '#F8FAFC', borderRadius: 8, padding: '9px 12px', fontSize: 12.5, color: 'var(--text-2)' }}>
                        {s.disputeReason && <div><strong>{T('Iemesls:')}</strong> {s.disputeReason}</div>}
                        {s.disputeEvidence && <div style={{ marginTop: 2 }}><strong>{T('Pierādījumi:')}</strong> <a href={s.disputeEvidence} target="_blank" rel="noopener noreferrer" style={{ color: 'var(--accent-700)' }}>{s.disputeEvidence}</a></div>}
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          </div>
        )}
        <div className="r-grid4" style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 18 }}>
          <StatCard label={T('Lietotāji kopā')} value={numLv(users.length)} icon="users" />
          <StatCard label={T('Aktīvās kampaņas')} value={numLv(activeCampaigns)} icon="megaphone" />
          <StatCard label={T('Kopējie skatījumi')} value={views(totalViews)} icon="chart" />
          <StatCard label={T('Apgrozījums')} value={eur0(revenue)} icon="wallet" />
        </div>

        <div className="card" style={{ padding: 22 }}>
          <div className="spread" style={{ marginBottom: 18 }}>
            <div>
              <h3 style={{ fontSize: 16 }}>{T('Platformas aktivitāte')}</h3>
              <p className="muted" style={{ fontSize: 13, marginTop: 2 }}>{T('Pēdējās 30 dienas')}</p>
            </div>
            <div style={{ display: 'flex', gap: 16, fontSize: 12.5 }}>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, color: 'var(--text-2)' }}><span style={{ width: 12, height: 3, borderRadius: 2, background: '#2563EB' }} />{T('Skatījumi / dienā')}</span>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, color: 'var(--text-2)' }}><span style={{ width: 12, height: 3, borderRadius: 2, background: '#D97706' }} />{T('Klipi / dienā')}</span>
            </div>
          </div>
          <AreaChart data={chartViews} data2={chartClips} height={230} />
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
          <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
            <div className="spread" style={{ padding: '18px 22px', borderBottom: '1px solid var(--border)' }}>
              <h3 style={{ fontSize: 16 }}>{T('Jaunākie lietotāji')}</h3>
              <button className="btn btn-ghost btn-sm" style={{ color: 'var(--accent-700)' }} onClick={() => setTab('users')}>{T('Visi')}</button>
            </div>
            {recentUsers.length === 0
              ? <div className="muted" style={{ padding: 24, textAlign: 'center', fontSize: 14 }}>{loading ? T('Ielādē…') : T('Nav lietotāju.')}</div>
              : <UsersTable rows={recentUsers} />}
          </div>
          <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
            <div className="spread" style={{ padding: '18px 22px', borderBottom: '1px solid var(--border)' }}>
              <h3 style={{ fontSize: 16 }}>{T('Top kampaņas')}</h3>
              <button className="btn btn-ghost btn-sm" style={{ color: 'var(--accent-700)' }} onClick={() => setTab('campaigns')}>{T('Visas')}</button>
            </div>
            {campaigns.length === 0
              ? <div className="muted" style={{ padding: 24, textAlign: 'center', fontSize: 14 }}>{loading ? T('Ielādē…') : T('Nav kampaņu.')}</div>
              : <CampaignsTable rows={[...campaigns].sort((a, b) => (b.views || 0) - (a.views || 0)).slice(0, 5)} showRemaining lang={lang} />}
          </div>
        </div>
      </div>
      {refreshOpen && <RefreshViewsModal onClose={() => setRefreshOpen(false)} onDone={async (n) => {
        setRefreshOpen(false);
        // Fulfilling the platform-wide refresh clears all pending brand requests.
        try { for (const r of refreshReqs) { if (window.KlipzyFirebase) await window.KlipzyFirebase.resolveNotification(r.id); } } catch (_) {}
        if (notif) notif.reload();
        data.reload && data.reload();
        setToast(T('Skatījumi ir atjaunoti') + (typeof n === 'number' ? ' (' + n + ' ' + T('klipi') + ').' : '.'));
        setTimeout(() => setToast(''), 5000);
      }} />}
      <Toast msg={toast} onClose={() => setToast('')} />
    </div>
  );
}

function RefreshViewsModal({ onClose, onDone }) {
  const lang = useLang();
  const T = (s) => tr(s, lang);
  // Canonical platform enums (match the submissions schema + Cloud Function).
  const PLATFORMS = [['youtube', 'YouTube'], ['tiktok', 'TikTok'], ['instagram', 'Instagram']];
  const [sel, setSel] = useState(PLATFORMS.map(function (p) { return p[0]; }));
  const [busy, setBusy] = useState(false);
  const [count, setCount] = useState(null);
  const toggle = (p) => setSel((s) => s.includes(p) ? s.filter((x) => x !== p) : [...s, p]);
  const run = async () => {
    if (sel.length === 0) return;
    setBusy(true);
    let n = 0;
    try {
      if (window.KlipzyFirebase) {
        n = await window.KlipzyFirebase.refreshViews(sel);
        // Also pick up any clip still sitting at 0 (initial fetch failed).
        if (window.KlipzyFirebase.backfillZeroViews) {
          try { n += await window.KlipzyFirebase.backfillZeroViews(); } catch (_) {}
        }
      }
    } catch (_) {}
    setCount(n); setBusy(false);
    setTimeout(() => onDone(n), 1100);
  };
  return (
    <ModalShell onClose={onClose} width={440}>
        <div className="spread" style={{ marginBottom: 6 }}>
          <h3 style={{ fontSize: 19 }}>{T('Atjaunot skatījumus')}</h3>
          <button className="btn btn-ghost btn-sm" style={{ padding: 6 }} onClick={onClose}><Icon d={I.x} size={18} /></button>
        </div>
        {count != null ? (
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: 'var(--green-tint)', border: '1px solid #BBF7D0', borderRadius: 10, padding: '14px 16px', color: '#166534', fontSize: 14, fontWeight: 540 }}>
            <Icon d={I.check} size={18} sw={2.4} /> {T('Atjaunoti')} {count} {T('klipu skatījumi.')}
          </div>
        ) : (
          <>
            <p className="muted" style={{ fontSize: 13.5, marginBottom: 16, lineHeight: 1.5 }}>{T('Izvēlies platformas, kurām atjaunot visu aktīvo iesniegto klipu skatījumus.')}</p>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 18 }}>
              {PLATFORMS.map(([k, label]) => (
                <label key={k} style={{ display: 'flex', alignItems: 'center', gap: 11, cursor: 'pointer', border: '1px solid ' + (sel.includes(k) ? 'var(--accent)' : 'var(--border-strong)'), background: sel.includes(k) ? 'var(--accent-tint)' : '#fff', borderRadius: 10, padding: '11px 14px' }}>
                  <input type="checkbox" checked={sel.includes(k)} onChange={() => toggle(k)} style={{ width: 17, height: 17, accentColor: 'var(--accent)' }} />
                  <span style={{ fontSize: 14, fontWeight: 540, color: sel.includes(k) ? 'var(--accent-700)' : 'var(--text)' }}>{label}</span>
                </label>
              ))}
            </div>
            <button className="btn btn-primary btn-lg btn-block" disabled={busy || sel.length === 0} onClick={run}><Icon d={I.refresh} size={17} /> {busy ? T('Atjauno…') : T('Atjaunot skatījumus')}</button>
          </>
        )}
    </ModalShell>
  );
}

/* ---------- Users (filter + sort + actions) ---------- */
function AdminUsers({ data, onRequested }) {
  const lang = useLang();
  const T = (s) => tr(s, lang);
  const [removed, setRemoved] = useState({});
  const [roles, setRoles] = useState({ clipper: true, brand: true, admin: true });
  const [sortDir, setSortDir] = useState('desc'); // by joined date
  const [selectedEmail, setSelectedEmail] = useState(null);
  const [patches, setPatches] = useState({});

  const toggleRole = (r) => setRoles((s) => ({ ...s, [r]: !s[r] }));

  const allUsers = (data.users || []).map((u) => ({ ...u, ...(patches[u.email] || {}) }));
  const rows = allUsers
    .filter((u) => roles[u.role] && !removed[u.email])
    .slice()
    .sort((a, b) => sortDir === 'desc' ? (b.joinedTs || 0) - (a.joinedTs || 0) : (a.joinedTs || 0) - (b.joinedTs || 0));

  const selected = rows.find((u) => u.email === selectedEmail) || null;

  const updateUser = (email, patch) => setPatches((p) => ({ ...p, [email]: { ...(p[email] || {}), ...patch } }));
  const deleteUser = async (email) => {
    const u = allUsers.find((x) => x.email === email);
    setRemoved((r) => ({ ...r, [email]: true })); setSelectedEmail(null);
    try { if (u && u.uid && window.KlipzyFirebase) await window.KlipzyFirebase.deleteUserDoc(u.uid); } catch (_) {}
  };

  const FILTERS = [['clipper', 'Klipotāji'], ['brand', 'Zīmols'], ['admin', 'Administratori']];

  return (
    <div className="fade-in">
      <TopBar title={T('Lietotāji')} subtitle={T('Visi reģistrētie klipotāji, zīmoli un administratori.')} />
      <div style={{ padding: 32, display: 'flex', gap: 22, alignItems: 'flex-start' }} className="r-userwrap">
        <div style={{ flex: 1, minWidth: 0 }}>
          {/* filter + sort bar */}
          <div className="card" style={{ padding: '12px 18px', marginBottom: 16, display: 'flex', alignItems: 'center', gap: 22, flexWrap: 'wrap' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
              <span className="eyebrow">{T('Filtrēt')}</span>
              {FILTERS.map(([k, label]) => (
                <label key={k} style={{ display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer', fontSize: 13.5, fontWeight: 500, color: 'var(--text-2)' }}>
                  <input type="checkbox" checked={roles[k]} onChange={() => toggleRole(k)} style={{ width: 16, height: 16, accentColor: 'var(--accent)' }} />
                  {T(label)}
                </label>
              ))}
            </div>
            <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 8 }}>
              <span className="eyebrow">{T('Kārtot')}</span>
              <button className="btn btn-secondary btn-sm" style={{ gap: 6 }} onClick={() => setSortDir((d) => d === 'desc' ? 'asc' : 'desc')}>
                {T('Reģistrēts')} · {sortDir === 'desc' ? T('jaunākie') : T('vecākie')}
                <Icon d={sortDir === 'desc' ? I.arrowDown : I.arrowUp} size={15} />
              </button>
            </div>
          </div>
          <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
            <UsersTable rows={rows} onSelect={(u) => setSelectedEmail((e) => e === u.email ? null : u.email)} selectedEmail={selectedEmail} />
            {rows.length === 0 && <div className="muted" style={{ padding: '28px', textAlign: 'center', fontSize: 14 }}>{data.loading ? T('Ielādē…') : T('Nav lietotāju ar izvēlētajiem filtriem.')}</div>}
          </div>
        </div>

        {selected && (
          <AdminUserPanel
            key={selected.email}
            user={selected}
            onClose={() => setSelectedEmail(null)}
            onUpdate={(patch) => updateUser(selected.email, patch)}
            onDelete={() => deleteUser(selected.email)}
            onRequested={onRequested}
          />
        )}
      </div>
    </div>
  );
}

function AdminCampaigns({ data, go }) {
  const lang = useLang();
  const T = (s) => tr(s, lang);
  const { campaigns, loading } = data;
  // Sort by pre-aggregated stored values (views / spent / clippers), hi or lo.
  const [sortKey, setSortKey] = useState('views');
  const [dir, setDir] = useState('desc');
  const remainingOf = (c) => (c.budgetRemaining != null ? c.budgetRemaining : (c.budget || 0) - (c.spent || 0));
  const valueOf = (c) => sortKey === 'spent' ? (c.spent || 0) : sortKey === 'clippers' ? (c.clippers || 0) : (c.views || 0);
  const sorted = [...campaigns].sort((a, b) => dir === 'desc' ? valueOf(b) - valueOf(a) : valueOf(a) - valueOf(b));
  const SORTS = [['views', 'Skatījumi'], ['spent', 'Iztērēts'], ['clippers', 'Klipotāji']];
  return (
    <div className="fade-in">
      <TopBar title={T('Kampaņas')} subtitle={T('Visas platformas kampaņas.')} />
      <div style={{ padding: 32 }}>
        {campaigns.length > 0 && (
          <div className="card" style={{ padding: '12px 18px', marginBottom: 16, display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
            <span className="eyebrow">{T('Kārtot pēc')}</span>
            <div style={{ display: 'inline-flex', gap: 3, padding: 3, background: '#F1F5F9', border: '1px solid var(--border)', borderRadius: 999 }}>
              {SORTS.map(([k, label]) => (
                <button key={k} onClick={() => setSortKey(k)} style={{
                  height: 30, padding: '0 12px', borderRadius: 999, border: 'none', cursor: 'pointer', fontSize: 12.5, fontWeight: 540,
                  background: sortKey === k ? '#fff' : 'transparent', color: sortKey === k ? 'var(--accent-700)' : 'var(--text-2)',
                  boxShadow: sortKey === k ? 'var(--sh-sm)' : 'none',
                }}>{T(label)}</button>
              ))}
            </div>
            <button className="btn btn-secondary btn-sm" style={{ marginLeft: 'auto', gap: 6 }} onClick={() => setDir((d) => d === 'desc' ? 'asc' : 'desc')}>
              {dir === 'desc' ? T('Augstākie') : T('Zemākie')} <Icon d={dir === 'desc' ? I.arrowDown : I.arrowUp} size={15} />
            </button>
          </div>
        )}
        <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
          {loading
            ? <div className="muted" style={{ padding: 28, textAlign: 'center', fontSize: 14 }}>{T('Ielādē…')}</div>
            : campaigns.length === 0
              ? <div className="muted" style={{ padding: 28, textAlign: 'center', fontSize: 14 }}>{T('Vēl nav publicētu kampaņu.')}</div>
              : <CampaignsTable rows={sorted} showRemaining lang={lang} onOpen={go ? (c) => go('campaign', { id: c.id }) : undefined} />}
        </div>
      </div>
    </div>
  );
}

/* ---------- cash-out requests (manual withdrawals) ---------- */
function AdminCashouts({ users }) {
  const lang = useLang();
  const T = (s) => tr(s, lang);
  const { rows, loading, reload } = useAdminCashouts(users);
  const byUid = {}; (users || []).forEach((u) => { byUid[u.uid] = u; });
  const [paying, setPaying] = useState(null);
  const [filter, setFilter] = useState('pending'); // pending | paid | all
  const [copied, setCopied] = useState(null);
  const [toast, setToast] = useState('');
  const [confirmPaid, setConfirmPaid] = useState(null);
  const copyAddr = (r) => {
    if (!r.addr) return;
    const text = r.addr;
    const done = () => { setCopied(r.id); setTimeout(() => setCopied(null), 1500); };
    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(text).then(done).catch(() => { fallbackCopy(text); done(); });
    } else { fallbackCopy(text); done(); }
  };
  const fallbackCopy = (text) => {
    try {
      const ta = document.createElement('textarea');
      ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0'; ta.style.left = '-9999px';
      document.body.appendChild(ta); ta.focus(); ta.select();
      document.execCommand('copy'); document.body.removeChild(ta);
    } catch (_) {}
  };
  const copyText = (id, text) => {
    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(text).then(() => { setCopied(id); setTimeout(() => setCopied(null), 1500); }).catch(() => { fallbackCopy(text); setCopied(id); setTimeout(() => setCopied(null), 1500); });
    } else { fallbackCopy(text); setCopied(id); setTimeout(() => setCopied(null), 1500); }
  };

  // When an admin opens the payouts view, any still-"received" request is
  // auto-advanced to "processing" so the clipper sees it's being handled.
  useEffect(() => {
    let ok = true;
    (async () => {
      for (const r of rows) {
        if (!r.status || r.status === 'received') {
          try { if (window.KlipzyFirebase) await window.KlipzyFirebase.markCashoutProcessing(r.id); } catch (_) {}
        }
      }
      if (ok && rows.some((r) => !r.status || r.status === 'received')) reload();
    })();
    return () => { ok = false; };
  }, [rows.length]);

  // EUR → coin conversion via NOWPayments estimate (works for any coin, not
  // just stablecoins). Cached per row so we don't re-request on every render.
  const [ests, setEsts] = useState({});
  useEffect(() => {
    let ok = true;
    (async () => {
      for (const r of rows) {
        if (!r.coin || ests[r.id] !== undefined) continue;
        const eurAmt = r.net != null ? r.net : r.amount;
        let val = null;
        try { if (window.KlipzyFirebase && window.KlipzyFirebase.estimatePayout) { const e = await window.KlipzyFirebase.estimatePayout(eurAmt, r.coin); if (e && e.amount) val = e.amount; } } catch (_) {}
        if (!ok) return;
        setEsts((m) => ({ ...m, [r.id]: val }));
      }
    })();
    return () => { ok = false; };
  }, [rows]);
  const STABLE = ['USDT', 'USDC', 'DAI', 'BUSD', 'TUSD', 'USDTTRC20', 'USDTERC20'];
  const cryptoAmount = (r) => {
    const v = ests[r.id];
    if (v) return Math.round(v * 100) / 100;
    // Fallback for stablecoins if the live estimate is unavailable (≈ €1 ≈ $1.08).
    const eurAmt = r.net != null ? r.net : r.amount;
    if (r.coin && STABLE.includes((r.coin || '').toUpperCase())) return Math.round(eurAmt * 1.14 * 100) / 100;
    return null;
  };

  const markPaid = async (row) => {
    setConfirmPaid(null);
    setPaying(row.id);
    try { if (window.KlipzyFirebase) await window.KlipzyFirebase.markCashoutPaid(row.id); } catch (_) {}
    setPaying(null);
    setToast(T('Izmaksa atzīmēta kā izmaksāta.'));
    setTimeout(() => setToast(''), 5000);
    reload();
  };
  const markProcessing = async (row) => {
    setPaying(row.id);
    try { if (window.KlipzyFirebase) await window.KlipzyFirebase.markCashoutProcessing(row.id); } catch (_) {}
    setPaying(null);
    reload();
  };
  const [declineRow, setDeclineRow] = useState(null);
  const [declineReason, setDeclineReason] = useState('');
  const markDeclined = async (row, reason) => {
    setDeclineRow(null); setDeclineReason('');
    setPaying(row.id);
    try { if (window.KlipzyFirebase) await window.KlipzyFirebase.markCashoutDeclined(row.id, reason); } catch (_) {}
    setPaying(null);
    setToast(T('Izmaksa atteikta un līdzekļi atgriezti.'));
    setTimeout(() => setToast(''), 5000);
    reload();
  };
  const markFailed = async (row) => {
    const reason = window.prompt(T('Neizdošanās iemesls:'), '');
    if (reason === null) return;
    setPaying(row.id);
    try { if (window.KlipzyFirebase) await window.KlipzyFirebase.markCashoutFailed(row.id, reason); } catch (_) {}
    setPaying(null);
    reload();
  };

  const daysLeft = (row) => {
    const created = row.createdAt && row.createdAt.seconds ? row.createdAt.seconds * 1000 : Date.now();
    const windowDays = row.instant ? 1 : 7;
    const dueMs = created + windowDays * 86400000;
    return Math.max(0, Math.ceil((dueMs - Date.now()) / 86400000));
  };

  const filtered = rows.filter((r) => filter === 'all' ? true : filter === 'paid' ? r.status === 'paid' : (r.status !== 'paid' && r.status !== 'failed' && r.status !== 'declined'));

  return (
    <div className="fade-in">
      <TopBar title={T('Izmaksas')} subtitle={T('Klipotāju un zīmolu izmaksas pieprasījumi, kas jāapstrādā manuāli.')} />
      <div style={{ padding: 32 }}>
        <div className="card" style={{ padding: '12px 18px', marginBottom: 16, display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{ display: 'inline-flex', gap: 3, padding: 3, background: '#F1F5F9', border: '1px solid var(--border)', borderRadius: 999 }}>
            {[['pending', 'Neapstrādātas'], ['paid', 'Izmaksātas'], ['all', 'Visas']].map(([k, label]) => (
              <button key={k} onClick={() => setFilter(k)} style={{
                height: 30, padding: '0 12px', borderRadius: 999, border: 'none', cursor: 'pointer', fontSize: 12.5, fontWeight: 540,
                background: filter === k ? '#fff' : 'transparent', color: filter === k ? 'var(--accent-700)' : 'var(--text-2)',
                boxShadow: filter === k ? 'var(--sh-sm)' : 'none',
              }}>{T(label)}</button>
            ))}
          </div>
        </div>
        <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
          {loading ? (
            <div className="muted" style={{ padding: 28, textAlign: 'center', fontSize: 14 }}>{T('Ielādē…')}</div>
          ) : filtered.length === 0 ? (
            <div className="muted" style={{ padding: 28, textAlign: 'center', fontSize: 14 }}>{T('Nav izmaksas pieprasījumu.')}</div>
          ) : (
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 14 }}>
              <thead>
                <tr style={{ textAlign: 'left', color: 'var(--muted)', fontSize: 12.5 }}>
                  <th style={{ padding: '12px 22px', fontWeight: 540 }}>{T('Lietotājs')}</th>
                  <th style={{ padding: '12px 16px', fontWeight: 540 }}>{T('Summa')}</th>
                  <th style={{ padding: '12px 16px', fontWeight: 540 }}>{T('Metode')}</th>
                  <th style={{ padding: '12px 16px', fontWeight: 540 }}>{T('Statuss')}</th>
                  <th style={{ padding: '12px 16px', fontWeight: 540 }}></th>
                </tr>
              </thead>
              <tbody>
                {filtered.map((r) => {
                  const u = byUid[r.clipperUid || r.brandUid];
                  const paid = r.status === 'paid';
                  const dLeft = daysLeft(r);
                  return (
                    <tr key={r.id} style={{ borderTop: '1px solid var(--border)' }}>
                      <td style={{ padding: '12px 22px' }}>
                        <div style={{ fontSize: 13.5, fontWeight: 540 }}>{u ? u.name : (r.clipperUid || r.brandUid || '—')}</div>
                        <div className="muted" style={{ fontSize: 12.5 }}>{u ? u.email : ''}</div>
                      </td>
                      <td style={{ padding: '12px 16px' }}>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                          <span className="tnum">{eur(r.net != null ? r.net : r.amount)}</span>
                          <button className="btn btn-ghost btn-sm" style={{ padding: 4 }} title={T('Kopēt summu')} onClick={() => copyText('eur-' + r.id, String((r.net != null ? r.net : r.amount).toFixed(2)))}>
                            <Icon d={copied === ('eur-' + r.id) ? I.check : I.copy} size={13} sw={2.2} />
                          </button>
                        </div>
                        {cryptoAmount(r) && (
                          <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 2 }}>
                            <span className="tnum" style={{ fontSize: 12, color: 'var(--accent-700)' }}>≈ {cryptoAmount(r)} {r.coin}</span>
                            <button className="btn btn-ghost btn-sm" style={{ padding: 4 }} title={T('Kopēt summu')} onClick={() => copyText('amt-' + r.id, cryptoAmount(r))}>
                              <Icon d={copied === ('amt-' + r.id) ? I.check : I.copy} size={13} sw={2.2} />
                            </button>
                          </div>
                        )}
                      </td>
                      <td style={{ padding: '12px 16px' }}>
                        {r.addr ? (
                          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                            <span className="tnum" style={{ fontSize: 12.5 }}>{r.coin ? r.coin + ' · ' : ''}{r.addr.slice(0, 6)}…{r.addr.slice(-4)}</span>
                            <button className="btn btn-ghost btn-sm" style={{ padding: 5 }} title={T('Kopēt adresi')} onClick={() => copyAddr(r)}>
                              <Icon d={copied === r.id ? I.check : I.copy} size={15} sw={2.2} />
                            </button>
                            {copied === r.id && <span style={{ fontSize: 11.5, color: 'var(--green)' }}>{T('Nokopēts')}</span>}
                          </div>
                        ) : (r.method || '—')}
                        {r.network ? <span className="badge" style={{ marginLeft: 6, background: 'var(--accent-tint)', color: 'var(--accent-700)' }}>{r.network}</span> : null}
                        {r.instant ? <span className="badge badge-amber" style={{ marginLeft: 6 }}>{T('tūlītēja')}</span> : null}
                      </td>
                      <td style={{ padding: '12px 16px' }}>
                        {r.status === 'paid' ? <span className="badge badge-green">{T('Izmaksāts')}</span>
                          : r.status === 'processing' ? <span className="badge badge-blue">{T('Apstrādē')}</span>
                          : r.status === 'declined' ? <span className="badge badge-red" title={r.failReason || ''}>{T('Atteikts')}</span>
                          : r.status === 'failed' ? <span className="badge badge-red" title={r.failReason || ''}>{T('Neizdevās')}</span>
                          : <span className="badge badge-amber">{dLeft} {T('dienas atlikušas')}</span>}
                      </td>
                      <td style={{ padding: '12px 16px', textAlign: 'right' }}>
                        {r.status !== 'paid' && (
                          <div style={{ display: 'inline-flex', gap: 6, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
                            {r.status !== 'declined' && (
                              <button className="btn btn-secondary btn-sm" style={{ color: 'var(--red)' }} disabled={paying === r.id} onClick={() => { setDeclineReason(''); setDeclineRow(r); }}>{T('Atteikt')}</button>
                            )}
                            {r.status !== 'declined' && (
                              <button className="btn btn-primary btn-sm" disabled={paying === r.id} onClick={() => setConfirmPaid(r)}>
                                {paying === r.id ? T('Saglabā…') : T('Atzīmēt kā izmaksātu')}
                              </button>
                            )}
                          </div>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}
        </div>
      </div>
      {declineRow && (() => {
        const forBrand = !!declineRow.brandUid;
        const roleWord = forBrand ? T('zīmolam') : T('klipotājam');
        return (
          <ModalShell onClose={() => setDeclineRow(null)} width={440}>
              <div className="spread" style={{ marginBottom: 10 }}>
                <h3 style={{ fontSize: 18 }}>{T('Atteikt izmaksu')}</h3>
                <button className="btn btn-ghost btn-sm" style={{ padding: 6 }} onClick={() => setDeclineRow(null)}><Icon d={I.x} size={18} /></button>
              </div>
              <label style={{ fontSize: 13, fontWeight: 540, display: 'block', marginBottom: 6 }}>{T('Atteikuma iemesls (redzams')} {roleWord}):</label>
              <textarea className="input" rows={3} value={declineReason} onChange={(e) => setDeclineReason(e.target.value)} style={{ width: '100%', resize: 'vertical', minHeight: 84, padding: '14px 14px', lineHeight: 1.5 }} autoFocus />
              <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', marginTop: 16 }}>
                <button className="btn btn-secondary btn-sm" onClick={() => setDeclineRow(null)}>{T('Atcelt')}</button>
                <button className="btn btn-primary btn-sm" style={{ background: 'var(--red)', borderColor: 'var(--red)' }} onClick={() => markDeclined(declineRow, declineReason)}>{T('Atteikt un atgriezt līdzekļus')}</button>
              </div>
          </ModalShell>
        );
      })()}
      {confirmPaid && (
        <ModalShell onClose={() => setConfirmPaid(null)} width={420}>
          <div className="spread" style={{ marginBottom: 10 }}>
            <h3 style={{ fontSize: 18 }}>{T('Apstiprināt izmaksu')}</h3>
            <button className="btn btn-ghost btn-sm" style={{ padding: 6 }} onClick={() => setConfirmPaid(null)}><Icon d={I.x} size={18} /></button>
          </div>
          <p className="muted" style={{ fontSize: 14, lineHeight: 1.5 }}>{T('Vai tiešām atzīmēt šo izmaksu kā izmaksātu?')} {(byUid[confirmPaid.clipperUid || confirmPaid.brandUid] || {}).name ? '(' + (byUid[confirmPaid.clipperUid || confirmPaid.brandUid] || {}).name + ' · ' + eur(confirmPaid.net != null ? confirmPaid.net : confirmPaid.amount) + ')' : ''}</p>
          <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', marginTop: 18 }}>
            <button className="btn btn-secondary btn-sm" onClick={() => setConfirmPaid(null)}>{T('Atcelt')}</button>
            <button className="btn btn-primary btn-sm" onClick={() => markPaid(confirmPaid)}>{T('Atzīmēt kā izmaksātu')}</button>
          </div>
        </ModalShell>
      )}
      <Toast msg={toast} onClose={() => setToast('')} />
    </div>
  );
}

/* ---------- admin messages (contact form) ---------- */
function AdminMessages() {
  const lang = useLang();
  const T = (s) => tr(s, lang);
  const [rows, setRows] = useState(null);
  useEffect(() => {
    let ok = true;
    (async () => {
      let list = [];
      try { if (window.KlipzyFirebase && window.KlipzyFirebase.listContactMessages) list = await window.KlipzyFirebase.listContactMessages(); } catch (_) {}
      if (ok) setRows(list);
    })();
    return () => { ok = false; };
  }, []);
  return (
    <div className="fade-in">
      <TopBar title={T('Ziņas')} subtitle={T('Ziņas no kontaktu formas.')} />
      <div style={{ padding: 32 }}>
        <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
          {rows === null ? (
            <div className="muted" style={{ padding: 28, textAlign: 'center', fontSize: 14 }}>{T('Ielādē…')}</div>
          ) : rows.length === 0 ? (
            <div className="muted" style={{ padding: 28, textAlign: 'center', fontSize: 14 }}>{T('Nav ziņu.')}</div>
          ) : rows.map((r) => {
            const d = r.createdAt && r.createdAt.seconds ? new Date(r.createdAt.seconds * 1000).toLocaleString(lang === 'en' ? 'en-GB' : 'lv-LV') : '—';
            return (
              <div key={r.id} style={{ padding: '16px 22px', borderTop: '1px solid var(--border)' }}>
                <div className="spread" style={{ gap: 12, flexWrap: 'wrap', marginBottom: 6 }}>
                  <div style={{ fontSize: 14, fontWeight: 600 }}>{r.subject || T('(bez tēmas)')}</div>
                  <span className="muted tnum" style={{ fontSize: 12 }}>{d}</span>
                </div>
                <div className="muted" style={{ fontSize: 12.5, marginBottom: 8 }}>{r.name} · <a href={'mailto:' + r.email} style={{ color: 'var(--accent-700)' }}>{r.email}</a></div>
                <div style={{ fontSize: 13.5, color: 'var(--text-2)', lineHeight: 1.5, whiteSpace: 'pre-wrap' }}>{r.message}</div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

/* ---------- audit log (append-only oversight feed) ---------- */
const ROLE_BADGE = {
  clipper: { label: 'Klipotājs', bg: 'var(--accent-tint)', fg: 'var(--accent-700)' },
  brand: { label: 'Zīmols', bg: '#FFE4E6', fg: '#BE123C' },
  admin: { label: 'Administrators', bg: '#FEF3C7', fg: '#B45309' },
};

function UsersTable({ rows, onSelect, selectedEmail }) {
  const lang = useLang();
  const T = (s) => tr(s, lang);
  return (
    <table className="r-fit" style={{ width: '100%', borderCollapse: 'collapse', fontSize: 14 }}>
      <thead>
        <tr style={{ textAlign: 'left', color: 'var(--muted)', fontSize: 12.5 }}>
          <th style={{ padding: '12px 22px', fontWeight: 540 }}>{T('Lietotājs')}</th>
          <th style={{ padding: '12px 16px', fontWeight: 540 }}>{T('Loma')}</th>
          <th style={{ padding: '12px 16px', fontWeight: 540 }}>{T('Reģistrēts')}</th>
          {onSelect && <th style={{ padding: '12px 16px', width: 48 }}></th>}
        </tr>
      </thead>
      <tbody>
        {rows.map((u) => {
          const b = ROLE_BADGE[u.role] || ROLE_BADGE.clipper;
          const on = selectedEmail === u.email;
          return (
            <tr key={u.email} style={{ borderTop: '1px solid var(--border)', background: on ? 'var(--accent-tint)' : 'transparent' }}>
              <td style={{ padding: '12px 22px' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
                  <BrandLogo initials={u.initials} grad={u.grad} size={34} radius={9} src={u.photoURL} />
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 540 }}>{u.name}</div>
                    <div className="muted" style={{ fontSize: 12.5 }}>{u.email}</div>
                  </div>
                </div>
              </td>
              <td style={{ padding: '12px 16px' }}>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '3px 10px', borderRadius: 999, fontSize: 12, fontWeight: 560, background: b.bg, color: b.fg }}>
                  {T(b.label)}
                  {u.role === 'brand' && u.approved === false ? <span style={{ fontSize: 10.5, opacity: .8 }}>· {T('gaida')}</span> : null}
                </span>
              </td>
              <td style={{ padding: '12px 16px' }} className="muted tnum">{u.joined}</td>
              {onSelect && (
                <td style={{ padding: '12px 16px' }}>
                  {u.role !== 'admin' && (
                    <button onClick={() => onSelect(u)} aria-label={T('Darbības')} className="btn btn-ghost btn-sm"
                      style={{ padding: 6, color: on ? 'var(--accent-700)' : 'var(--muted)' }}>
                      <Icon d={I.dots} size={18} sw={2.4} />
                    </button>
                  )}
                </td>
              )}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

/* ---------- per-user action + detail panel ---------- */
function AdminUserPanel({ user, onClose, onUpdate, onDelete, onRequested }) {
  const lang = useLang();
  const T = (s) => tr(s, lang);
  const [removingPhoto, setRemovingPhoto] = useState(false);
  const removePhoto = async () => {
    setRemovingPhoto(true);
    try {
      if (window.KlipzyFirebase) {
        await window.KlipzyFirebase.removeProfilePhoto(user.uid, user.photoPath);
        await window.KlipzyFirebase.createNotification({ toUid: user.uid, toRole: user.role, kind: 'photoRemoved', severity: 'reminder', message: 'Tavs profila attēls tika noņemts, jo tas neatbilda platformas prasībām. Lūdzu, augšupielādē citu.' });
      }
    } catch (_) {}
    setRemovingPhoto(false);
    onUpdate({ photoURL: null, photoPath: null });
  };
  const isBrand = user.role === 'brand';
  const [confirmDelete, setConfirmDelete] = useState(false);
  const [reqOpen, setReqOpen] = useState(false);
  const [reqText, setReqText] = useState('');
  const [reqSeverity, setReqSeverity] = useState('reminder');
  const [reqSent, setReqSent] = useState(false);
  const [reqBusy, setReqBusy] = useState(false);
  const [campView, setCampView] = useState('active');

  const sendRequest = async () => {
    if (!reqText.trim()) return;
    setReqBusy(true);
    try {
      if (window.KlipzyFirebase) await window.KlipzyFirebase.createNotification({ toUid: user.uid, toRole: user.role, message: reqText.trim(), severity: reqSeverity });
    } catch (_) {}
    setReqBusy(false);
    setReqSent(true);
    setReqText('');
    if (onRequested) onRequested();
    setTimeout(() => { setReqSent(false); setReqOpen(false); setReqSeverity('reminder'); }, 2200);
  };

  return (
    <aside className="card fade-in r-userpanel" style={{ width: 340, flex: 'none', padding: 0, position: 'sticky', top: 96, overflow: 'hidden' }}>
      {/* header */}
      <div style={{ padding: '18px 18px 16px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 12 }}>
        <BrandLogo initials={user.initials} grad={user.grad} size={42} radius={11} src={user.photoURL} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 15, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{user.name}</div>
          <div className="muted" style={{ fontSize: 12.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{user.email}</div>
        </div>
        <button className="btn btn-ghost btn-sm" style={{ padding: 6 }} onClick={onClose} aria-label={T('Aizvērt')}><Icon d={I.x} size={16} /></button>
      </div>

      {/* info box */}
      <div style={{ padding: 18, borderBottom: '1px solid var(--border)' }}>
        <div className="eyebrow" style={{ marginBottom: 12 }}>{isBrand ? T('Zīmola dati') : T('Klipotāja dati')}</div>
        {isBrand ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            <InfoRow label={T('Iztērēts')} value={eur0(user.spent)} />
            <InfoRow label={T('Kopējie skatījumi')} value={views(user.totalViews)} />
            <InfoRow label={T('Aktīvās kampaņas')} value={String(user.activeCampaigns)} />
            <InfoRow label={T('Pēdējā kampaņa')} value={user.lastCampaign} />
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div style={{ display: 'flex', gap: 10 }}>
              <MiniMetric label={T('Kopā izmaksāts')} value={eur(user.totalPayouts)} />
              <MiniMetric label={T('Skatījumi')} value={views(user.totalViews)} />
            </div>
            <div>
              <div style={{ display: 'inline-flex', gap: 3, padding: 3, background: '#F1F5F9', border: '1px solid var(--border)', borderRadius: 999, marginBottom: 10 }}>
                {[['active', 'Aktīvās'], ['finished', 'Pabeigtās']].map(([k, label]) => (
                  <button key={k} onClick={() => setCampView(k)} style={{
                    height: 28, padding: '0 12px', borderRadius: 999, border: 'none', cursor: 'pointer', fontSize: 12.5, fontWeight: 540,
                    background: campView === k ? '#fff' : 'transparent', color: campView === k ? 'var(--accent-700)' : 'var(--text-2)',
                    boxShadow: campView === k ? 'var(--sh-sm)' : 'none',
                  }}>{T(label)}</button>
                ))}
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                {(campView === 'active' ? user.active : user.finished).map((c) => (
                  <div key={c.name} className="spread" style={{ fontSize: 13 }}>
                    <span style={{ fontWeight: 500 }}>{c.name}</span>
                    <span className="muted tnum">{views(c.views)}</span>
                  </div>
                ))}
                {(campView === 'active' ? user.active : user.finished).length === 0 && (
                  <div className="muted" style={{ fontSize: 12.5 }}>{campView === 'active' ? T('Nav aktīvu kampaņu.') : T('Nav pabeigtu kampaņu.')}</div>
                )}
              </div>
            </div>
          </div>
        )}
      </div>

      {/* actions */}
      <div style={{ padding: 18, display: 'flex', flexDirection: 'column', gap: 10 }}>
        {user.photoURL && (
          <button className="btn btn-secondary btn-block" style={{ color: '#DC2626', borderColor: '#FECACA' }}
            disabled={removingPhoto} onClick={removePhoto}>
            <Icon d={I.x} size={16} /> {removingPhoto ? T('Noņem…') : T('Noņemt profila bildi')}
          </button>
        )}
        {isBrand && user.approved === false && (
          <button className="btn btn-primary btn-block" style={{ background: 'var(--green)', borderColor: 'var(--green)' }} onClick={() => onUpdate({ approved: true })}>
            <Icon d={I.check} size={16} sw={2.4} /> {T('Apstiprināt')}
          </button>
        )}
        {isBrand && user.approved === true && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: 'var(--green)', fontWeight: 540, padding: '2px 0 4px' }}>
            <Icon d={I.check} size={16} sw={2.4} /> {T('Konts apstiprināts')}
          </div>
        )}

        {/* request more info */}
        {!reqOpen ? (
          <button className="btn btn-secondary btn-block" onClick={() => setReqOpen(true)}>
            <Icon d={I.inbox} size={16} /> {T('Pieprasīt papildu informāciju')}
          </button>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {reqSent ? (
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: 'var(--green)', fontWeight: 540, background: 'var(--green-tint)', borderRadius: 'var(--r)', padding: '10px 12px' }}>
                <Icon d={I.check} size={16} sw={2.4} /> {T('Pieprasījums nosūtīts')} {isBrand ? T('zīmolam') : T('klipotājam')}
              </div>
            ) : (
              <>
                <textarea className="input" value={reqText} onChange={(e) => setReqText(e.target.value)} rows={3}
                  placeholder={T('Ziņa') + ' ' + (isBrand ? T('zīmolam') : T('klipotājam')) + '…'} style={{ resize: 'vertical', minHeight: 70, fontFamily: 'inherit' }} />
                <div style={{ display: 'inline-flex', gap: 3, padding: 3, background: '#F1F5F9', border: '1px solid var(--border)', borderRadius: 999 }}>
                  {[['reminder', 'Atģādinājums'], ['critical', 'Jādara tagad']].map(([k, label]) => (
                    <button key={k} onClick={() => setReqSeverity(k)} style={{
                      height: 30, padding: '0 12px', borderRadius: 999, border: 'none', cursor: 'pointer', fontSize: 12.5, fontWeight: 540,
                      background: reqSeverity === k ? '#fff' : 'transparent',
                      color: reqSeverity === k ? (k === 'critical' ? 'var(--red)' : 'var(--amber)') : 'var(--text-2)',
                      boxShadow: reqSeverity === k ? 'var(--sh-sm)' : 'none',
                    }}>{T(label)}</button>
                  ))}
                </div>
                <div style={{ display: 'flex', gap: 8 }}>
                  <button className="btn btn-primary btn-sm" style={{ flex: 1, gap: 6 }} disabled={!reqText.trim() || reqBusy} onClick={sendRequest}>
                    <Icon d={I.send} size={15} /> {reqBusy ? T('Sūta…') : T('Nosūtīt')}
                  </button>
                  <button className="btn btn-ghost btn-sm" onClick={() => { setReqOpen(false); setReqText(''); }}>{T('Atcelt')}</button>
                </div>
              </>
            )}
          </div>
        )}

        {/* delete */}
        {!confirmDelete ? (
          <button className="btn btn-secondary btn-block" style={{ color: '#DC2626', borderColor: '#FECACA' }} onClick={() => setConfirmDelete(true)}>
            <Icon d={I.trash} size={16} /> {isBrand ? T('Dzēst zīmola kontu') : T('Dzēst klipotāja kontu')}
          </button>
        ) : (
          <div style={{ background: '#FEF2F2', border: '1px solid #FECACA', borderRadius: 'var(--r)', padding: 12 }}>
            <div style={{ fontSize: 13, color: '#991B1B', fontWeight: 540, marginBottom: 4 }}>{T('Dzēst šo kontu?')}</div>
            <div style={{ fontSize: 12.5, color: '#B91C1C', marginBottom: 10 }}>{T('Šo darbību nevar atsaukt.')}</div>
            <div style={{ display: 'flex', gap: 8 }}>
              <button className="btn btn-sm" style={{ flex: 1, background: '#DC2626', color: '#fff', borderColor: '#DC2626', gap: 6 }} onClick={onDelete}>
                <Icon d={I.trash} size={15} /> {T('Apstiprināt dzēšanu')}
              </button>
              <button className="btn btn-ghost btn-sm" onClick={() => setConfirmDelete(false)}>{T('Atcelt')}</button>
            </div>
          </div>
        )}
      </div>
    </aside>
  );
}

function InfoRow({ label, value }) {
  return (
    <div className="spread" style={{ fontSize: 13.5 }}>
      <span className="muted">{label}</span>
      <span style={{ fontWeight: 560, textAlign: 'right', maxWidth: 180 }}>{value}</span>
    </div>
  );
}

function MiniMetric({ label, value }) {
  return (
    <div style={{ flex: 1, background: '#F8FAFC', border: '1px solid var(--border)', borderRadius: 'var(--r)', padding: '10px 12px' }}>
      <div className="tnum" style={{ fontSize: 16, fontWeight: 600, letterSpacing: '-0.02em' }}>{value}</div>
      <div className="muted" style={{ fontSize: 11.5, marginTop: 2 }}>{label}</div>
    </div>
  );
}

Object.assign(window, { AdminApp });
