<script lang="ts">
	import { Card, Spinner } from '$lib/components';
	import { data } from '$lib/stores/data.svelte';
	import { navbarExtra } from '$lib/stores/navbar-extra.svelte';
	import { onDestroy } from 'svelte';
	import type { UsageDayEntry } from '$lib/types';
	import {
		Chart, BarController, DoughnutController,
		CategoryScale, LinearScale, BarElement, ArcElement,
		Tooltip, Legend
	} from 'chart.js';

	Chart.register(BarController, DoughnutController, CategoryScale, LinearScale, BarElement, ArcElement, Tooltip, Legend);

	// ── Formatters ────────────────────────────────────────────────────────────
	function formatDuration(ms: number): string {
		if (ms < 1000) return `${ms}ms`;
		const s = Math.floor(ms / 1000);
		const h = Math.floor(s / 3600), m = Math.floor((s % 3600) / 60), sec = s % 60;
		if (h > 0) return `${h}h ${m}m`;
		if (m > 0) return `${m}m ${sec}s`;
		return `${sec}s`;
	}
	function fmtNum(n: number): string { return (n ?? 0).toLocaleString(); }
	function fmtTok(n: number): string {
		if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
		if (n >= 1_000) return `${Math.round(n / 1_000)}k`;
		return String(n);
	}
	function shortDate(d: string): string {
		return new Date(d + 'T12:00:00Z').toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
	}

	// ── Day selector ──────────────────────────────────────────────────────────
	let days = $state(data.usageDays);
	function selectDays(d: number) { days = d; data.refetchUsage(d); }
	$effect(() => { navbarExtra.set(daySelector); return () => navbarExtra.set(null); });
	onDestroy(() => navbarExtra.set(null));

	// ── Palette ───────────────────────────────────────────────────────────────
	const PALETTE = ['#6366f1','#34d399','#fbbf24','#fb7185','#22d3ee','#a78bfa','#f97316','#ec4899','#84cc16','#06b6d4'];

	// ── Derived totals ────────────────────────────────────────────────────────
	let totals = $derived(data.usage?.totals ?? []);
	let daily  = $derived(data.usage?.daily  ?? []);

	let grandRequests = $derived(totals.reduce((s, t) => s + t.requests, 0));
	let grandDuration = $derived(totals.reduce((s, t) => s + t.duration_ms, 0));
	let grandInput    = $derived(totals.reduce((s, t) => s + t.input_tokens, 0));
	let grandOutput   = $derived(totals.reduce((s, t) => s + t.output_tokens, 0));

	let sortedTotals  = $derived([...totals].sort((a, b) => b.requests - a.requests));
	let dates         = $derived([...new Set(daily.map((d: UsageDayEntry) => d.date))].sort());
	let tenantIds     = $derived([...new Set(daily.map((d: UsageDayEntry) => d.tenant_id))].sort());
	let colorMap      = $derived(Object.fromEntries(tenantIds.map((id, i) => [id, PALETTE[i % PALETTE.length]])));

	let reqByDateTenant = $derived.by(() => {
		const m: Record<string, Record<string, number>> = {};
		for (const row of daily) {
			if (!m[row.date]) m[row.date] = {};
			m[row.date][row.tenant_id] = (m[row.date][row.tenant_id] ?? 0) + row.requests;
		}
		return m;
	});

	let tokByDate = $derived.by(() => {
		const m: Record<string, { inp: number; out: number }> = {};
		for (const row of daily) {
			if (!m[row.date]) m[row.date] = { inp: 0, out: 0 };
			m[row.date].inp += row.input_tokens;
			m[row.date].out += row.output_tokens;
		}
		return m;
	});

	// ── Canvas refs ───────────────────────────────────────────────────────────
	let reqCanvas   = $state<HTMLCanvasElement | undefined>();
	let tokCanvas   = $state<HTMLCanvasElement | undefined>();
	let donutCanvas = $state<HTMLCanvasElement | undefined>();

	let reqChart:   Chart | null = null;
	let tokChart:   Chart | null = null;
	let donutChart: Chart | null = null;

	// Center text plugin for doughnut
	const centerTextPlugin = {
		id: 'centerText',
		afterDraw(chart: any) {
			if (chart.config.type !== 'doughnut') return;
			const { ctx, chartArea: { top, bottom, left, right } } = chart;
			const total = (chart.data.datasets[0].data as number[]).reduce((a: number, b: number) => a + b, 0);
			const cx = (left + right) / 2, cy = (top + bottom) / 2;
			ctx.save();
			ctx.textAlign = 'center';
			ctx.textBaseline = 'middle';
			ctx.fillStyle = getCssVar('--text-bright');
			ctx.font = 'bold 18px JetBrains Mono, monospace';
			ctx.fillText(fmtNum(total), cx, cy - 8);
			ctx.fillStyle = getCssVar('--text-muted');
			ctx.font = '10px sans-serif';
			ctx.fillText('total requests', cx, cy + 9);
			ctx.restore();
		}
	};

	const CHART_DEFAULTS = {
		font: { family: "'JetBrains Mono', monospace", size: 10 },
	};

	function getCssVar(name: string): string {
		return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
	}

	const commonBarOptions = (tickCallback?: (v: any) => string) => ({
		responsive: true,
		maintainAspectRatio: false,
		animation: { duration: 400 },
		scales: {
			x: {
				stacked: true,
				grid: { display: false },
				ticks: { color: getCssVar('--text-dim'), font: CHART_DEFAULTS.font, maxRotation: 0 },
				border: { color: getCssVar('--border-strong') },
			},
			y: {
				stacked: true,
				beginAtZero: true,
				grid: { color: getCssVar('--border-subtle') },
				ticks: {
					color: getCssVar('--text-dim'),
					font: CHART_DEFAULTS.font,
					...(tickCallback ? { callback: tickCallback } : {}),
				},
				border: { color: 'transparent' },
			},
		},
		plugins: {
			legend: {
				labels: { color: getCssVar('--text-dim'), boxWidth: 10, padding: 14, font: CHART_DEFAULTS.font },
			},
			tooltip: {
				backgroundColor: getCssVar('--surface-2'),
				borderColor: getCssVar('--border'),
				borderWidth: 1,
				titleColor: getCssVar('--text-bright'),
				bodyColor: getCssVar('--text'),
				padding: 10,
				mode: 'index' as const,
				intersect: false,
			},
		},
	});

	$effect(() => {
		const usage = data.usage;
		const rc = reqCanvas, tc = tokCanvas, dc = donutCanvas;
		if (!usage || !rc || !tc || !dc) return;

		const labels = dates.map(shortDate);

		// ── Requests chart ──
		const reqDatasets = tenantIds.map((tid, i) => ({
			label: tid,
			data: dates.map(d => reqByDateTenant[d]?.[tid] ?? 0),
			backgroundColor: PALETTE[i % PALETTE.length] + 'bb',
			borderColor: PALETTE[i % PALETTE.length],
			borderWidth: 0,
			borderRadius: 2,
		}));

		reqChart?.destroy();
		reqChart = new Chart(rc, {
			type: 'bar',
			data: { labels, datasets: reqDatasets },
			options: commonBarOptions(),
		});

		// ── Tokens chart ──
		const tokDatasets = [
			{
				label: 'Input',
				data: dates.map(d => tokByDate[d]?.inp ?? 0),
				backgroundColor: '#6366f1bb',
				borderWidth: 0,
				borderRadius: 2,
			},
			{
				label: 'Output',
				data: dates.map(d => tokByDate[d]?.out ?? 0),
				backgroundColor: '#34d399bb',
				borderWidth: 0,
				borderRadius: 2,
			},
		];

		tokChart?.destroy();
		tokChart = new Chart(tc, {
			type: 'bar',
			data: { labels, datasets: tokDatasets },
			options: commonBarOptions((v: any) => fmtTok(Number(v))),
		});

		// ── Doughnut chart ──
		const donutLabels = sortedTotals.map(t => t.tenant_id);
		const donutData   = sortedTotals.map(t => t.requests);
		const donutColors = sortedTotals.map((_, i) => PALETTE[i % PALETTE.length]);

		donutChart?.destroy();
		donutChart = new Chart(dc, {
			type: 'doughnut',
			data: {
				labels: donutLabels,
				datasets: [{ data: donutData, backgroundColor: donutColors, borderWidth: 0, hoverOffset: 6 }],
			},
			options: {
				responsive: true,
				maintainAspectRatio: false,
				cutout: '62%',
				animation: { duration: 400 },
				plugins: {
					legend: {
						position: 'right',
						labels: { color: '#5c6180', boxWidth: 10, padding: 10, font: CHART_DEFAULTS.font },
					},
					tooltip: {
						backgroundColor: '#151820',
						borderColor: '#2a2f40',
						borderWidth: 1,
						titleColor: '#eef0ff',
						bodyColor: '#c8cce0',
						padding: 10,
						callbacks: {
							label: (ctx: any) => ` ${fmtNum(ctx.raw)} (${((ctx.raw / grandRequests) * 100).toFixed(1)}%)`,
						},
					},
				},
			},
			plugins: [centerTextPlugin],
		});

		return () => {
			reqChart?.destroy();   reqChart   = null;
			tokChart?.destroy();   tokChart   = null;
			donutChart?.destroy(); donutChart = null;
		};
	});
