<script lang="ts">
	import { page } from '$app/state';
	import { api, type UsageReport, type UsageBreakdownRow } from '$lib/api';
	import { session } from '$lib/session';
	import { resolveOrg } from '$lib/org';
	import {
		fmtCost,
		fmtDateOnly,
		fmtNum,
		fmtQuantity,
		fmtTokens,
		usageKindLabel,
	} from '$lib/format';
	import PageHeader from '$lib/components/PageHeader.svelte';
	import StatCard from '$lib/components/StatCard.svelte';
	import LoadingState from '$lib/components/LoadingState.svelte';
	import ErrorBanner from '$lib/components/ErrorBanner.svelte';
	import EmptyState from '$lib/components/EmptyState.svelte';

	const org = $derived(resolveOrg($session.me, page.url.search));
	const slug = $derived(org?.slug ?? '');

	let usage = $state<UsageReport | null>(null);
	let loading = $state(true);
	let error = $state<string | null>(null);
	let from = $state('');
	let to = $state('');

	function toIsoStart(dateLocal: string): string | undefined {
		if (!dateLocal) return undefined;
		const d = new Date(`${dateLocal}T00:00:00`);
		return Number.isNaN(d.getTime()) ? undefined : d.toISOString();
	}

	function toIsoEnd(dateLocal: string): string | undefined {
		if (!dateLocal) return undefined;
		const d = new Date(`${dateLocal}T23:59:59.999`);
		return Number.isNaN(d.getTime()) ? undefined : d.toISOString();
	}

	async function load() {
		if (!slug) return;
		loading = true;
		error = null;
		try {
			usage = await api.usage(slug, {
				...(toIsoStart(from) !== undefined ? { from: toIsoStart(from) } : {}),
				...(toIsoEnd(to) !== undefined ? { to: toIsoEnd(to) } : {}),
			});
		} catch (err) {
			error = err instanceof Error ? err.message : String(err);
		} finally {
			loading = false;
		}
	}

	function clearRange() {
		from = '';
		to = '';
		void load();
	}

	function sourceLabel(row: UsageBreakdownRow): string {
		if (row.capabilityId) return row.capabilityId;
		if (row.model) return row.model;
		return '—';
	}

	function meterCell(row: UsageBreakdownRow): string {
		if (row.unit) return fmtQuantity(row.quantity, row.unit);
		if (row.inputTokens > 0 || row.outputTokens > 0) return fmtTokens(row.inputTokens, row.outputTokens);
		return '—';
	}

	function meterHint(row: UsageBreakdownRow): string {
		if (row.unit) return '非 token 计量';
		if (row.inputTokens > 0 || row.outputTokens > 0) return 'in / out tokens';
		return '无计量';
	}

	$effect(() => {
		if (slug) void load();
	});
</script>

