// screens-dashboard.jsx — Platform Overview / Dashboard

const API_BASE = window.NebulaAdmin.API_BASE();
const getAuthHeaders = window.NebulaAdmin.authHeaders;

// Generates deterministic-looking series
function series(seed, n = 24, base = 50, amp = 30) {
  const out = [];
  let v = base;
  for (let i = 0; i < n; i++) {
    seed = (seed * 9301 + 49297) % 233280;
    const r = (seed / 233280) - 0.5;
    v = base + Math.sin(i / 3.4 + seed * 0.001) * amp + r * amp * 0.6;
    out.push(Math.max(0, v));
  }
  return out;
}

// Small green dot indicator for live data
const LiveDot = () => (
  <span style={{ display: 'inline-block', width: 6, height: 6, borderRadius: '50%', background: 'var(--success)', marginLeft: 6 }} />
);

function DashboardScreen({ t, push }) {
  const [kpis, setKpis] = React.useState(null);

  React.useEffect(() => {
    let stopped = false;
    const load = async () => {
      try {
        const res = await fetch(`${API_BASE}/api/dashboard`, { headers: getAuthHeaders() });
        if (!res.ok) throw new Error('http ' + res.status);
        const data = await res.json();
        if (!stopped) setKpis(data);
      } catch (e) {
        if (!stopped) console.warn('[dashboard] fetch failed', e);
      }
    };
    load();
    const timer = setInterval(load, 5000);
    return () => { stopped = true; clearInterval(timer); };
  }, []);

  const fmtMoney = (v) => {
    if (v == null || isNaN(v)) return null;
    try { return '¥' + Number(v).toLocaleString('zh-CN', { maximumFractionDigits: 2 }); }
    catch (e) { return '¥' + v; }
  };
  const fmtCount = (v) => {
    if (v == null || isNaN(v)) return null;
    try { return Number(v).toLocaleString('zh-CN'); }
    catch (e) { return String(v); }
  };

  const kpiStake   = kpis ? fmtMoney(kpis.today_stake)   : '¥4,820,103';
  const kpiPayout  = kpis ? fmtMoney(kpis.today_payout)  : '¥3,124,902';
  const kpiProfit  = kpis ? fmtMoney(kpis.today_profit)  : '¥1,242,030';
  const kpiUsers   = kpis ? fmtCount(kpis.users_total)   : '38,201';
  const kpiWallets = kpis ? fmtMoney(kpis.wallets_total) : '¥2,491';
  const profitUp = kpis ? Number(kpis.today_profit) >= 0 : true;

  return (
    <div className="stack">
      <div className="page-h">
        <div>
          <h1>{t.p_dashboard}</h1>
          <div className="sub">{t.real_time} · {t.tx('跨 6 个租户 · 12 个站点 · 943,180 名用户', 'Across 6 tenants · 12 sites · 943,180 users')}</div>
        </div>
        <div className="actions">
          <button className="chip"><Icons.globe /> {t.tx('全部租户', 'All tenants')}</button>
          <button className="chip active">{t.today}</button>
          <button className="btn btn-sm" onClick={() => push(t.tx('已导出当前视图', 'Current view exported'))}>
            <Icons.download /> {t.export}
          </button>
          <button className="btn btn-pri btn-sm" onClick={() => push(t.tx('全局开关已切换', 'Global switch toggled'))}>
            <Icons.bolt /> {t.tx('全局开关', 'Global switch')}
          </button>
        </div>
      </div>

      {/* Top KPIs */}
      <div className="row-5">
        <KPI label={t.tx('今日投注', "Today's stake")} value={kpiStake} delta="+12.4%" up live={!!kpis} t={t}
             spark={<Sparkline data={series(7, 24, 50, 30)} w={120} h={32} />} />
        <KPI label={t.tx('今日派彩', "Today's payout")} value={kpiPayout} delta="+8.1%" up live={!!kpis} t={t}
             spark={<Sparkline data={series(17, 24, 60, 25)} w={120} h={32} stroke="oklch(0.65 0.15 30)" />} />
        <KPI label={t.tx('净盈亏', 'Net profit')} value={kpiProfit} delta={profitUp ? '+3.2%' : '-3.2%'} up={profitUp} live={!!kpis} t={t}
             spark={<Sparkline data={series(29, 24, 40, 22)} w={120} h={32} stroke="oklch(0.6 0.16 145)" />} />
        <KPI label={t.tx('用户总数', 'Total users')} value={kpiUsers} delta="+24.0%" up live={!!kpis} t={t}
             spark={<Sparkline data={series(43, 24, 45, 28)} w={120} h={32} stroke="oklch(0.62 0.14 230)" />} />
        <KPI label={t.tx('钱包总余额', 'Total wallet balance')} value={kpiWallets} delta="+5.0%" up live={!!kpis} t={t}
             spark={<Sparkline data={series(53, 24, 30, 30)} w={120} h={32} stroke="oklch(0.6 0.18 305)" />} />
      </div>

      {/* Row 2: revenue chart + tenant health */}
      <div style={{ display: 'grid', gridTemplateColumns: '1.7fr 1fr', gap: 16 }}>
        <RevenueChart t={t} />
        <TenantHealthCard t={t} />
      </div>

      {/* Row 3: pending queue + risk + module split */}
      <div style={{ display: 'grid', gridTemplateColumns: '1.3fr 1fr 1fr', gap: 16 }}>
        <PendingQueueCard t={t} push={push} />
        <RiskFeed t={t} />
        <RevenueBreakdown t={t} />
      </div>

      {/* Row 4: top sites + channel quality */}
      <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 16 }}>
        <TopSitesCard t={t} />
        <PaymentMixCard t={t} />
      </div>
    </div>
  );
}

