// Page 1: 總覽 — KPIs, 異常橫條, 堆疊面積圖, Top brands 排行

function gotoBrand(b) {
  if (b && b.id) window.location.hash = '#/brands/' + encodeURIComponent(b.id);
}

function PageOverview({ filters, density, chartStyle }) {
  const { BRANDS, DAILY_AGG, TODAY, DAYS } = window.MOCK;
  // 真實 KPI 直接拿後端聚合結果，不要在前端用 BRANDS.dailyCost 推算
  // （cost-trend 只回 top5 + 'other'，對其他品牌都是 0，會失真）
  const live = (window.LIVE && window.LIVE.kpis) || {};

  const todayCost = (DAILY_AGG[DAYS - 1] && DAILY_AGG[DAYS - 1].total) || 0;
  const yesterdayCost = (DAILY_AGG[DAYS - 2] && DAILY_AGG[DAYS - 2].total) || 0;
  const todayConvos = BRANDS.reduce((s, b) => s + (b.dailyConvos[DAYS - 1] || 0), 0);
  const yesterdayConvos = BRANDS.reduce((s, b) => s + (b.dailyConvos[DAYS - 2] || 0), 0);

  const periodCost = +(live.total_cost_usd || 0);
  const periodConvos = +(live.total_convos || 0);
  const activeBrandIds = +(live.active_brands || BRANDS.length);
  const totalTokens = +(live.total_tokens || 0);
  const avgCostPerConvo = +(live.avg_cost_per_convo || 0);
  const avgCacheHit = +(live.cache_hit_rate || 0);
  const deltaCost = +(live.delta_total_cost_usd || 0);
  const deltaConvos = +(live.delta_total_convos || 0);
  const deltaActive = +(live.delta_active_brands || 0);
  const deltaTokens = +(live.delta_total_tokens || 0);
  const deltaAvgCost = +(live.delta_avg_cost_per_convo || 0);

  const totalSpark = DAILY_AGG.map(d => d.total);
  const anomalous = BRANDS.filter(b => b.isAnomalous).sort((a, b) => b.anomalyRatio - a.anomalyRatio);

  const topBrands = [...BRANDS].sort((a, b) => b.totalCost - a.totalCost);
  const top5 = topBrands.slice(0, 5);
  const otherBrands = topBrands.slice(5);
  const stackSeries = top5.map((b) => ({
    key: b.id,
    name: b.name.split(' ')[0],
    values: b.dailyCost,
  })).concat([{
    key: 'other', name: '其他',
    values: DAILY_AGG.map((d, i) => otherBrands.reduce((s, b) => s + b.dailyCost[i], 0)),
  }]);

  return (
    <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 14 }}>
      <PageHeader title="總覽" subtitle="3 秒內回答：現在有沒有東西燒起來" />

      {anomalous.length > 0 && <AnomalyBanner anomalous={anomalous} onPick={gotoBrand} />}

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 10 }}>
        <KPICard label="總費用 (USD)" value={fmtUSD(periodCost, periodCost < 10 ? 2 : 0)} delta={deltaCost} spark={totalSpark} sparkColor="#B45309" />
        <KPICard label="對話總數" value={fmtCompact(periodConvos)} delta={deltaConvos} spark={DAILY_AGG.map(d => Object.values(d.perBrand).length)} sparkColor="#1D4ED8" inverse />
        <KPICard label="活躍品牌" value={activeBrandIds + (BRANDS.length ? '/' + BRANDS.length : '')} delta={deltaActive} spark={null} sparkColor="#6D28D9" inverse />
        <KPICard label="Token 總量" value={fmtCompact(totalTokens)} delta={deltaTokens} spark={DAILY_AGG.map(d => d.total * 220000)} sparkColor="#0891B2" inverse />
        <KPICard label="平均每場費用" value={fmtUSD(avgCostPerConvo, 3)} delta={deltaAvgCost} spark={DAILY_AGG.map((d, i) => d.total / Math.max(1, BRANDS.reduce((s, b) => s + (b.dailyConvos[i] || 0), 0)))} sparkColor="#DB2777" inverseDelta />
        <KPICard label="Cache 命中率" value={fmtPct(avgCacheHit)} delta={0} spark={null} sparkColor="#15803D" inverseDelta />
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 320px', gap: 10 }}>
        <Card>
          <CardHeader title="每日費用趨勢" subtitle={`近 ${DAYS} 天 · 依品牌堆疊`}
            right={<>
              <ScaleToggle />
              <span style={{ fontFamily: 'JetBrains Mono', fontSize: 11, color: '#7A6E00', fontWeight: 600 }}>{fmtUSD(periodCost, 0)}</span>
            </>}
          />
          <div style={{ padding: '4px 12px 12px' }}>
            <ResponsiveBox height={240}>
              {(w, h) => (
                <StackedArea
                  series={stackSeries}
                  dates={DAILY_AGG.map(d => d.date)}
                  colors={['#B45309', '#1D4ED8', '#6D28D9', '#15803D', '#DB2777', '#9098A3']}
                  w={w} h={h}
                />
              )}
            </ResponsiveBox>
            <Legend items={stackSeries.map((s, i) => ({
              label: s.name,
              color: ['#B45309', '#1D4ED8', '#6D28D9', '#15803D', '#DB2777', '#9098A3'][i],
              value: fmtUSD(s.values.reduce((a, b) => a + b, 0), 0),
            }))} />
          </div>
        </Card>

        <Card>
          <CardHeader title="今日燒錢狀況" subtitle="2026-05-07 · UTC+8" />
          <div style={{ padding: '12px 16px', display: 'flex', flexDirection: 'column', gap: 14 }}>
            <BigStat label="今日總費用" value={fmtUSD(todayCost, 2)} delta={yesterdayCost > 0 ? (todayCost - yesterdayCost) / yesterdayCost : 0} />
            <BigStat label="今日對話數" value={fmtNum(todayConvos)} delta={yesterdayConvos > 0 ? (todayConvos - yesterdayConvos) / yesterdayConvos : 0} inverseDelta />
            <BigStat label="今日活躍品牌" value={BRANDS.filter(b => (b.dailyCost[DAYS - 1] || 0) > 0.001).length} delta={0} inverseDelta />
            <div style={{ borderTop: '1px solid #EEEEE9', paddingTop: 12 }}>
              <div style={{ fontSize: 10, color: '#9098A3', textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: 8, fontFamily: 'JetBrains Mono' }}>逐時消耗</div>
              <HourlyBars />
            </div>
          </div>
        </Card>
      </div>

      <Card>
        <CardHeader title="費用排行 Top Brands" subtitle="期間總計 · 點擊列進入詳細"
          right={<button onClick={() => { window.location.hash = '#/brands'; }} style={{ fontSize: 11, color: '#5C6470', padding: '4px 8px', border: '1px solid #E5E5E0', borderRadius: 4 }}>顯示全部 {BRANDS.length} 個 →</button>} />
        <BrandsTable brands={topBrands.slice(0, 12)} density={density} compact onRowClick={gotoBrand} />
      </Card>
    </div>
  );
}