{#if loading && !usage}
	<LoadingState />
{:else if error && !usage}
	<ErrorBanner message={error} onretry={load} />
{:else if usage}
	<PageHeader
		title="用量报告"
		description="按 UsageFact 分账：模型完成与外部能力（PDF→MD、ASR 等）分开汇总。缺失成本计为未知，不为 0。"
	/>

	<div class="saas-card-pad mb-6">
		<div class="flex flex-wrap items-end gap-3">
			<div>
				<label class="saas-label" for="usage-from">从</label>
				<input id="usage-from" class="saas-input" type="date" bind:value={from} />
			</div>
			<div>
				<label class="saas-label" for="usage-to">到</label>
				<input id="usage-to" class="saas-input" type="date" bind:value={to} />
			</div>
			<button class="saas-btn-primary py-1.5! text-sm" type="button" onclick={load} disabled={loading}>
				{loading ? '加载中…' : '应用筛选'}
			</button>
			<button class="saas-btn-secondary py-1.5! text-sm" type="button" onclick={clearRange} disabled={loading}>
				清除
			</button>
			{#if usage.from || usage.to}
				<p class="saas-muted grow text-right text-xs">
					窗口：
					{usage.from ? fmtDateOnly(usage.from) : '—'}
					→
					{usage.to ? fmtDateOnly(usage.to) : '—'}
				</p>
			{/if}
		</div>
		{#if error}
			<p class="mt-3 text-sm text-error-700">{error}</p>
		{/if}
	</div>

	<div class="mb-6 grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
		<StatCard label="运行总数" value={fmtNum(usage.totals.runCount)} />
		<StatCard
			label="有成本 / 无成本"
			value={`${fmtNum(usage.totals.runsWithCost)} / ${fmtNum(usage.totals.runsWithoutCost)}`}
			hint="无成本 = 成本未知，不是 $0"
		/>
		<StatCard label="成本 (USD)" value={fmtCost(usage.totals.costUsd)} hint="仅汇总已知 costUsd" />
		<StatCard label="输入 tokens" value={fmtNum(usage.totals.inputTokens)} hint="主要来自模型完成" />
		<StatCard label="输出 tokens" value={fmtNum(usage.totals.outputTokens)} hint="主要来自模型完成" />
		<StatCard
			label="分账条目"
			value={fmtNum(usage.breakdown.reduce((n, b) => n + b.factCount, 0))}
			hint={`${fmtNum(usage.breakdown.length)} 个分项`}
		/>
	</div>

	<div class="saas-card overflow-hidden mb-6">
		<div class="border-b border-surface-200 px-5 py-3">
			<h3 class="text-sm font-semibold text-surface-800">按来源分账</h3>
			<p class="saas-muted mt-0.5 text-xs">
				kind × provider × model/capability。外部能力显示页数/秒等计量，不与 tokens 混排。
			</p>
		</div>
		{#if usage.breakdown.length === 0}
			<EmptyState title="暂无用量事实" description="跑过智能体后，模型与外部能力消费会出现在此。" />
		{:else}
			<div class="overflow-x-auto">
				<table class="data-table">
					<thead>
						<tr>
							<th>类型</th>
							<th>供应方</th>
							<th>模型 / 能力</th>
							<th>次数</th>
							<th>计量</th>
							<th>有成本 / 未知</th>
							<th>成本</th>
						</tr>
					</thead>
					<tbody>
						{#each usage.breakdown as row}
							<tr>
								<td>
									<span
										class={row.kind === 'external_capability'
											? 'saas-badge-primary'
											: row.kind === 'model_completion'
												? 'saas-badge-success'
												: 'saas-badge-primary'}
									>
										{usageKindLabel(row.kind)}
									</span>
								</td>
								<td class="font-mono text-xs">{row.provider}</td>
								<td class="font-mono text-xs">{sourceLabel(row)}</td>
								<td class="tabular-nums">{fmtNum(row.factCount)}</td>
								<td class="tabular-nums">
									<div>{meterCell(row)}</div>
									<div class="text-[11px] text-surface-600">{meterHint(row)}</div>
								</td>
								<td class="tabular-nums text-surface-700">
									{fmtNum(row.factsWithCost)} / {fmtNum(row.factsWithoutCost)}
								</td>
								<td class="tabular-nums font-medium">{fmtCost(row.costUsd)}</td>
							</tr>
						{/each}
					</tbody>
				</table>
			</div>
		{/if}
	</div>

	<div class="saas-card overflow-hidden">
		<div class="border-b border-surface-200 px-5 py-3">
			<h3 class="text-sm font-semibold text-surface-800">按项目</h3>
			<p class="saas-muted mt-0.5 text-xs">项目仍是权限边界；行内成本已含该项目全部 fact 类型。</p>
		</div>
		{#if usage.projects.length === 0}
			<EmptyState title="暂无项目" description="创建项目并触发智能体后会出现用量。" />
		{:else}
			<div class="overflow-x-auto">
				<table class="data-table">
					<thead>
						<tr>
							<th>项目</th>
							<th>运行</th>
							<th>有成本 / 未知</th>
							<th>in / out tokens</th>
							<th>成本</th>
							<th></th>
						</tr>
					</thead>
					<tbody>
						{#each usage.projects as p}
							<tr>
								<td class="font-medium">{p.projectName}</td>
								<td class="tabular-nums">{fmtNum(p.runCount)}</td>
								<td class="tabular-nums text-surface-700">
									{fmtNum(p.runsWithCost)} / {fmtNum(p.runsWithoutCost)}
								</td>
								<td class="tabular-nums text-surface-600">{fmtTokens(p.inputTokens, p.outputTokens)}</td>
								<td class="tabular-nums">{fmtCost(p.costUsd)}</td>
								<td class="text-right">
									<a class="text-sm text-primary-700 hover:underline" href={`/admin/projects/${p.projectId}`}>
										查看项目
									</a>
								</td>
							</tr>
						{/each}
					</tbody>
				</table>
			</div>
		{/if}
	</div>
{/if}
