import { useEffect, useMemo, useState, type ReactNode } from "react";
import { adminUsage, grantCredits, type UsageReport, type UsageTenantSum, type UsageDay } from "../api";
import { BillingRules } from "../components/BillingRules";

// 管理端「用量 & 计费」= 计费闭环一页：顶部配「规则」(单价/积分权重/汇率)，下方看「结果」(用量观测)。
// 规则→扣费→观测：改规则即对后续任务生效，用量观测（读 /admin/usage，系统级跨租户）即其结果。
// 金额/积分均为微单位（×10⁻⁶），展示时 ÷1e6。

const MICRO = 1_000_000;
const credits = (micro: number) => (micro / MICRO).toLocaleString("zh-CN", { maximumFractionDigits: 2 });
const money = (micro: number) => (micro / MICRO).toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const int = (n: number) => n.toLocaleString("zh-CN");

// YYYYMMDD（本地）。
function ymd(d: Date): string {
  return `${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, "0")}${String(d.getDate()).padStart(2, "0")}`;
}
function rangeFor(days: number): { from: string; to: string } {
  const now = new Date();
  const from = new Date(now);
  from.setDate(now.getDate() - (days - 1));
  return { from: ymd(from), to: ymd(now) };
}
// 把稀疏的 trend 补齐成连续日序列（缺的天补 0），便于成条形图。
function fillDays(trend: UsageDay[], days: number): UsageDay[] {
  const byDay = new Map(trend.map((d) => [d.day, d]));
  const out: UsageDay[] = [];
  const now = new Date();
  for (let i = days - 1; i >= 0; i--) {
    const d = new Date(now);
    d.setDate(now.getDate() - i);
    const key = ymd(d);
    out.push(byDay.get(key) ?? { day: key, total_tok: 0, credits_micro: 0, cost_micros: 0, task_count: 0 });
  }
  return out;
}
const mmdd = (ymdStr: string) => `${ymdStr.slice(4, 6)}-${ymdStr.slice(6, 8)}`;

