// Page 2: 品牌列表 + drilldown + 方案散布圖

function PageBrands({ filters, density, drilldownId, setDrilldownId }) {
  const { BRANDS } = window.MOCK;

  if (drilldownId) {
    const brand = BRANDS.find(b => b.id === drilldownId);
    if (brand) return <BrandDrilldown brand={brand} onBack={() => setDrilldownId(null)} range={filters.range} />;
  }

  const sorted = [...BRANDS].sort((a, b) => b.totalCost - a.totalCost);

  return (
    <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 14 }}>
      <PageHeader title="品牌" subtitle={`共 ${BRANDS.length} 個品牌 · ${BRANDS.filter(b => b.status === 'active').length} 個使用中`} />

      <Card>
        <CardHeader title="方案 vs 月費用 散布圖" subtitle="超過方案上限的點為升級候選"
          right={<div style={{ display: 'flex', gap: 14, fontSize: 11 }}>
            <span style={{ display: 'flex', alignItems: 'center', gap: 6, color: '#5C6470' }}>
              <span style={{ width: 8, height: 8, background: '#1D4ED8', borderRadius: '50%' }}></span>方案內
            </span>
            <span style={{ display: 'flex', alignItems: 'center', gap: 6, color: '#5C6470' }}>
              <span style={{ width: 8, height: 8, background: '#DC2626', borderRadius: '50%' }}></span>超過上限
            </span>
          </div>} />
        <div style={{ padding: '12px 14px' }}>
          <ResponsiveBox height={320}>
            {(w, h) => <PlanTierScatter brands={BRANDS} onPick={setDrilldownId} w={w} h={h} />}
          </ResponsiveBox>
        </div>
      </Card>

      <Card>
        <CardHeader title="所有品牌" subtitle="點擊任一列查看詳細"
          right={<button style={{ fontSize: 11, color: '#5C6470', padding: '4px 8px', border: '1px solid #E5E5E0', borderRadius: 4 }}>匯出 CSV</button>} />
        <BrandsTable brands={sorted} density={density} onRowClick={(b) => setDrilldownId(b.id)} />
      </Card>
    </div>
  );
}

function PlanTierScatter({ brands, onPick, w = 920, h = 320 }) {
  const padL = 60, padR = 20, padT = 14, padB = 36;
  const tierOrder = ['trial', 'starter', 'growth', 'enterprise'];
  const tierLabel = { trial: '試用', starter: '入門版', growth: '成長版', enterprise: '企業版' };
  const tierX = { trial: 0.15, starter: 0.4, growth: 0.65, enterprise: 0.9 };
  const innerW = w - padL - padR;
  const innerH = h - padT - padB;

  const maxCost = Math.max(...brands.map(b => b.totalCost)) * 1.05;
  const yScale = (v) => padT + innerH - (v / maxCost) * innerH;

  const jittered = brands.map(b => {
    const hash = b.id.split('').reduce((a, c) => a + c.charCodeAt(0), 0);
    const jitter = ((hash * 31) % 100) / 100 * 0.18 - 0.09;
    return {
      ...b,
      x: padL + (tierX[b.tier] + jitter) * innerW,
      y: yScale(b.totalCost),
      r: Math.max(3.5, Math.min(14, Math.sqrt(b.totalConvos) * 0.45)),
      overCeiling: b.totalCost > b.plan_ceiling_usd,
    };
  });

  const ceilings = { trial: 100, starter: 400, growth: 1500, enterprise: 5000 };

  return (
    <svg width={w} height={h} style={{ display: 'block' }}>
      {[0, 0.25, 0.5, 0.75, 1].map(t => {
        const y = padT + innerH - t * innerH;
        return (
          <g key={t}>
            <line x1={padL} x2={w - padR} y1={y} y2={y} stroke="#EEEEE9" strokeDasharray="2 3" />
            <text x={padL - 8} y={y + 3} fontSize={10} fill="#9098A3" textAnchor="end" fontFamily="JetBrains Mono">${fmtCompact(maxCost * t)}</text>
          </g>
        );
      })}

      {tierOrder.map((t) => {
        const x = padL + tierX[t] * innerW;
        const ceilY = yScale(ceilings[t]);
        return (
          <g key={t}>
            <line x1={x - 80} x2={x + 80} y1={ceilY} y2={ceilY} stroke="#9098A3" strokeDasharray="3 3" strokeOpacity={0.6} />
            <text x={x + 80} y={ceilY - 3} fontSize={9} fill="#9098A3" fontFamily="JetBrains Mono" textAnchor="end">上限 ${ceilings[t]}</text>
            <text x={x} y={h - 12} fontSize={11} fill="#5C6470" textAnchor="middle" fontWeight={600}>{tierLabel[t]}</text>
            <text x={x} y={h - 0} fontSize={9} fill="#9098A3" textAnchor="middle" fontFamily="JetBrains Mono">{brands.filter(b => b.tier === t).length} 個品牌</text>
          </g>
        );
      })}

      {jittered.map(b => (
        <g key={b.id} style={{ cursor: 'pointer' }} onClick={() => onPick(b.id)}>
          <title>{`${b.name}（idx=${b.id}） · ${fmtUSD(b.totalCost, 2)} · ${b.totalConvos} 場`}</title>
          <circle cx={b.x} cy={b.y} r={b.r}
            fill={b.overCeiling ? '#DC2626' : '#1D4ED8'}
            fillOpacity={0.22}
            stroke={b.overCeiling ? '#DC2626' : '#1D4ED8'}
            strokeWidth={1.25} />
          {b.overCeiling && (
            <text x={b.x + b.r + 4} y={b.y + 3} fontSize={10} fill="#DC2626" fontFamily="Inter">{b.name.split(' ')[0]}</text>
          )}
        </g>
      ))}
    </svg>
  );
}

