// 使用统计 · 真实实现版
// - 4 张关键卡：总消息数 / 总花费 / 缓存命中率 / Token 总量
// - 7 天 / 30 天时段切换
// - 📈 每日花费趋势（折线图）
// - 💬 每日消息数（折线图）
// - 📦 压缩 · 摘要（来自 CompressionStats，带摘要管理页入口）
// - 🤖 模型使用分布（按消息）
// - 💡 省钱小贴士

// ---- 价目表（per 1M tokens, USD） ----
// 只包含实际使用的模型，其他模型调用时再添加
const MODEL_PRICING = {
  // 主要使用的模型
  'sonnet-4.5.5': { in: 3,  out: 15, label: 'Sonnet 4.5', kind: 'shark' },
  'opus-4.5':   { in: 5,  out: 25, label: 'Opus 4.5',   kind: 'shark' },

  // 其他可用模型（暂未使用，保留定价）
  'sonnet-4.5.6': { in: 3,  out: 15, label: 'Sonnet 4.6', kind: 'amber' },
  'opus-4.6':   { in: 5,  out: 25, label: 'Opus 4.6',   kind: 'amber' },
  'opus-4.7':   { in: 5,  out: 25, label: 'Opus 4.7',   kind: 'amber' },
  'haiku-4.5':  { in: 1,  out: 5,  label: 'Haiku 4.5',  kind: 'rose'  },

  // 压缩系统可能使用的模型
  'deepseek-v3':{ in: 0.27, out: 1.1, label: 'DeepSeek V3', kind: 'amber' },
};

function estimateTokens(text) {
  if (!text) return 0;
  // 粗略估算：中文 1 token ≈ 2 字符，足够展示
  return Math.ceil((text || '').length / 2);
}
function priceOf(modelId, inTok, outTok) {
  const p = MODEL_PRICING[modelId] || MODEL_PRICING['sonnet-4.5.5'];
  return (inTok * p.in + outTok * p.out) / 1_000_000;
}
function fmtMoney3(v) { return '$' + (v || 0).toFixed(3); }
function fmtTokAbbr(n) {
  if (n == null) return '0';
  if (n >= 10000) return (n / 1000).toFixed(1) + 'K';
  if (n >= 1000)  return (n / 1000).toFixed(2) + 'K';
  return String(n);
}