export function UsagePage() {
  const [days, setDays] = useState(30);
  const [tenant, setTenant] = useState(""); // "" = 全平台
  const [report, setReport] = useState<UsageReport | null>(null);
  const [tenantOpts, setTenantOpts] = useState<UsageTenantSum[]>([]); // 下拉选项（来自全平台口径）
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [err, setErr] = useState("");

  const load = async () => {
    setRefreshing(true);
    try {
      const { from, to } = rangeFor(days);
      const r = await adminUsage({ tenant: tenant || undefined, from, to });
      setReport(r);
      if (!tenant && r.tenants) setTenantOpts(r.tenants); // 全平台口径顺带刷新下拉
      setErr("");
    } catch (e) {
      setErr((e as Error).message);
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  };

  useEffect(() => {
    void load();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [days, tenant]);

  const series = useMemo(() => (report ? fillDays(report.trend, days) : []), [report, days]);

  const [granting, setGranting] = useState("");
  const doGrant = async (tenantId: string, name: string) => {
    const s = window.prompt(`给「${name}」充值积分（正=充值，负=扣减/校正）`, "100");
    if (s === null) return;
    const n = Number(s);
    if (!n) return;
    setGranting(tenantId);
    try {
      await grantCredits(tenantId, n, "admin 手动充值");
      await load();
    } catch (e) {
      window.alert((e as Error).message);
    } finally {
      setGranting("");
    }
  };

  if (loading) return <div className="text-sm text-gray-400">加载用量数据中…</div>;
  if (err) return <div className="text-sm text-rose-500">用量加载失败：{err}</div>;
  if (!report) return null;

  const t = report.totals;
  const selectedName = tenant ? tenantOpts.find((x) => x.tenant_id === tenant)?.name ?? tenant : "";

  return (
    <div className="space-y-6">
      {/* 配置端：计费规则（改规则即对后续任务生效） */}
      <BillingRules onSaved={() => void load()} />

      {/* 观测端：用量结果 */}
      <div className="flex items-center gap-2 pt-1">
        <h3 className="text-sm font-semibold text-gray-700">用量观测</h3>
        <span className="text-[11px] text-gray-400">按规则折算后的实际消耗</span>
      </div>

      {/* 顶栏：租户筛选 + 区间 + 刷新 */}
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex items-center gap-2">
          <select
            value={tenant}
            onChange={(e) => setTenant(e.target.value)}
            className="rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-sm text-gray-700 shadow-sm focus:border-violet-400 focus:outline-none"
          >
            <option value="">全平台（所有租户）</option>
            {tenantOpts.map((o) => (
              <option key={o.tenant_id} value={o.tenant_id}>
                {o.name || o.tenant_id}
              </option>
            ))}
          </select>
          <div className="flex overflow-hidden rounded-lg border border-gray-200 text-xs">
            {[7, 30].map((d) => (
              <button
                key={d}
                onClick={() => setDays(d)}
                className={`px-3 py-1.5 ${days === d ? "bg-violet-600 text-white" : "bg-white text-gray-500 hover:bg-gray-50"}`}
              >
                近 {d} 天
              </button>
            ))}
          </div>
        </div>
        <div className="flex items-center gap-3 text-xs text-gray-400">
          <span>
            {mmdd(report.from)} ~ {mmdd(report.to)} · {tenant ? "单租户口径" : "全平台口径"}
          </span>
          <button
            onClick={() => void load()}
            disabled={refreshing}
            className="flex items-center gap-1 rounded border border-gray-200 px-2.5 py-1 text-gray-500 hover:bg-gray-50 disabled:opacity-40"
          >
            <svg viewBox="0 0 24 24" className={`h-3.5 w-3.5 ${refreshing ? "animate-spin" : ""}`} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M23 4v6h-6 M1 20v-6h6 M3.51 9a9 9 0 0 1 14.85-3.36L23 10 M1 14l4.64 4.36A9 9 0 0 0 20.49 15" />
            </svg>
            {refreshing ? "刷新中" : "刷新"}
          </button>
        </div>
      </div>

      {/* KPI 卡片 */}
      <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
        <Metric label="积分消耗" tone="violet" value={credits(t.credits_micro)} sub={`区间合计 · ${int(t.task_count)} 次运行`} />
        <Metric label="Token 用量" tone="cyan" value={int(t.total_tok)} sub="prompt + completion（估算）" />
        <Metric label="估算成本" tone="amber" value={money(t.cost_micros)} sub="按定价折算（配置币种）" />
        {tenant ? (
          <Metric label="当前积分余额" tone={(report.balance_micro ?? 0) >= 0 ? "emerald" : "rose"} value={credits(report.balance_micro ?? 0)} sub={selectedName || "该租户"} />
        ) : (
          <Metric label="活跃租户" tone="emerald" value={int(tenantOpts.length)} sub="区间内有用量的租户数" />
        )}
      </div>

      {/* 积分消耗趋势（按天） */}
      <div className="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
        <div className="mb-4 flex items-center justify-between">
          <h4 className="text-sm font-semibold text-gray-700">积分消耗趋势</h4>
          <span className="text-[11px] text-gray-400">每日 credits · 悬停看明细</span>
        </div>
        <TrendBars series={series} />
      </div>

      {/* 全平台：各租户用量排行 */}
      {!tenant && (
        <div className="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
          <div className="mb-3 flex items-center justify-between">
            <h4 className="text-sm font-semibold text-gray-700">各租户用量排行</h4>
            <span className="rounded bg-violet-50 px-2 py-0.5 text-[10px] font-medium text-violet-700">按积分消耗</span>
          </div>
          {tenantOpts.length === 0 ? (
            <div className="py-6 text-center text-xs text-gray-400">区间内暂无用量</div>
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b border-gray-100 text-left text-[11px] uppercase tracking-wide text-gray-400">
                    <th className="py-2 pr-3 font-medium">租户</th>
                    <th className="py-2 pr-3 text-right font-medium">积分消耗</th>
                    <th className="py-2 pr-3 text-right font-medium">Token</th>
                    <th className="py-2 pr-3 text-right font-medium">成本</th>
                    <th className="py-2 pr-3 text-right font-medium">运行数</th>
                    <th className="py-2 pr-3 text-right font-medium">当前余额</th>
                    <th className="py-2 text-right font-medium">操作</th>
                  </tr>
                </thead>
                <tbody>
                  {tenantOpts.map((r) => (
                    <tr key={r.tenant_id} className="border-b border-gray-50 last:border-0">
                      <td className="py-2 pr-3">
                        <button onClick={() => setTenant(r.tenant_id)} className="font-medium text-violet-600 hover:underline">
                          {r.name || r.tenant_id}
                        </button>
                      </td>
                      <td className="py-2 pr-3 text-right tabular-nums text-gray-800">{credits(r.credits_micro)}</td>
                      <td className="py-2 pr-3 text-right tabular-nums text-gray-500">{int(r.total_tok)}</td>
                      <td className="py-2 pr-3 text-right tabular-nums text-gray-500">{money(r.cost_micros)}</td>
                      <td className="py-2 pr-3 text-right tabular-nums text-gray-500">{int(r.task_count)}</td>
                      <td className={`py-2 pr-3 text-right tabular-nums ${r.balance_micro >= 0 ? "text-gray-800" : "text-rose-500"}`}>{credits(r.balance_micro)}</td>
                      <td className="py-2 text-right">
                        <button
                          onClick={() => void doGrant(r.tenant_id, r.name || r.tenant_id)}
                          disabled={granting === r.tenant_id}
                          className="rounded border border-violet-200 px-2.5 py-1 text-xs text-violet-600 hover:bg-violet-50 disabled:opacity-40"
                        >
                          {granting === r.tenant_id ? "…" : "充值"}
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

const TONE: Record<string, string> = {
  violet: "text-violet-600",
  cyan: "text-cyan-600",
  amber: "text-amber-600",
  emerald: "text-emerald-600",
  rose: "text-rose-500",
};

function Metric({ label, value, sub, tone }: { label: string; value: ReactNode; sub?: ReactNode; tone: string }) {
  return (
    <div className="rounded-xl border border-gray-100 bg-white p-4 shadow-sm">
      <div className="text-xs text-gray-400">{label}</div>
      <div className={`mt-1 text-2xl font-semibold tabular-nums ${TONE[tone] ?? "text-gray-800"}`}>{value}</div>
      {sub && <div className="mt-1 text-[11px] text-gray-400">{sub}</div>}
    </div>
  );
}

function TrendBars({ series }: { series: UsageDay[] }) {
  const max = Math.max(1, ...series.map((d) => d.credits_micro));
  if (series.every((d) => d.credits_micro === 0)) {
    return <div className="py-8 text-center text-xs text-gray-400">区间内暂无用量</div>;
  }
  return (
    <div className="flex h-40 items-end gap-1">
      {series.map((d) => {
        const h = (d.credits_micro / max) * 100;
        return (
          <div key={d.day} className="group relative flex h-full flex-1 flex-col items-center justify-end">
            <div
              className="w-full rounded-t bg-violet-400 transition-colors group-hover:bg-violet-600"
              style={{ height: `${Math.max(d.credits_micro > 0 ? 4 : 0, h)}%` }}
            />
            {/* tooltip */}
            <div className="pointer-events-none absolute bottom-full mb-1 hidden whitespace-nowrap rounded bg-gray-800 px-2 py-1 text-[10px] text-white group-hover:block">
              {mmdd(d.day)} · {credits(d.credits_micro)} 积分 · {int(d.task_count)} 次
            </div>
          </div>
        );
      })}
    </div>
  );
}