function BrandDrilldown({ brand, onBack, range }) {
  const [tab, setTab] = React.useState('activity');
  const [summary, setSummary] = React.useState(null);  // { total_*, delta_*, ... } from /summary

  React.useEffect(() => {
    let alive = true;
    if (!brand || !brand.id) return;
    setSummary(null);
    window.AdminAPI.brands.summary(brand.id, range || '30d')
      .then((s) => { if (alive) setSummary(s || {}); })
      .catch((e) => { if (alive) { console.warn('brand summary failed', e); setSummary({}); } });
    return () => { alive = false; };
  }, [brand && brand.id, range]);

  // delta 拿 summary 的真實值；summary 沒回時退回 0（不再用編造的 +12% / -2%）
  const dCost = (summary && summary.delta_total_cost_usd) || 0;
  const dConvos = (summary && summary.delta_total_convos) || 0;
  const dTokens = (summary && summary.delta_total_tokens) || 0;
  const dCache = (summary && summary.delta_cache_hit_rate) || 0;
  const cacheHit = summary && typeof summary.cache_hit_rate === 'number' ? summary.cache_hit_rate : (brand.cacheHit || 0);

  return (
    <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12, color: '#9098A3' }}>
        <button onClick={onBack} style={{ color: '#5C6470', fontSize: 12 }}>← 回品牌列表</button>
        <span>/</span>
        <span style={{ color: '#5C6470' }}>{brand.name}</span>
      </div>

      <Card>
        <div style={{ padding: '14px 18px', display: 'flex', alignItems: 'center', gap: 16 }}>
          <BrandThumb id={brand.id} />
          <div style={{ flex: 1 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={{ fontSize: 16, fontWeight: 600, color: '#17171A' }}>{brand.name}</span>
              {brand.isAnomalous && <Pill color="red">⚠ 異常 · {brand.anomalyRatio}× 基準</Pill>}
            </div>
            <div style={{ fontSize: 11, color: '#9098A3', marginTop: 4 }}>
              <span className="term">brand_idx={brand.id}</span>
              {brand.lastActivityHrs < 9999 && <span> · 最後活躍 {brand.lastActivityHrs} 小時前</span>}
            </div>
          </div>
        </div>
      </Card>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10 }}>
        <KPICard label="期間費用" value={fmtUSD(brand.totalCost, brand.totalCost < 10 ? 4 : 2)} delta={dCost} spark={brand.dailyCost} sparkColor="#B45309" />
        <KPICard label="對話數" value={fmtNum(brand.totalConvos)} delta={dConvos} spark={brand.dailyConvos} sparkColor="#1D4ED8" inverse />
        <KPICard label="Token 數" value={fmtCompact(brand.tokens)} delta={dTokens} spark={brand.dailyCost.map(c => c * 220000)} sparkColor="#6D28D9" inverse />
        <KPICard label="Cache 命中" value={fmtPct(cacheHit)} delta={dCache} spark={null} sparkColor="#15803D" inverseDelta />
      </div>

      <Card>
        <div style={{ display: 'flex', borderBottom: '1px solid #EEEEE9' }}>
          {[
            { id: 'activity', label: '活動趨勢' },
            { id: 'users', label: '成員' },
            { id: 'sessions', label: '對話紀錄' },
          ].map(t => (
            <button key={t.id} onClick={() => setTab(t.id)}
              style={{
                padding: '10px 16px', fontSize: 12, fontWeight: 500,
                color: tab === t.id ? '#17171A' : '#9098A3',
                borderBottom: tab === t.id ? '2px solid #FFE600' : '2px solid transparent',
              }}>{t.label}</button>
          ))}
        </div>
        <div style={{ padding: 14 }}>
          {tab === 'activity' && <BrandActivityChart brand={brand} />}
          {tab === 'users' && <BrandUsersTable brand={brand} />}
          {tab === 'sessions' && <BrandSessionsList brand={brand} />}
        </div>
      </Card>
    </div>
  );
}