function KPI({ label, value, delta, up, spark, live, t }) {
  return (
    <div className="stat">
      <div className="lbl">{label}{live ? <LiveDot /> : null}</div>
      <div className="num">{value}</div>
      <div className="delta" style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
        <span className={up ? 'delta up' : 'delta dn'}>
          {up ? <Icons.arrowUp /> : <Icons.arrowDn />}{delta}
        </span>
        <span className="ago" style={{ color: 'var(--text-faint)' }}>{(t && t.tx ? t.tx : ((zh) => zh))('vs 昨日', 'vs yesterday')}</span>
      </div>
      <div className="spark">{spark}</div>
    </div>
  );
}

function RevenueChart({ t }) {
  const [mode, setMode] = React.useState('day');
  const dataLines = [
    { name: t.tx('充值', 'Deposit'), color: 'oklch(0.55 0.18 264)', data: series(11, 30, 60, 25) },
    { name: t.tx('提现', 'Withdraw'), color: 'oklch(0.65 0.14 30)',  data: series(23, 30, 40, 18) },
    { name: t.tx('投注', 'Stake'), color: 'oklch(0.6 0.13 152)',  data: series(31, 30, 50, 22) },
  ];
  const w = 600, h = 220, pad = 32;
  const max = Math.max(...dataLines.flatMap(l => l.data)) * 1.1;
  const px = (i) => pad + (i / 29) * (w - pad * 1.3);
  const py = (v) => h - pad - (v / max) * (h - pad * 1.5);

  return (
    <div className="card">
      <div className="card-h">
        <h3>{t.tx('充值 · 提现 · 投注 趋势', 'Deposit · Withdraw · Stake trend')}</h3>
        <div style={{ display: 'flex', gap: 4 }}>
          {['day','week','month'].map(m => (
            <button key={m} className={`chip ${mode === m ? 'active' : ''}`}
                    onClick={() => setMode(m)} style={{ minWidth: 36 }}>
              {m === 'day' ? t.tx('日', 'D') : m === 'week' ? t.tx('周', 'W') : t.tx('月', 'M')}
            </button>
          ))}
        </div>
      </div>
      <div className="card-body" style={{ padding: '8px 8px 12px' }}>
        <svg viewBox={`0 0 ${w} ${h}`} style={{ width: '100%', height: 220 }}>
          {[0, 0.25, 0.5, 0.75, 1].map((p, i) => {
            const y = pad + p * (h - pad * 1.5);
            return (
              <g key={i}>
                <line x1={pad} y1={y} x2={w - pad * 0.3} y2={y} stroke="var(--border)" strokeDasharray={i === 4 ? '0' : '2 3'} />
                <text x={pad - 6} y={y + 3} textAnchor="end" fontSize="9" fill="var(--text-faint)" fontFamily="var(--font-mono)">
                  {Math.round(max * (1 - p)).toString()}
                </text>
              </g>
            );
          })}
          {dataLines.map((l, li) => {
            const linePath = l.data.map((v, i) => `${i === 0 ? 'M' : 'L'}${px(i)},${py(v)}`).join(' ');
            const areaPath = `${linePath} L${px(29)},${h - pad} L${px(0)},${h - pad} Z`;
            return (
              <g key={li}>
                <path d={areaPath} fill={l.color} opacity="0.06" />
                <path d={linePath} fill="none" stroke={l.color} strokeWidth="1.5" strokeLinejoin="round" />
                {l.data.map((v, i) => i % 5 === 0 && (
                  <circle key={i} cx={px(i)} cy={py(v)} r="2" fill="white" stroke={l.color} strokeWidth="1.2" />
                ))}
              </g>
            );
          })}
          {/* x-axis labels */}
          {[0, 6, 12, 18, 24, 29].map((i) => (
            <text key={i} x={px(i)} y={h - pad + 16} textAnchor="middle" fontSize="9" fill="var(--text-faint)" fontFamily="var(--font-mono)">
              {t.tx(`${i + 1}日`, `D${i + 1}`)}
            </text>
          ))}
        </svg>
        <div style={{ display: 'flex', gap: 16, padding: '0 8px', fontSize: 11.5, color: 'var(--text-muted)' }}>
          {[t.tx('充值','Deposit'), t.tx('提现','Withdraw'), t.tx('投注','Stake')].map((n, i) => (
            <div key={n} style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
              <span style={{ width: 8, height: 8, borderRadius: 2, background: dataLines[i].color }} />
              {n}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function TenantHealthCard({ t }) {
  return (
    <div className="card">
      <div className="card-h">
        <h3>{t.tx('租户健康度', 'Tenant health')}</h3>
        <span className="meta">{t.tx('6 个租户', '6 tenants')}</span>
      </div>
      <div style={{ padding: '4px 0' }}>
        {DATA.tenants.map((tn) => (
          <div key={tn.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 16px', borderBottom: '1px solid var(--border)' }}>
            <div style={{ flex: '0 0 auto' }}>
              <Avatar name={tn.name} size={26} />
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 2 }}>
                <span style={{ fontSize: 12.5, fontWeight: 500 }}>{tn.name}</span>
                <span className="text-mono text-faint" style={{ fontSize: 10 }}>{tn.id}</span>
              </div>
              <div style={{ display: 'flex', gap: 10, fontSize: 11, color: 'var(--text-muted)' }}>
                <span>{tn.sites} {t.tx('站点', 'sites')}</span>
                <span>{fmtNum(tn.users)} {t.tx('用户', 'users')}</span>
                <span style={{ color: 'var(--text-faint)' }}>{t.tx('到期', 'Exp')} {tn.expires}</span>
              </div>
            </div>
            <StatusBadge status={tn.status} t={t} />
          </div>
        ))}
      </div>
    </div>
  );
}

function PendingQueueCard({ t, push }) {
  return (
    <div className="card">
      <div className="card-h">
        <h3>{t.tx('实时待办 · 24 项', 'Pending · 24 items')}</h3>
        <a className="text-muted" style={{ fontSize: 11.5 }}>{t.tx('查看全部', 'View all')} →</a>
      </div>
      <div className="tbl-scroll">
      <table className="tbl tbl-stack">
        <thead><tr>
          <th>{t.tx('类型', 'Type')}</th><th>{t.tx('对象', 'Target')}</th><th className="right">{t.tx('金额', 'Amount')}</th><th>{t.tx('风险', 'Risk')}</th><th>{t.tx('时间', 'Time')}</th><th></th>
        </tr></thead>
        <tbody>
          {DATA.approvals.slice(0, 6).map((a) => {
            const typeMap = {
              withdraw: [t.tx('提现','Withdraw'),'warning'],
              adjust:   [t.tx('调账','Adjust'),'outline'],
              bonus:    [t.tx('活动','Bonus'),'accent'],
              patch:    [t.tx('补单','Patch'),'info'],
              export:   [t.tx('导出','Export'),'outline'],
              sensitive:[t.tx('敏感','Sensitive'),'purple'],
            };
            const [label, cls] = typeMap[a.type] || ['—',''];
            return (
              <tr key={a.id}>
                <td data-label={t.tx('类型', 'Type')}><span className={`badge ${cls}`}>{label}</span></td>
                <td data-label={t.tx('对象', 'Target')}><span style={{ fontWeight: 500 }}>{a.who}</span><div className="text-faint" style={{ fontSize: 10, fontFamily: 'var(--font-mono)' }}>{a.id}</div></td>
                <td data-label={t.tx('金额', 'Amount')} className="right">{a.amount === 0 ? '—' : fmtCN(Math.abs(a.amount))}</td>
                <td data-label={t.tx('风险', 'Risk')}><RiskDot score={a.risk} /></td>
                <td data-label={t.tx('时间', 'Time')} className="muted">{a.age}</td>
                <td data-label={t.tx('操作', 'Actions')} className="tbl-actions">
                  <button className="btn btn-xs" onClick={() => push(`${a.id} ${t.tx('已通过', 'approved')}`)}>{t.approve}</button>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
      </div>
    </div>
  );
}

function RiskFeed({ t }) {
  return (
    <div className="card">
      <div className="card-h">
        <h3>{t.tx('风险告警', 'Risk alerts')}</h3>
        <span className="badge danger"><span className="dot" />{t.tx('6 高危', '6 high')}</span>
      </div>
      <div>
        {DATA.risks.slice(0, 6).map((r) => (
          <div key={r.id} style={{ padding: '10px 16px', borderBottom: '1px solid var(--border)', display: 'flex', gap: 10, alignItems: 'flex-start' }}>
            <div style={{ width: 28, height: 28, borderRadius: 6, background: r.sev === 'high' ? 'var(--danger-soft)' : 'var(--warning-soft)', color: r.sev === 'high' ? 'var(--danger)' : 'var(--warning)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
              <Icons.warn />
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 12.5, fontWeight: 500, marginBottom: 2 }}>{r.title}</div>
              <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>
                <span className="text-mono" style={{ color: 'var(--text-subtle)' }}>{r.who}</span> · {r.site} · {r.age}{t.tx('前', ' ago')}
              </div>
            </div>
            <div style={{ textAlign: 'right' }}>
              <div style={{ fontSize: 14, fontWeight: 600, color: r.sev === 'high' ? 'var(--danger)' : 'var(--warning)' }}>{r.score}</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function RevenueBreakdown({ t }) {
  const data = [
    { name: t.tx('直播打赏', 'Live tips'),       value: 42, color: 'oklch(0.55 0.18 264)' },
    { name: t.tx('游戏收入', 'Game revenue'),    value: 28, color: 'oklch(0.6 0.16 145)' },
    { name: t.tx('会员订阅', 'Subscriptions'),   value: 18, color: 'oklch(0.62 0.14 230)' },
    { name: t.tx('广告佣金', 'Ad commission'),   value: 12, color: 'oklch(0.65 0.14 30)' },
  ];
  return (
    <div className="card">
      <div className="card-h">
        <h3>{t.tx('收入构成', 'Revenue mix')}</h3>
        <span className="meta">{t.today}</span>
      </div>
      <div className="card-body" style={{ display: 'flex', alignItems: 'center', gap: 18 }}>
        <div style={{ position: 'relative' }}>
          <Donut data={data} size={112} thickness={16} />
          <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
            <div style={{ fontSize: 9, color: 'var(--text-faint)', textTransform: 'uppercase', letterSpacing: '.05em' }}>Total</div>
            <div style={{ fontSize: 16, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>¥1.24M</div>
          </div>
        </div>
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 7 }}>
          {data.map((d) => (
            <div key={d.name} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12 }}>
              <span style={{ width: 8, height: 8, borderRadius: 2, background: d.color }} />
              <span style={{ flex: 1 }}>{d.name}</span>
              <span className="tabular text-muted">{d.value}%</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function TopSitesCard({ t }) {
  const sites = [
    { name: '极光主站', tenant: 'T-A01', dep: 1240200, share: 38, users: 124902, online: 12400, trend: series(3, 14, 50, 20) },
    { name: 'Aurora Global', tenant: 'T-A01', dep: 820400, share: 25, users: 89230, online: 8200, trend: series(8, 14, 45, 18) },
    { name: 'Stellar HK',  tenant: 'T-B02', dep: 480200, share: 14, users: 56120, online: 4200, trend: series(12, 14, 38, 15) },
    { name: '银河直播 #1', tenant: 'T-E05', dep: 320400, share: 10, users: 42103, online: 8120, trend: series(19, 14, 42, 22) },
    { name: '红日直播间', tenant: 'T-C03', dep: 240100, share: 7, users: 32104, online: 2400, trend: series(27, 14, 28, 14) },
  ];
  return (
    <div className="card">
      <div className="card-h">
        <h3>{t.tx('Top 站点 · 充值', 'Top sites · Deposit')}</h3>
        <span className="meta">{t.today}</span>
      </div>
      <div className="tbl-scroll">
      <table className="tbl tbl-stack">
        <thead><tr>
          <th style={{ width: 28 }}>#</th><th>{t.tx('站点', 'Site')}</th><th className="right">{t.tx('充值', 'Deposit')}</th><th>{t.tx('占比', 'Share')}</th><th className="right">{t.tx('在线', 'Online')}</th><th>{t.tx('趋势', 'Trend')}</th>
        </tr></thead>
        <tbody>
          {sites.map((s, i) => (
            <tr key={s.name}>
              <td data-label="#" className="muted tabular">{i + 1}</td>
              <td data-label={t.tx('站点', 'Site')}>
                <div style={{ fontWeight: 500 }}>{s.name}</div>
                <div className="text-mono text-faint" style={{ fontSize: 10 }}>{s.tenant}</div>
              </td>
              <td data-label={t.tx('充值', 'Deposit')} className="right tabular">{fmtCN(s.dep)}</td>
              <td data-label={t.tx('占比', 'Share')}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                  <span className="barmini" style={{ width: 60 }}><i style={{ width: `${s.share * 2.6}%` }} /></span>
                  <span className="tabular muted">{s.share}%</span>
                </div>
              </td>
              <td data-label={t.tx('在线', 'Online')} className="right tabular">{fmtNum(s.online)}</td>
              <td data-label={t.tx('趋势', 'Trend')}><Sparkline data={s.trend} w={70} h={22} /></td>
            </tr>
          ))}
        </tbody>
      </table>
      </div>
    </div>
  );
}

function PaymentMixCard({ t }) {
  const ch = DATA.channels.slice(0, 5);
  return (
    <div className="card">
      <div className="card-h">
        <h3>{t.tx('支付通道质量', 'Payment channel quality')}</h3>
        <a className="text-muted" style={{ fontSize: 11.5 }}>{t.tx('路由配置', 'Routing config')} →</a>
      </div>
      <div style={{ padding: '6px 16px 14px' }}>
        {ch.map((c) => (
          <div key={c.id} style={{ padding: '10px 0', borderBottom: '1px solid var(--border)' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 5 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <span style={{ fontSize: 12.5, fontWeight: 500 }}>{c.name}</span>
                <span className="badge outline">{c.tier === 'vip' ? 'VIP' : 'ALL'}</span>
                <StatusBadge status={c.status} t={t} />
              </div>
              <span className="tabular text-muted" style={{ fontSize: 11 }}>{c.latency}</span>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span className="barmini" style={{ flex: 1, height: 5 }}>
                <i style={{ width: `${c.success}%`, background: c.success >= 97 ? 'var(--success)' : c.success >= 92 ? 'var(--warning)' : 'var(--danger)' }} />
              </span>
              <span className="tabular" style={{ fontSize: 12, fontWeight: 500, minWidth: 48, textAlign: 'right' }}>{c.success}%</span>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { DashboardScreen });