function PageHeader({ title, subtitle }) {
  return (
    <div style={{ display: 'flex', alignItems: 'baseline', gap: 12, marginBottom: 2 }}>
      <h1 style={{ fontSize: 18, fontWeight: 600, color: '#17171A', letterSpacing: '-0.01em' }}>{title}</h1>
      {subtitle && <span style={{ fontSize: 12, color: '#9098A3' }}>{subtitle}</span>}
    </div>
  );
}

function Card({ children, style }) {
  return (
    <div style={{
      background: '#FFFFFF',
      border: '1px solid #E5E5E0',
      borderRadius: 6,
      ...style,
    }}>{children}</div>
  );
}

function CardHeader({ title, subtitle, right }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
      padding: '10px 14px', borderBottom: '1px solid #EEEEE9',
    }}>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 10 }}>
        <span style={{ fontSize: 12.5, fontWeight: 600, color: '#17171A' }}>{title}</span>
        {subtitle && <span style={{ fontSize: 11, color: '#9098A3' }}>{subtitle}</span>}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>{right}</div>
    </div>
  );
}

function KPICard({ label, value, delta, spark, sparkColor, inverse, inverseDelta }) {
  const isGood = inverseDelta ? delta < 0 : delta > 0;
  const deltaColor = delta === 0 ? '#9098A3' : isGood ? '#15803D' : '#DC2626';
  const arrow = delta > 0 ? '↑' : delta < 0 ? '↓' : '·';
  return (
    <div style={{
      background: '#FFFFFF', border: '1px solid #E5E5E0', borderRadius: 6,
      padding: '11px 13px',
    }}>
      <div style={{ fontSize: 10, color: '#9098A3', textTransform: 'uppercase', letterSpacing: '0.08em', fontFamily: 'JetBrains Mono', fontWeight: 500 }}>{label}</div>
      <div style={{ fontSize: 22, fontWeight: 600, color: '#17171A', fontFamily: 'JetBrains Mono', marginTop: 4, letterSpacing: '-0.02em' }}>{value}</div>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 6 }}>
        <span style={{ fontSize: 10.5, color: deltaColor, fontFamily: 'JetBrains Mono' }}>
          {arrow} {fmtDelta(Math.abs(delta))} <span style={{ color: '#9098A3' }}>vs 上期</span>
        </span>
        {spark && <Sparkline data={spark} w={56} h={18} color={sparkColor} fill />}
      </div>
    </div>
  );
}

