// Admin center
const { useState: useStateAD, useMemo: useMemoAD } = React;

function AdminPage({ openCity }) {
  const store = useStore();
  const [tab, setTab] = useStateAD('feedback');

  if (!store.isAdmin()) return <div className="page-empty">Admin access required.</div>;

  return (
    <div className="page admin-page">
      <div className="page-head">
        <div>
          <div className="loc-kicker">CONTROL CENTER · {store.getCurrentUser().email.toUpperCase()}</div>
          <h1 className="page-title">Admin</h1>
          <div className="page-sub">Triage feedback, moderate user-submitted cities, monitor usage.</div>
        </div>
      </div>

      <div className="admin-tabs">
        <button className={`pb-tab ${tab === 'feedback' ? 'on' : ''}`} onClick={() => setTab('feedback')}>Feedback <span className="tab-count">{store.getFeedback().length}</span></button>
        <button className={`pb-tab ${tab === 'cities' ? 'on' : ''}`} onClick={() => setTab('cities')}>City moderation</button>
        <button className={`pb-tab ${tab === 'users' ? 'on' : ''}`} onClick={() => setTab('users')}>Users <span className="tab-count">{store.getAllUsers().length}</span></button>
        <button className={`pb-tab ${tab === 'affiliates' ? 'on' : ''}`} onClick={() => setTab('affiliates')}>Affiliate IDs</button>
        <button className={`pb-tab ${tab === 'ai' ? 'on' : ''}`} onClick={() => setTab('ai')}>AI</button>
        <button className={`pb-tab ${tab === 'analytics' ? 'on' : ''}`} onClick={() => setTab('analytics')}>Analytics</button>
      </div>

      {tab === 'feedback' && <AdminFeedback/>}
      {tab === 'cities' && <AdminCities openCity={openCity}/>}
      {tab === 'users' && <AdminUsers/>}
      {tab === 'affiliates' && <AdminAffiliates/>}
      {tab === 'ai' && <AdminAI/>}
      {tab === 'analytics' && <AdminAnalytics/>}
    </div>
  );
}

function AdminFeedback() {
  const store = useStore();
  const [statusFilter, setStatusFilter] = useStateAD('open');
  const [openId, setOpenId] = useStateAD(null);
  const list = store.getFeedback().filter(f => statusFilter === 'all' || f.status === statusFilter);

  return (
    <div className="admin-feedback">
      <div className="snip-dash-filters">
        {['open','triaged','in-progress','resolved','wontfix','all'].map(s => (
          <button key={s} className={`chip ${statusFilter === s ? 'on' : ''}`} onClick={() => setStatusFilter(s)}>{s}</button>
        ))}
      </div>
      <table className="admin-table">
        <thead>
          <tr><th>Type</th><th>Title</th><th>From</th><th>Status</th><th>When</th><th></th></tr>
        </thead>
        <tbody>
          {list.map(f => (
            <React.Fragment key={f.id}>
              <tr className={openId === f.id ? 'open' : ''}>
                <td><span className={`fb-kind ${f.kind}`}>{f.kind}</span>{f.severity && f.kind === 'bug' && <span className={`fb-sev ${f.severity}`}>{f.severity}</span>}</td>
                <td>{f.title}</td>
                <td className="muted">{f.userName} <span className="dim">{f.contact}</span></td>
                <td>
                  <select className="settings-input compact" value={f.status} onChange={e => store.updateFeedback(f.id, { status: e.target.value })}>
                    {['open','triaged','in-progress','resolved','wontfix'].map(s => <option key={s} value={s}>{s}</option>)}
                  </select>
                </td>
                <td className="muted">{new Date(f.createdAt).toLocaleDateString()}</td>
                <td>
                  <button className="loc-tag-btn" onClick={() => setOpenId(openId === f.id ? null : f.id)}>{openId === f.id ? 'close' : 'open'}</button>
                  <button className="loc-tag-btn" onClick={() => { if (confirm('Delete?')) store.deleteFeedback(f.id); }}>delete</button>
                </td>
              </tr>
              {openId === f.id && (
                <tr className="admin-row-detail"><td colSpan="6">
                  <div className="fb-body">{f.body}</div>
                  <textarea className="settings-input bio-text" rows="3" placeholder="Admin notes…" defaultValue={f.adminNotes}
                    onBlur={e => store.updateFeedback(f.id, { adminNotes: e.target.value })}/>
                </td></tr>
              )}
            </React.Fragment>
          ))}
          {!list.length && <tr><td colSpan="6" className="muted">No feedback in this bucket.</td></tr>}
        </tbody>
      </table>
    </div>
  );
}