const StatsPage = ({ state, go }) => {
  const [range, setRange] = React.useState(7);
  const messages = state.messages || [];
  const summaries = state.summaries || [];

  // === 总览指标 ===
  let inToks = 0, outToks = 0, totalCost = 0;
  for (let i = 0; i < messages.length; i++) {
    const m = messages[i];
    const t = estimateTokens(m.content);
    if (m.role === 'user') {
      inToks += t;
    } else if (m.role === 'assistant') {
      outToks += t;
      const prev = messages[i - 1];
      const inT = prev && prev.role === 'user' ? estimateTokens(prev.content) : 0;
      totalCost += priceOf(m.model || 'sonnet-4.5', inT, t);
    }
  }
  const totalTok = inToks + outToks;

  // 缓存命中估算：连续相同模型的 assistant 回复算命中
  const assistantMsgs = messages.filter((m) => m.role === 'assistant');
  let cacheHits = 0;
  for (let i = 1; i < assistantMsgs.length; i++) {
    if (assistantMsgs[i].model && assistantMsgs[i].model === assistantMsgs[i - 1].model) cacheHits++;
  }
  const cacheHitRate = assistantMsgs.length > 1 ? cacheHits / (assistantMsgs.length - 1) : 0;
  const cacheSavings = totalCost * cacheHitRate * 0.5; // 命中折半

  // === 每日趋势数据 ===
  const today = new Date(); today.setHours(0, 0, 0, 0);
  const days = [];
  for (let i = range - 1; i >= 0; i--) {
    const d = new Date(today); d.setDate(d.getDate() - i);
    const next = new Date(d); next.setDate(next.getDate() + 1);
    let msgs = 0, cost = 0;
    messages.forEach((m, idx) => {
      if (!m.ts) return;
      if (m.ts >= d.getTime() && m.ts < next.getTime()) {
        msgs++;
        if (m.role === 'assistant') {
          const prev = messages[idx - 1];
          const inT = prev && prev.role === 'user' ? estimateTokens(prev.content) : 0;
          cost += priceOf(m.model || 'sonnet-4.5', inT, estimateTokens(m.content));
        }
      }
    });
    days.push({
      label: `${d.getMonth() + 1}/${d.getDate()}`,
      weekday: ['日','一','二','三','四','五','六'][d.getDay()],
      msgs, cost,
      isToday: i === 0,
    });
  }
  const rangeTotalCost = days.reduce((a, d) => a + d.cost, 0);
  const rangeTotalMsgs = days.reduce((a, d) => a + d.msgs, 0);

  // === 模型使用分布（assistant 消息层面）===
  const byModel = {};
  assistantMsgs.forEach((m) => {
    const id = m.model || 'sonnet-4.5';
    byModel[id] = (byModel[id] || 0) + 1;
  });
  const modelEntries = Object.entries(byModel).sort((a, b) => b[1] - a[1]);

  return (
    <div>
      <div className="page-head">
        <div>
          <h1 className="page-title">使用统计 <span style={{fontSize:26, marginLeft: 6}}>💰</span></h1>
          <div className="page-sub">让数字也变成回忆的形状</div>
        </div>
      </div>

      <div className="stats-wrap-v2">

        {/* === 顶部 4 张关键卡 === */}
        <div className="stats-hero-grid">
          <div className="stats-hero-card">
            <div className="hl">总消息数</div>
            <div className="hv">{messages.length}</div>
            <div className="hf">和五郎的对话</div>
          </div>
          <div className="stats-hero-card amber">
            <div className="hl">总花费</div>
            <div className="hv">{fmtMoney3(totalCost)}</div>
            <div className="hf">累计消费</div>
          </div>
          <div className="stats-hero-card rose">
            <div className="hl">缓存命中率</div>
            <div className="hv">{(cacheHitRate * 100).toFixed(1)}<span className="hv-unit">%</span></div>
            <div className="hf">省了 <span style={{color:'var(--amber-600)', fontWeight:600}}>{fmtMoney3(cacheSavings)}</span></div>
          </div>
          <div className="stats-hero-card shark">
            <div className="hl">Token 总量</div>
            <div className="hv">{fmtTokAbbr(totalTok)}</div>
            <div className="hf">
              <span style={{color:'var(--shark-600)'}}>↑ {fmtTokAbbr(inToks)}</span>
              <span style={{margin:'0 8px', color:'var(--ink-300)'}}>·</span>
              <span style={{color:'var(--amber-600)'}}>↓ {fmtTokAbbr(outToks)}</span>
            </div>
          </div>
        </div>

        {/* === 模型使用分布（按消息）—— 放在关键卡正下面 === */}
        <div className="stats-chart-panel">
          <div className="stats-chart-head">
            <span className="title">
              <span className="pic"><window.Icon name="bot" size={15} /></span>
              模型使用分布
            </span>
            <span className="aside">共 <strong>{assistantMsgs.length}</strong> 条回复</span>
          </div>
          {modelEntries.length === 0 ? (
            <div className="stats-empty-line">还没有数据 · 开口跟五郎聊一句吧</div>
          ) : (
            modelEntries.map(([id, cnt]) => {
              const p = MODEL_PRICING[id] || { label: id, kind: 'amber' };
              const pct = (cnt / assistantMsgs.length) * 100;
              return (
                <div key={id} className="cstat-bar-row">
                  <div className="cstat-bar-label">
                    <span className="lf">
                      <span className={"dot " + (p.kind === 'shark' ? 'shark' : 'amber')}></span>
                      <span>claude-{id}</span>
                    </span>
                    <span className="rt"><strong>{cnt}</strong> 条<span className="pct">· {pct.toFixed(1)}%</span></span>
                  </div>
                  <div className="cstat-bar">
                    <div className={"cstat-bar-fill " + (p.kind === 'shark' ? 'shark' : '')} style={{width: pct + '%'}}></div>
                  </div>
                </div>
              );
            })
          )}
        </div>

        {/* === 时段切换 === */}
        <div className="stats-range-toggle">
          <button className={range === 7 ? 'on' : ''} onClick={() => setRange(7)}>最近 7 天</button>
          <button className={range === 30 ? 'on' : ''} onClick={() => setRange(30)}>最近 30 天</button>
        </div>

        {/* === 每日花费趋势 === */}
        <div className="stats-chart-panel">
          <div className="stats-chart-head">
            <span className="title">
              <span className="pic"><window.Icon name="chart" size={15} /></span>
              每日花费趋势
            </span>
            <span className="aside">合计 <strong>{fmtMoney3(rangeTotalCost)}</strong></span>
          </div>
          <LineChart days={days} valueKey="cost" formatter={(v) => fmtMoney3(v)} color="amber" />
        </div>

        {/* === 每日消息数 === */}
        <div className="stats-chart-panel">
          <div className="stats-chart-head">
            <span className="title">
              <span className="pic"><window.Icon name="chat" size={15} /></span>
              每日消息数
            </span>
            <span className="aside">合计 <strong>{rangeTotalMsgs}</strong> 条</span>
          </div>
          <LineChart days={days} valueKey="msgs" formatter={(v) => v + ' 条'} color="shark" />
        </div>

        {/* === 压缩 · 摘要（含统计页入口） === */}
        <window.CompressionStats state={state} go={go} />

        {/* === 省钱小贴士 === */}
        <div className="stats-tips">
          <div className="stats-tips-title">💡 省钱小贴士</div>
          <ul>
            <li>Prompt Caching 已启用（1 小时 TTL），连续聊天更省钱</li>
            <li>Sonnet 4.5 比 Opus 4 便宜 80%，日常聊天可优先使用</li>
            <li>缓存命中率越高，省的钱越多（目标：&gt; 60%）</li>
            {summaries.length > 0 ? (
              <li>已开启对话压缩 · 累计省了 <strong>{fmtMoney3(summaries.reduce((a, s) => a + (s.costSaved || 0), 0))}</strong>，继续保持～</li>
            ) : (
              <li>开启对话压缩功能后，长程聊天还能再省 80–90%！</li>
            )}
          </ul>
        </div>
      </div>
    </div>
  );
};