function BigStat({ label, value, delta, inverseDelta }) {
  const isGood = inverseDelta ? delta < 0 : delta > 0;
  const deltaColor = isGood ? '#15803D' : '#DC2626';
  return (
    <div>
      <div style={{ fontSize: 10, color: '#9098A3', textTransform: 'uppercase', letterSpacing: '0.08em', fontFamily: 'JetBrains Mono' }}>{label}</div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 2 }}>
        <span style={{ fontSize: 22, fontWeight: 600, color: '#17171A', fontFamily: 'JetBrains Mono', letterSpacing: '-0.02em' }}>{value}</span>
        <span style={{ fontSize: 11, color: deltaColor, fontFamily: 'JetBrains Mono' }}>{fmtDelta(delta)}</span>
      </div>
    </div>
  );
}

function HourlyBars() {
  const [hours, setHours] = React.useState(null);  // null = loading
  React.useEffect(() => {
    let alive = true;
    window.AdminAPI.overview.hourly()
      .then((data) => { if (alive) setHours((data && data.hours) || []); })
      .catch(() => { if (alive) setHours([]); });
    return () => { alive = false; };
  }, []);

  if (hours == null) {
    return <div style={{ height: 50, display: 'grid', placeItems: 'center', fontSize: 10, color: '#9098A3' }}>載入中…</div>;
  }
  const costs = hours.map(h => h.cost_usd || 0);
  const max = Math.max(0.0001, ...costs);
  const nowHour = new Date().getUTCHours();  // 後端用 UTC，前端 bar 也按 UTC 標當前小時
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 2, height: 50 }}>
      {hours.map((h, i) => {
        const ratio = h.cost_usd ? Math.max(0.05, h.cost_usd / max) : 0;
        return (
          <div key={i} style={{
            flex: 1,
            height: ratio > 0 ? `${ratio * 100}%` : '2px',
            background: i === nowHour ? '#FFE600' : i < nowHour ? '#5C6470' : '#E5E5E0',
            opacity: h.cost_usd === 0 ? 0.35 : 1,
            borderRadius: 1,
          }} title={`${String(i).padStart(2, '0')}:00 UTC · ${fmtUSD(h.cost_usd, 4)} · ${h.convos} 場`}></div>
        );
      })}
    </div>
  );
}