function AdminCities({ openCity }) {
  const store = useStore();
  const all = store.getAllPlaybooks();
  const userCities = [];
  for (const pb of all) {
    for (const d of pb.destinations) {
      if (d.userAdded) userCities.push({ ...d, ownerEmail: pb.userId });
    }
  }
  const moderation = store.getCityModeration();
  return (
    <div className="admin-cities">
      <div className="muted" style={{ marginBottom: 12 }}>User-submitted cities pulled from playbooks. Approve to feature on the public globe.</div>
      <table className="admin-table">
        <thead><tr><th>City</th><th>Status</th><th>Submitted by</th><th>Coords</th><th></th></tr></thead>
        <tbody>
          {userCities.length === 0 && <tr><td colSpan="5" className="muted">No user cities yet.</td></tr>}
          {userCities.map(c => (
            <tr key={c.id}>
              <td>{c.label}</td>
              <td>
                <select className="settings-input compact" value={moderation[c.id] || 'pending'} onChange={e => store.setCityStatus(c.id, e.target.value)}>
                  {['pending','published','rejected'].map(s => <option key={s} value={s}>{s}</option>)}
                </select>
              </td>
              <td className="muted">{c.ownerEmail}</td>
              <td className="muted mono-small">{c.lat?.toFixed(2)}, {c.lng?.toFixed(2)}</td>
              <td>{c.cityId && <button className="loc-tag-btn" onClick={() => openCity?.(c.cityId)}>view</button>}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function AdminUsers() {
  const store = useStore();
  const users = store.getAllUsers();
  return (
    <table className="admin-table">
      <thead><tr><th>Name</th><th>Email</th><th>Provider</th><th>Role</th><th>Joined</th><th>Playbooks</th></tr></thead>
      <tbody>
        {users.map(u => {
          const all = store.getAllPlaybooks().filter(p => p.userId === u.id);
          return (
            <tr key={u.id}>
              <td>{u.name}</td><td>{u.email}</td><td>{u.provider}</td>
              <td><span className={`role-tag ${u.role}`}>{u.role}</span></td>
              <td className="muted">{new Date(u.createdAt).toLocaleDateString()}</td>
              <td>{all.length}</td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

function AdminAffiliates() {
  const [, force] = useStateAD(0);
  const configs = window.allAffiliateConfigs();
  const ids = window.affiliateIds.get();
  const grouped = {};
  for (const c of configs) (grouped[c.category] = grouped[c.category] || []).push(c);

  const setId = (k, v) => { window.affiliateIds.set(k, v); force(x => x + 1); };

  const exportJson = () => {
    const text = JSON.stringify(window.affiliateIds.get(), null, 2);
    navigator.clipboard?.writeText(text);
    alert('Affiliate IDs copied as JSON.');
  };
  const importJson = () => {
    const raw = prompt('Paste JSON map of affiliate IDs:');
    if (!raw) return;
    try { window.affiliateIds.setAll(JSON.parse(raw)); force(x => x + 1); }
    catch { alert('Invalid JSON.'); }
  };
  const clearAll = () => { if (confirm('Clear ALL affiliate IDs?')) { window.affiliateIds.clear(); force(x => x + 1); } };

  const filled = Object.keys(ids).length;
  const total = configs.length;

  return (
    <div className="admin-affiliates">
      <div className="affil-summary">
        <div>
          <div className="loc-kicker">PROGRAMS · {filled}/{total} CONFIGURED</div>
          <div className="affil-help">
            Paste your affiliate / referral / partner ID for each program below. Empty fields still produce working search links — they just don't earn commission. Apply at each program's site; networks like <b>Travelpayouts</b>, <b>Impact</b>, and <b>Awin</b> bundle many programs under one signup.
          </div>
        </div>
        <div className="affil-actions">
          <button className="loc-tag-btn" onClick={exportJson}>Copy JSON</button>
          <button className="loc-tag-btn" onClick={importJson}>Paste JSON</button>
          <button className="loc-tag-btn danger" onClick={clearAll}>Clear all</button>
        </div>
      </div>

      {Object.entries(grouped).map(([cat, list]) => (
        <div key={cat} className="affil-cat">
          <div className="affil-cat-head">{cat.toUpperCase()}</div>
          <table className="admin-table affil-table">
            <thead>
              <tr><th>Provider</th><th>Network</th><th>URL param</th><th>Your ID</th><th></th></tr>
            </thead>
            <tbody>
              {list.map(c => (
                <tr key={c.key}>
                  <td><b>{c.provider}</b></td>
                  <td><span className={`net-tag ${c.network}`}>{c.network}</span></td>
                  <td className="mono-small">{c.paramName || '—'}</td>
                  <td>
                    <input className="settings-input compact"
                      placeholder={`e.g. your-${c.network}-id`}
                      defaultValue={ids[c.key] || ''}
                      onBlur={e => setId(c.key, e.target.value.trim())}/>
                  </td>
                  <td>
                    {ids[c.key] ? <span className="affil-ok">●</span> : <span className="affil-pending">○</span>}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      ))}
    </div>
  );
}

function AdminAI() {
  const { useState: useS, useEffect: useE } = React;
  const [cfg, setCfg]         = useS(null);
  const [usage, setUsage]     = useS([]);
  const [users, setUsers]     = useS({});
  const [loading, setLoading] = useS(true);
  const [saving, setSaving]   = useS(false);
  const [draft, setDraft]     = useS({ enabled: true, per_user_cap_usd: 0.15, api_key_override: '', notes: '' });

  const refresh = async () => {
    setLoading(true);
    const [c, u] = await Promise.all([
      window.fsnCloud.getAiConfig(),
      window.fsnCloud.getAiUsageAll(),
    ]);
    if (c) {
      setCfg(c);
      setDraft({
        enabled: c.enabled !== false,
        per_user_cap_usd: parseFloat(c.per_user_cap_usd ?? 0.15),
        api_key_override: c.api_key_override || '',
        notes: c.notes || '',
      });
    }
    setUsage(u || []);
    // Build user lookup from store
    const all = window.store.getAllUsers();
    const map = {};
    for (const x of all) map[x.id] = x;
    setUsers(map);
    setLoading(false);
  };

  useE(() => { refresh(); }, []);

  const save = async () => {
    setSaving(true);
    await window.fsnCloud.updateAiConfig({
      enabled: !!draft.enabled,
      per_user_cap_usd: parseFloat(draft.per_user_cap_usd) || 0,
      api_key_override: draft.api_key_override?.trim() || null,
      notes: draft.notes || null,
    });
    setSaving(false);
    refresh();
  };

  const resetUser = async (userId) => {
    if (!confirm('Reset this user\'s AI usage to zero?')) return;
    await window.fsnCloud.resetUserAiUsage(userId);
    refresh();
  };

  if (loading) return <div className="muted" style={{ padding: 20 }}>Loading AI dashboard…</div>;

  const totalSpend = usage.reduce((a, u) => a + parseFloat(u.total_cost_usd || 0), 0);
  const totalCalls = usage.reduce((a, u) => a + (u.request_count || 0), 0);
  const cap = parseFloat(draft.per_user_cap_usd) || 0;

  return (
    <div className="admin-ai">
      <div className="kpi-grid" style={{ marginBottom: 24 }}>
        <Kpi label="Total spend" value={`$${totalSpend.toFixed(4)}`} accent="#9bbf8c"/>
        <Kpi label="Total calls" value={totalCalls}/>
        <Kpi label="Active users" value={usage.length}/>
        <Kpi label="Per-user cap" value={`$${cap.toFixed(2)}`} accent="#7fb6d9"/>
        <Kpi label="Status" value={draft.enabled ? 'ON' : 'OFF'} accent={draft.enabled ? '#9bbf8c' : '#d99a8c'}/>
      </div>

      <div className="ai-config-card">
        <div className="loc-kicker">PROXY CONFIG</div>
        <div className="ai-config-grid">
          <label className="ai-config-row">
            <input type="checkbox" checked={!!draft.enabled} onChange={e => setDraft({ ...draft, enabled: e.target.checked })}/>
            <div>
              <div className="ai-config-label">AI features enabled</div>
              <div className="ai-config-help">Master killswitch. When off, all users see "AI temporarily disabled".</div>
            </div>
          </label>

          <div className="ai-config-row">
            <div className="ai-config-label">Per-user budget cap (USD)</div>
            <input className="settings-input" type="number" step="0.01" min="0"
              value={draft.per_user_cap_usd}
              onChange={e => setDraft({ ...draft, per_user_cap_usd: e.target.value })}/>
            <div className="ai-config-help">Each user can spend up to this amount before being blocked. Sonnet 4.5 ≈ $0.003-0.01 per typical request, so $0.15 ≈ 15-50 calls.</div>
          </div>

          <div className="ai-config-row">
            <div className="ai-config-label">API key override</div>
            <input className="settings-input" type="password" placeholder="(uses env var ANTHROPIC_API_KEY)"
              value={draft.api_key_override}
              onChange={e => setDraft({ ...draft, api_key_override: e.target.value })}/>
            <div className="ai-config-help">Optional. If set, proxy uses this key instead of the env var. Useful for rotating keys without redeploying.</div>
          </div>

          <div className="ai-config-row">
            <div className="ai-config-label">Notes</div>
            <textarea className="settings-input bio-text" rows="2"
              value={draft.notes}
              onChange={e => setDraft({ ...draft, notes: e.target.value })}/>
          </div>

          <div>
            <button className="ask-btn" onClick={save} disabled={saving}>
              {saving ? 'Saving…' : 'Save config →'}
            </button>
            {cfg?.updated_at && <span className="muted" style={{ marginLeft: 12, fontSize: 11 }}>Last saved {new Date(cfg.updated_at).toLocaleString()}</span>}
          </div>
        </div>
      </div>

      <div className="loc-kicker" style={{ marginTop: 28, marginBottom: 8 }}>USER USAGE · TOP SPENDERS</div>
      <table className="admin-table">
        <thead>
          <tr><th>User</th><th>Spent</th><th>% of cap</th><th>Calls</th><th>Tokens (in / out)</th><th>Last call</th><th></th></tr>
        </thead>
        <tbody>
          {usage.length === 0 && <tr><td colSpan="7" className="muted">No AI usage yet.</td></tr>}
          {usage.map(u => {
            const user = users[u.user_id];
            const pct = cap > 0 ? Math.min(100, (parseFloat(u.total_cost_usd) / cap) * 100) : 0;
            const overCap = parseFloat(u.total_cost_usd) >= cap && cap > 0;
            return (
              <tr key={u.user_id}>
                <td>{user ? <><b>{user.name}</b> <span className="dim">{user.email}</span></> : <span className="dim mono-small">{u.user_id.slice(0, 8)}…</span>}</td>
                <td className={overCap ? 'overcap' : ''}>${parseFloat(u.total_cost_usd).toFixed(4)}</td>
                <td>
                  <div className="ai-usage-bar">
                    <div className="ai-usage-bar-fill" style={{ width: `${pct}%`, background: overCap ? '#d99a8c' : pct > 70 ? '#e5c07b' : '#9bbf8c' }}/>
                  </div>
                  <span className="mono-small">{pct.toFixed(0)}%</span>
                </td>
                <td>{u.request_count}</td>
                <td className="muted mono-small">{(u.total_input_tokens || 0).toLocaleString()} / {(u.total_output_tokens || 0).toLocaleString()}</td>
                <td className="muted">{u.last_request_at ? new Date(u.last_request_at).toLocaleDateString() : '—'}</td>
                <td><button className="loc-tag-btn" onClick={() => resetUser(u.user_id)}>reset</button></td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function AdminAnalytics() {
  const store = useStore();
  const users = store.getAllUsers();
  const all = store.getAllPlaybooks();
  const totalSnips = all.reduce((a, p) => a + p.snips.length, 0);
  const totalDests = all.reduce((a, p) => a + p.destinations.length, 0);
  const fb = store.getFeedback();
  const openBugs = fb.filter(f => f.kind === 'bug' && f.status === 'open').length;
  const affilCount = Object.keys(window.affiliateIds.get()).length;
  const affilTotal = window.allAffiliateConfigs().length;

  return (
    <div className="admin-analytics">
      <div className="kpi-grid">
        <Kpi label="Users" value={users.length}/>
        <Kpi label="Playbooks" value={all.length}/>
        <Kpi label="Snips" value={totalSnips}/>
        <Kpi label="Destinations" value={totalDests}/>
        <Kpi label="Open bugs" value={openBugs} accent="#d99a8c"/>
        <Kpi label="Feature reqs" value={fb.filter(f => f.kind === 'feature').length} accent="#7fb6d9"/>
        <Kpi label="Affiliate IDs" value={`${affilCount}/${affilTotal}`} accent="#9bbf8c"/>
      </div>
    </div>
  );
}

function Kpi({ label, value, accent }) {
  return (
    <div className="kpi-card" style={accent ? { borderColor: accent } : {}}>
      <div className="kpi-value" style={accent ? { color: accent } : {}}>{value}</div>
      <div className="kpi-label">{label}</div>
    </div>
  );
}

window.AdminPage = AdminPage;