function BrandActivityChart({ brand }) {
  // 從 BRANDS 拿不到日期 array → 用 DAILY_AGG.date 對齊（兩者都用 fullDates）
  const dates = ((window.MOCK && window.MOCK.DAILY_AGG) || []).map((d) => d.date);
  return (
    <ResponsiveBox height={240}>
      {(w, h) => <BrandActivityChartImpl brand={brand} dates={dates} w={w} h={h} />}
    </ResponsiveBox>
  );
}

function BrandActivityChartImpl({ brand, dates, w, h }) {
  const padL = 50, padR = 50, padT = 14, padB = 24;
  const innerW = Math.max(0, w - padL - padR);
  const innerH = h - padT - padB;
  const dailyCost = brand.dailyCost || [];
  const dailyConvos = brand.dailyConvos || [];
  const n = Math.max(1, dailyCost.length);
  const stepX = n > 1 ? innerW / (n - 1) : innerW;
  const maxCost = Math.max(0.0001, ...dailyCost) * 1.1;
  const maxConvo = Math.max(1, ...dailyConvos) * 1.1;

  const costPath = dailyCost.map((v, i) => {
    const x = padL + i * stepX;
    const y = padT + innerH - (v / maxCost) * innerH;
    return (i === 0 ? 'M' : 'L') + x.toFixed(1) + ',' + y.toFixed(1);
  }).join(' ');

  return (
    <div>
      <svg width="100%" height={h} viewBox={`0 0 ${w} ${h}`} style={{ display: 'block' }}>
        {[0, 0.25, 0.5, 0.75, 1].map((t) => {
          const y = padT + innerH - t * innerH;
          return (
            <g key={t}>
              <line x1={padL} x2={w - padR} y1={y} y2={y} stroke="#EEEEE9" strokeDasharray="2 3" />
              <text x={padL - 8} y={y + 3} fontSize={10} fill="#B45309" textAnchor="end" opacity={0.85}>${fmtCompact(maxCost * t)}</text>
              <text x={w - padR + 8} y={y + 3} fontSize={10} fill="#1D4ED8" textAnchor="start" opacity={0.85}>{fmtCompact(maxConvo * t)}</text>
            </g>
          );
        })}
        {dailyConvos.map((v, i) => {
          const barH = (v / maxConvo) * innerH;
          const x = padL + i * stepX - 3;
          const y = padT + innerH - barH;
          return <rect key={i} x={x} y={y} width={6} height={barH} fill="#1D4ED8" fillOpacity={0.2} />;
        })}
        {dailyCost.length > 1 && (
          <>
            <path d={costPath + ` L ${padL + (n - 1) * stepX},${padT + innerH} L ${padL},${padT + innerH} Z`} fill="#B45309" fillOpacity={0.1} />
            <path d={costPath} stroke="#B45309" strokeWidth={1.5} fill="none" />
          </>
        )}
        {dailyCost.map((v, i) => (
          <g key={i}>
            <title>{`${dates[i] || `day ${i + 1}`} · ${fmtUSD(v, 4)} · ${dailyConvos[i] || 0} 場`}</title>
            <circle cx={padL + i * stepX} cy={padT + innerH - (v / maxCost) * innerH} r={4} fill="#B45309" fillOpacity={0.001} stroke="none" />
            <circle cx={padL + i * stepX} cy={padT + innerH - (v / maxCost) * innerH} r={2} fill="#B45309" pointerEvents="none" />
          </g>
        ))}
        {/* X 軸標籤：頭、中、尾三個 */}
        {dates.length > 0 && [0, Math.floor((n - 1) / 2), n - 1].filter((i, idx, arr) => arr.indexOf(i) === idx).map((i) => (
          <text key={'x' + i} x={padL + i * stepX} y={h - 6} fontSize={10} fill="#9098A3" textAnchor="middle">{(dates[i] || '').slice(5)}</text>
        ))}
      </svg>
      <div style={{ display: 'flex', gap: 16, fontSize: 11, marginTop: 8 }}>
        <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}><span style={{ width: 12, height: 2, background: '#B45309' }}></span><span style={{ color: '#5C6470' }}>每日費用 (USD)</span></span>
        <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}><span style={{ width: 6, height: 10, background: '#1D4ED8', opacity: 0.5 }}></span><span style={{ color: '#5C6470' }}>對話數</span></span>
      </div>
    </div>
  );
}