function Legend({ items }) {
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 14, marginTop: 8, paddingTop: 8, borderTop: '1px solid #EEEEE9' }}>
      {items.map((it, i) => (
        <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 11 }}>
          <span style={{ width: 8, height: 8, background: it.color, borderRadius: 2 }}></span>
          <span style={{ color: '#5C6470' }}>{it.label}</span>
          <span style={{ color: '#17171A', fontFamily: 'JetBrains Mono' }}>{it.value}</span>
        </div>
      ))}
    </div>
  );
}

function ScaleToggle() {
  const [scale, setScale] = React.useState('linear');
  const opts = [{ id: 'linear', label: '線性' }, { id: 'log', label: '對數' }];
  return (
    <div style={{ display: 'flex', background: '#F7F7F5', border: '1px solid #E5E5E0', borderRadius: 4, overflow: 'hidden' }}>
      {opts.map(s => (
        <button key={s.id} onClick={() => setScale(s.id)}
          style={{
            padding: '3px 8px', fontSize: 10.5,
            color: scale === s.id ? '#7A6E00' : '#9098A3',
            background: scale === s.id ? '#FFFAB8' : 'transparent',
          }}>{s.label}</button>
      ))}
    </div>
  );
}

function AnomalyBanner({ anomalous, onPick }) {
  const top = anomalous[0];
  return (
    <div style={{
      background: '#FEF3C7',
      border: '1px solid #FCD34D',
      borderLeft: '3px solid #B45309',
      borderRadius: 5,
      padding: '10px 14px',
      display: 'flex', alignItems: 'center', gap: 12,
      fontSize: 12,
    }}>
      <Icon d="M12 9v4M12 17h.01M5 19h14a2 2 0 0 0 1.7-3L13.7 4a2 2 0 0 0-3.4 0L3.3 16A2 2 0 0 0 5 19z" size={16} stroke="#B45309" />
      <div style={{ flex: 1, color: '#17171A' }}>
        <span style={{ color: '#B45309', fontWeight: 600 }}>{anomalous.length} 個品牌今日費用超過 7 日均的 3 倍：</span>{' '}
        {anomalous.slice(0, 3).map((b, i) => (
          <span key={b.id}>
            <button onClick={() => onPick && onPick(b)}
              style={{ color: '#17171A', fontWeight: 500, padding: 0, textDecoration: 'underline', textUnderlineOffset: 2, cursor: 'pointer' }}
            >{b.name}</button>{' '}
            <span style={{ fontFamily: 'JetBrains Mono', color: '#B45309' }}>{fmtUSD(b.todayCost, 0)} ({b.anomalyRatio}×)</span>
            {i < Math.min(2, anomalous.length - 1) ? '、' : ''}
          </span>
        ))}
        {anomalous.length > 3 && <span style={{ color: '#9098A3' }}> 還有 {anomalous.length - 3} 個</span>}
      </div>
      <button onClick={() => onPick && top && onPick(top)} style={{
        padding: '5px 12px', fontSize: 11.5, fontWeight: 600,
        background: '#B45309', color: '#FFFFFF', borderRadius: 4,
      }}>立即調查 →</button>
    </div>
  );
}