// =====================================================================
// LineChart · 固定每日宽度 · 水平滚动 · 文字保持正常长宽比（不再用 preserveAspectRatio="none"）
// =====================================================================
const LineChart = ({ days, valueKey, formatter, color = 'amber' }) => {
  const PX_PER_DAY = 78;                          // 每天横向占的像素
  const P = { l: 30, r: 30, t: 38, b: 32 };
  const H = 200;
  const W = Math.max(PX_PER_DAY * days.length + P.l + P.r, 480);

  const vals = days.map((d) => d[valueKey] || 0);
  const rawMax = Math.max(...vals);
  const max = rawMax > 0 ? rawMax * 1.18 : 1;
  const usableW = W - P.l - P.r;
  const usableH = H - P.t - P.b;
  const xStep = days.length > 1 ? usableW / (days.length - 1) : 0;
  const xAt = (i) => P.l + i * xStep;
  const yAt = (v) => P.t + (1 - v / max) * usableH;

  const pts = days.map((d, i) => ({
    x: xAt(i), y: yAt(d[valueKey] || 0),
    v: d[valueKey] || 0, label: d.label, isToday: d.isToday,
  }));

  // 平滑贝塞尔路径
  let pathD = '';
  pts.forEach((p, i) => {
    if (i === 0) { pathD += `M ${p.x.toFixed(1)},${p.y.toFixed(1)}`; return; }
    const prev = pts[i - 1];
    const cpx1 = prev.x + xStep * 0.42;
    const cpx2 = p.x - xStep * 0.42;
    pathD += ` C ${cpx1.toFixed(1)},${prev.y.toFixed(1)} ${cpx2.toFixed(1)},${p.y.toFixed(1)} ${p.x.toFixed(1)},${p.y.toFixed(1)}`;
  });
  const areaD = pathD + ` L ${pts[pts.length - 1].x.toFixed(1)},${(P.t + usableH).toFixed(1)} L ${pts[0].x.toFixed(1)},${(P.t + usableH).toFixed(1)} Z`;

  // 固定每天 78px → 30 天会有 ~2.3k 宽，可横向滑动；不再过滤标签
  const showLabel = (p) => p.v > 0;
  const showXLabel = () => true;

  // 横向滚动到"今天"那一列
  const scrollerRef = React.useRef(null);
  React.useEffect(() => {
    const el = scrollerRef.current;
    if (!el) return;
    // 让今天大致出现在视口右侧偏中
    el.scrollLeft = Math.max(0, el.scrollWidth - el.clientWidth);
  }, [days.length, valueKey]);

  const lineGradId = `lg-line-${color}-${Math.random().toString(36).slice(2,8)}`;
  const areaGradId = `lg-area-${color}-${Math.random().toString(36).slice(2,8)}`;

  return (
    <div className={"line-chart line-chart-" + color} ref={scrollerRef}>
      <svg
        width={W}
        height={H}
        viewBox={`0 0 ${W} ${H}`}
        className="line-chart-svg"
      >
        <defs>
          <linearGradient id={areaGradId} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" className="area-stop-0" />
            <stop offset="100%" className="area-stop-1" />
          </linearGradient>
          <linearGradient id={lineGradId} x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" className="line-stop-0" />
            <stop offset="100%" className="line-stop-1" />
          </linearGradient>
        </defs>

        {/* gridlines */}
        {[0, 0.25, 0.5, 0.75].map((f, i) => {
          const y = P.t + f * usableH;
          return <line key={i} x1={P.l} x2={W - P.r} y1={y} y2={y} className="lc-grid" />;
        })}
        <line x1={P.l} x2={W - P.r} y1={P.t + usableH} y2={P.t + usableH} className="lc-axis" />

        {/* 面积 */}
        <path d={areaD} fill={`url(#${areaGradId})`} />

        {/* 折线 */}
        <path d={pathD} fill="none" stroke={`url(#${lineGradId})`} strokeWidth="2.5" strokeLinejoin="round" strokeLinecap="round" />

        {/* 数据点 + 标签 */}
        {pts.map((p, i) => (
          <g key={i}>
            {showLabel(p, i) && (
              <text
                x={p.x}
                y={p.y - 14}
                textAnchor="middle"
                className={"lc-vlabel " + (p.isToday ? 'today' : '')}
              >
                {formatter(p.v)}
              </text>
            )}
            <circle
              cx={p.x} cy={p.y}
              r={p.isToday ? 4.5 : 3}
              className={"lc-dot " + (p.isToday ? 'today' : '')}
            />
            {showXLabel(p, i) && (
              <text
                x={p.x}
                y={P.t + usableH + 18}
                textAnchor="middle"
                className={"lc-xlabel " + (p.isToday ? 'today' : '')}
              >
                {p.isToday ? '今天' : p.label}
              </text>
            )}
          </g>
        ))}
      </svg>
    </div>
  );
};

window.StatsPage = StatsPage;
window.LineChart = LineChart;
window.MODEL_PRICING = MODEL_PRICING;