function BrandUsersTable({ brand }) {
  const [users, setUsers] = React.useState(null);  // null = loading
  const [error, setError] = React.useState(null);

  React.useEffect(() => {
    let alive = true;
    setUsers(null);
    setError(null);
    if (!brand || !brand.id) return;
    window.AdminAPI.brands.users(brand.id, 50)
      .then((data) => {
        if (!alive) return;
        setUsers((data && data.users) || []);
      })
      .catch((e) => {
        if (!alive) return;
        setError(e.message || '載入失敗');
        setUsers([]);
      });
    return () => { alive = false; };
  }, [brand && brand.id]);

  if (users == null) {
    return <div style={{ padding: 20, fontSize: 12, color: '#9098A3' }}>載入成員中...</div>;
  }
  if (error) {
    return <div style={{ padding: 20, fontSize: 12, color: '#DC2626' }}>{error}</div>;
  }
  if (users.length === 0) {
    return <div style={{ padding: 20, fontSize: 12, color: '#9098A3' }}>此品牌目前沒有任何成員操作過 agent。</div>;
  }

  const formatLastActive = (iso) => {
    if (!iso) return '—';
    const ms = Date.now() - new Date(iso).getTime();
    const mins = Math.floor(ms / 60000);
    if (mins < 1) return '剛剛';
    if (mins < 60) return `${mins} 分鐘前`;
    const hrs = Math.floor(mins / 60);
    if (hrs < 24) return `${hrs} 小時前`;
    const days = Math.floor(hrs / 24);
    if (days < 30) return `${days} 天前`;
    return iso.slice(0, 10);
  };

  return (
    <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
      <thead>
        <tr style={{ borderBottom: '1px solid #EEEEE9' }}>
          <Th>使用者</Th>
          <Th style={{ textAlign: 'right' }}>對話數</Th>
          <Th style={{ textAlign: 'right' }}>Token</Th>
          <Th style={{ textAlign: 'right' }}>費用</Th>
          <Th>最後活躍</Th>
        </tr>
      </thead>
      <tbody>
        {users.map((u) => (
          <tr key={u.user_admin_id} style={{ borderBottom: '1px solid #EEEEE9', height: 32 }}>
            <td style={{ padding: '6px 12px' }}>
              <div style={{ color: '#17171A' }} title={`user_admin_idx=${u.user_admin_id}`}>
                {u.user_admin_name || `admin#${u.user_admin_id}`}
              </div>
              <div className="term" style={{ fontSize: 10, color: '#9098A3' }}>idx={u.user_admin_id}</div>
            </td>
            <td className="mono" style={{ padding: '6px 12px', textAlign: 'right', color: '#17171A' }}>{u.total_convos}</td>
            <td className="mono" style={{ padding: '6px 12px', textAlign: 'right', color: '#5C6470' }}>{fmtCompact(u.total_tokens)}</td>
            <td className="mono" style={{ padding: '6px 12px', textAlign: 'right', color: '#17171A' }}>{fmtUSD(u.total_cost_usd, 4)}</td>
            <td style={{ padding: '6px 12px', color: '#5C6470' }}>{formatLastActive(u.last_activity_at)}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function BrandSessionsList({ brand }) {
  // 之前讀 window.MOCK.CONVERSATIONS（brands route 不會 load 對話列表，永遠空）。
  // 改成 useEffect 直接拉 /api/conversations?brand_id=...
  const [list, setList] = React.useState(null);
  const [error, setError] = React.useState(null);
  React.useEffect(() => {
    let alive = true;
    setList(null);
    setError(null);
    if (!brand || !brand.id) return;
    window.AdminAPI.conversations.list({ brandId: brand.id, limit: 30 })
      .then((data) => {
        if (!alive) return;
        const rows = (data && data.conversations) || [];
        setList(rows);
      })
      .catch((e) => { if (alive) { setError(e.message || '載入失敗'); setList([]); } });
    return () => { alive = false; };
  }, [brand && brand.id]);

  if (list == null) return <div style={{ padding: 20, fontSize: 12, color: '#9098A3' }}>載入對話列表中...</div>;
  if (error) return <div style={{ padding: 20, fontSize: 12, color: '#DC2626' }}>{error}</div>;
  if (list.length === 0) return <div style={{ padding: 20, fontSize: 12, color: '#9098A3' }}>此品牌目前沒有對話紀錄。</div>;

  const onOpenThread = (threadId) => {
    window.location.hash = '#/conversations/' + encodeURIComponent(threadId);
  };

  return (
    <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
      <thead>
        <tr style={{ borderBottom: '1px solid #EEEEE9' }}>
          <Th>更新時間</Th><Th>標題</Th><Th>使用者</Th>
          <Th style={{ textAlign: 'right' }}>訊息</Th>
          <Th style={{ textAlign: 'right' }}>工具</Th>
          <Th style={{ textAlign: 'right' }}>費用</Th>
        </tr>
      </thead>
      <tbody>
        {list.map((s) => {
          const updated = s.updated_at ? new Date(s.updated_at) : null;
          return (
            <tr key={s.thread_id} onClick={() => onOpenThread(s.thread_id)}
              style={{ borderBottom: '1px solid #EEEEE9', height: 32, cursor: 'pointer' }}
              onMouseEnter={(e) => e.currentTarget.style.background = '#FFFAB8'}
              onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
              <td className="term" style={{ padding: '6px 12px', color: '#5C6470', fontSize: 11 }}>
                {updated ? updated.toISOString().slice(5, 16).replace('T', ' ') : '—'}
              </td>
              <td style={{ padding: '6px 12px', color: '#17171A', maxWidth: 360, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{s.title || '新對話'}</td>
              <td style={{ padding: '6px 12px', color: '#5C6470' }} title={s.user_admin_id ? `user_admin_idx=${s.user_admin_id}` : ''}>
                {s.user_admin_name || (s.user_admin_id ? `admin#${s.user_admin_id}` : '—')}
              </td>
              <td className="mono" style={{ padding: '6px 12px', textAlign: 'right', color: '#17171A' }}>{s.message_count || 0}</td>
              <td className="mono" style={{ padding: '6px 12px', textAlign: 'right', color: '#5C6470' }}>{s.total_tool_calls || 0}</td>
              <td className="mono" style={{ padding: '6px 12px', textAlign: 'right', color: '#17171A' }}>{fmtUSD(s.total_cost_usd || 0, 4)}</td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

window.PageBrands = PageBrands;