</script>

{#snippet daySelector()}
	<div class="day-selector">
		{#each [7, 14, 30] as d}
			<button class="day-btn" class:active={days === d} onclick={() => selectDays(d)}>{d}d</button>
		{/each}
	</div>
{/snippet}

<div class="page">
	{#if !data.initialLoaded}
		<div class="center"><Spinner /></div>
	{:else if data.usage}
		<!-- Stat cards -->
		<div class="stat-grid">
			<div class="stat-card">
				<div class="stat-label">Requests</div>
				<div class="stat-value">{fmtNum(grandRequests)}</div>
				<div class="stat-sub">{days}-day window</div>
			</div>
			<div class="stat-card">
				<div class="stat-label">Duration</div>
				<div class="stat-value">{formatDuration(grandDuration)}</div>
				<div class="stat-sub">total agent run time</div>
			</div>
			<div class="stat-card">
				<div class="stat-label">Input Tokens</div>
				<div class="stat-value">{fmtTok(grandInput)}</div>
				<div class="stat-sub">prompt + cache</div>
			</div>
			<div class="stat-card">
				<div class="stat-label">Output Tokens</div>
				<div class="stat-value">{fmtTok(grandOutput)}</div>
				<div class="stat-sub">completion tokens</div>
			</div>
		</div>

		<!-- Daily requests chart -->
		<Card title="Daily Requests by Tenant">
			<div class="chart-container" style="height: 240px;">
				<canvas bind:this={reqCanvas}></canvas>
			</div>
		</Card>

		<!-- Tokens + Doughnut row -->
		<div class="chart-row">
			<Card title="Daily Token Usage">
				<div class="chart-container" style="height: 220px;">
					<canvas bind:this={tokCanvas}></canvas>
				</div>
			</Card>
			<Card title="Requests by Tenant">
				<div class="chart-container" style="height: 220px;">
					<canvas bind:this={donutCanvas}></canvas>
				</div>
			</Card>
		</div>

		<!-- Per-tenant table -->
		<Card title="Per-Tenant Totals">
			<div class="table-wrap">
				<table class="usage-table">
					<thead>
						<tr>
							<th>Tenant</th>
							<th class="num">Requests</th>
							<th class="num">Duration</th>
							<th class="num">Input</th>
							<th class="num">Output</th>
							<th class="num">Cache In</th>
							<th class="num">Cache Read</th>
						</tr>
					</thead>
					<tbody>
						{#each sortedTotals as row}
							<tr>
								<td>
									<span class="tenant-cell">
										<span class="tenant-dot" style="background:{colorMap[row.tenant_id] ?? '#888'}"></span>
										<span class="mono">{row.tenant_id}</span>
									</span>
								</td>
								<td class="num">{fmtNum(row.requests)}</td>
								<td class="num">{formatDuration(row.duration_ms)}</td>
								<td class="num">{fmtTok(row.input_tokens)}</td>
								<td class="num">{fmtTok(row.output_tokens)}</td>
								<td class="num muted">{fmtTok(row.cache_creation_tokens)}</td>
								<td class="num muted">{fmtTok(row.cache_read_tokens)}</td>
							</tr>
						{/each}
					</tbody>
				</table>
			</div>
			<div class="mobile-tenant-list">
				{#each sortedTotals as row}
					<div class="mobile-tenant-card">
						<div class="mobile-tenant-name">
							<span class="tenant-dot" style="background:{colorMap[row.tenant_id] ?? '#888'}"></span>
							{row.tenant_id}
						</div>
						<div class="mobile-tenant-stats">
							<div class="mobile-tenant-stat">
								<span class="mobile-tenant-stat-label">Requests</span>
								<span class="mobile-tenant-stat-value">{fmtNum(row.requests)}</span>
							</div>
							<div class="mobile-tenant-stat">
								<span class="mobile-tenant-stat-label">Duration</span>
								<span class="mobile-tenant-stat-value">{formatDuration(row.duration_ms)}</span>
							</div>
							<div class="mobile-tenant-stat">
								<span class="mobile-tenant-stat-label">Input</span>
								<span class="mobile-tenant-stat-value">{fmtTok(row.input_tokens)}</span>
							</div>
							<div class="mobile-tenant-stat">
								<span class="mobile-tenant-stat-label">Output</span>
								<span class="mobile-tenant-stat-value">{fmtTok(row.output_tokens)}</span>
							</div>
						</div>
					</div>
				{/each}
			</div>
		</Card>
	{/if}
</div>

<style>
	.page { display: flex; flex-direction: column; gap: 20px; }
	.center { display: flex; justify-content: center; padding: 60px 0; }

	/* Stat cards */
	.stat-grid {
		display: grid;
		grid-template-columns: repeat(4, 1fr);
		gap: 12px;
	}
	.stat-card {
		background: var(--surface-1);
		border: 1px solid var(--border);
		border-radius: var(--radius-lg);
		padding: 16px 20px;
	}
	.stat-label {
		font-size: var(--font-size-xs);
		color: var(--text-muted);
		text-transform: uppercase;
		letter-spacing: 0.07em;
		font-weight: 600;
		margin-bottom: 8px;
	}
	.stat-value {
		font-size: var(--font-size-2xl);
		font-weight: 700;
		color: var(--text-bright);
		line-height: 1;
		margin-bottom: 5px;
		font-family: var(--font-mono);
	}
	.stat-sub {
		font-size: var(--font-size-xs);
		color: var(--text-muted);
	}

	/* Chart containers */
	.chart-container { position: relative; }
	.chart-row {
		display: grid;
		grid-template-columns: 3fr 2fr;
		gap: 20px;
	}

	/* Table */
	.table-wrap { overflow-x: auto; }
	.usage-table {
		width: 100%;
		border-collapse: collapse;
		font-size: var(--font-size-sm);
	}
	.usage-table th {
		text-align: left;
		padding: 6px 12px;
		color: var(--text-muted);
		font-weight: 500;
		border-bottom: 1px solid var(--border);
		font-size: var(--font-size-xs);
		text-transform: uppercase;
		letter-spacing: 0.05em;
		white-space: nowrap;
	}
	.usage-table td {
		padding: 9px 12px;
		color: var(--text);
		border-bottom: 1px solid var(--border-subtle);
	}
	.usage-table tr:last-child td { border-bottom: none; }
	.usage-table tr:hover td { background: var(--surface-hover); }
	.num { text-align: right; font-family: var(--font-mono); }
	.muted { color: var(--text-muted) !important; }
	.tenant-cell { display: flex; align-items: center; gap: 8px; }
	.tenant-dot { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }
	.mono { font-family: var(--font-mono); }

	/* Day selector */
	.day-selector {
		display: flex;
		border: 1px solid var(--border);
		border-radius: var(--radius);
		overflow: hidden;
	}
	.day-btn {
		padding: 4px 12px;
		background: var(--surface-2);
		border: none;
		color: var(--text-dim);
		font-size: var(--font-size-sm);
		font-family: var(--font-mono);
		cursor: pointer;
		transition: all var(--duration) var(--ease);
	}
	.day-btn:not(:last-child) { border-right: 1px solid var(--border); }
	.day-btn:hover { background: var(--surface-3); color: var(--text); }
	.day-btn.active { background: var(--accent-dim); color: var(--accent); }

	@media (max-width: 900px) {
		.stat-grid { grid-template-columns: 1fr 1fr; }
		.chart-row { grid-template-columns: 1fr; }
	}

	@media (max-width: 768px) {
		.stat-grid { grid-template-columns: 1fr; }
		.stat-card { padding: 12px 14px; }
		.usage-table { display: none; }
		.mobile-tenant-list { display: flex; }
	}

	.mobile-tenant-list {
		display: none;
		flex-direction: column;
	}
	.mobile-tenant-card {
		padding: 14px 16px;
		border-bottom: 1px solid var(--border-subtle);
		display: flex;
		flex-direction: column;
		gap: 6px;
	}
	.mobile-tenant-card:last-child { border-bottom: none; }
	.mobile-tenant-name {
		display: flex;
		align-items: center;
		gap: 8px;
		font-family: var(--font-mono);
		font-size: var(--font-size-sm);
		font-weight: 600;
		color: var(--text-bright);
	}
	.mobile-tenant-stats {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 4px 16px;
		font-size: var(--font-size-xs);
		color: var(--text-dim);
	}
	.mobile-tenant-stat {
		display: flex;
		justify-content: space-between;
		gap: 6px;
	}
	.mobile-tenant-stat-label { color: var(--text-muted); }
	.mobile-tenant-stat-value { font-family: var(--font-mono); color: var(--text); }
</style>