function BrandsTable({ brands, density, compact, onRowClick }) {
  const rowH = density === 'comfy' ? 38 : 32;
  const cellPad = density === 'comfy' ? '8px 12px' : '6px 12px';
  return (
    <div style={{ overflow: 'auto' }} className="scroll">
      <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
        <thead>
          <tr style={{ background: '#FAFAF9', borderBottom: '1px solid #E5E5E0' }}>
            <Th style={{ width: 40, textAlign: 'right' }}>排名</Th>
            <Th>品牌</Th>
            <Th style={{ width: 80 }}>方案</Th>
            <Th style={{ width: 90, textAlign: 'right' }}>對話數</Th>
            <Th style={{ width: 100, textAlign: 'right' }}>Token</Th>
            <Th style={{ width: 110, textAlign: 'right' }}>費用</Th>
            <Th style={{ width: 100, textAlign: 'right' }}>平均/場</Th>
            <Th style={{ width: 110 }}>14 天趨勢</Th>
            <Th style={{ width: 90 }}>狀態</Th>
          </tr>
        </thead>
        <tbody>
          {brands.map((b, i) => (
            <tr key={b.id} onClick={() => onRowClick && onRowClick(b)}
              style={{
                borderBottom: '1px solid #EEEEE9',
                background: i % 2 ? '#FAFAF9' : '#FFFFFF',
                cursor: onRowClick ? 'pointer' : 'default',
                height: rowH,
              }}
              onMouseEnter={(e) => e.currentTarget.style.background = '#FFFAB8'}
              onMouseLeave={(e) => e.currentTarget.style.background = i % 2 ? '#FAFAF9' : '#FFFFFF'}
            >
              <td style={{ padding: cellPad, color: '#9098A3', fontFamily: 'JetBrains Mono', textAlign: 'right' }}>{i + 1}</td>
              <td style={{ padding: cellPad }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <BrandThumb id={b.id} />
                  <div style={{ minWidth: 0 }}>
                    <div style={{ color: '#17171A', fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: 220 }}>{b.name}</div>
                    {!compact && <div style={{ fontSize: 10, color: '#9098A3', fontFamily: 'JetBrains Mono' }}>{b.id}</div>}
                  </div>
                </div>
              </td>
              <td style={{ padding: cellPad }}><TierBadge tier={b.tier} /></td>
              <td style={{ padding: cellPad, textAlign: 'right', fontFamily: 'JetBrains Mono', color: '#17171A' }}>{fmtNum(b.totalConvos)}</td>
              <td style={{ padding: cellPad, textAlign: 'right', fontFamily: 'JetBrains Mono', color: '#5C6470' }}>{fmtCompact(b.tokens)}</td>
              <td style={{ padding: cellPad, textAlign: 'right', fontFamily: 'JetBrains Mono', color: '#17171A', fontWeight: 600 }}>{fmtUSD(b.totalCost, 2)}</td>
              <td style={{ padding: cellPad, textAlign: 'right', fontFamily: 'JetBrains Mono', color: '#5C6470' }}>{fmtUSD(b.avgCostPerConvo, 3)}</td>
              <td style={{ padding: cellPad }}>
                <Sparkline data={b.dailyCost.slice(-14)} w={90} h={18} color={b.isAnomalous ? '#DC2626' : '#1D4ED8'} fill />
              </td>
              <td style={{ padding: cellPad }}><StatusDot status={b.status} /></td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function Th({ children, style }) {
  return <th style={{
    padding: '7px 12px', textAlign: 'left',
    fontSize: 10, color: '#9098A3', fontWeight: 500,
    textTransform: 'uppercase', letterSpacing: '0.08em',
    fontFamily: 'JetBrains Mono',
    ...style,
  }}>{children}</th>;
}

function BrandThumb({ id }) {
  const hash = id.split('').reduce((a, c) => a + c.charCodeAt(0), 0);
  const hue = (hash * 47) % 360;
  return (
    <div style={{
      width: 22, height: 22, borderRadius: 4,
      background: `oklch(0.65 0.10 ${hue})`,
      flexShrink: 0,
      display: 'grid', placeItems: 'center',
      fontSize: 10, fontWeight: 700, color: '#fff',
      fontFamily: 'JetBrains Mono',
    }}>{id.slice(0, 2).toUpperCase()}</div>
  );
}

window.PageOverview = PageOverview;
window.PageHeader = PageHeader;
window.Card = Card;
window.CardHeader = CardHeader;
window.KPICard = KPICard;
window.BrandsTable = BrandsTable;
window.BrandThumb = BrandThumb;
window.Th = Th;
