<script lang="ts">
	import * as Card from '$lib/components/ui/card';
	import { TrendingUp, TrendingDown, Minus, LineChart } from 'lucide-svelte';
	import type { ChartDataPoint } from '$lib/api/dashboard/types';
	import { onDestroy, tick } from 'svelte';
	import { m } from '$lib/i18n/messages';

	interface Props {
		monthlyData: ChartDataPoint[];
		class?: string;
	}

	let { monthlyData, class: cls = '' }: Props = $props();

	let total    = $derived(monthlyData.reduce((sum, d) => sum + d.value, 0));
	let average  = $derived(monthlyData.length > 0 ? Math.round(total / monthlyData.length) : 0);
	let maxValue = $derived(Math.max(...monthlyData.map((d) => d.value), 1));

	// Trend: compare last two months
	let trendPct = $derived(() => {
		if (monthlyData.length < 2) return 0;
		const last = monthlyData[monthlyData.length - 1].value;
		const prev = monthlyData[monthlyData.length - 2].value;
		if (prev === 0) return 0;
		return Math.round(((last - prev) / prev) * 100);
	});

	let canvas: HTMLCanvasElement | undefined = $state();
	let chartInstance: any;

	async function buildChart() {
		if (!canvas || monthlyData.length < 2) return;

		const {
			Chart,
			LineController,
			LineElement, PointElement,
			CategoryScale, LinearScale,
			Tooltip, Filler
		} = await import('chart.js');

		Chart.register(LineController, LineElement, PointElement, CategoryScale, LinearScale, Tooltip, Filler);

		chartInstance?.destroy();

		// Blue palette
		const blue        = 'rgb(59, 130, 246)';    // blue-500
		const blueDark    = 'rgb(37, 99, 235)';     // blue-600
		const blueLight   = 'rgba(59, 130, 246, 0.12)';
		const blueMid     = 'rgba(59, 130, 246, 0.5)';
		const muted       = '#94a3b8';               // slate-400
		const gridColor   = 'rgba(148, 163, 184, 0.12)';
		const foreground  = '#0f172a';               // slate-900
		const popover     = '#ffffff';

		const ctx = canvas.getContext('2d')!;
		const h   = canvas.clientHeight || 260;

		// Gradient fill under the area
		const areaGrad = ctx.createLinearGradient(0, 0, 0, h);
		areaGrad.addColorStop(0,   blueMid);
		areaGrad.addColorStop(0.6, blueLight);
		areaGrad.addColorStop(1,   'rgba(59, 130, 246, 0)');

		chartInstance = new Chart(canvas, {
			type: 'line',
			data: {
				labels: monthlyData.map((d) => d.label),
				datasets: [
					{
						label: m.dashboard_operations(),
						data: monthlyData.map((d) => d.value),
						borderColor: blue,
						borderWidth: 2.5,
						pointBackgroundColor: blueDark,
						pointBorderColor: popover,
						pointBorderWidth: 2.5,
						pointRadius: 5,
						pointHoverRadius: 7,
						pointHoverBorderWidth: 2.5,
						pointHoverBackgroundColor: blueDark,
						pointHoverBorderColor: popover,
						tension: 0.45,
						fill: true,
						backgroundColor: areaGrad
					}
				]
			},
			options: {
				responsive: true,
				maintainAspectRatio: false,
				animation: { duration: 800, easing: 'easeOutCubic' },
				interaction: { mode: 'index', intersect: false },
				plugins: {
					legend: { display: false },
					tooltip: {
						backgroundColor: popover,
						titleColor: foreground,
						titleFont: { weight: 'bold', size: 12 },
						bodyColor: muted,
						borderColor: 'rgba(59,130,246,0.25)',
						borderWidth: 1,
						padding: { x: 14, y: 10 },
						cornerRadius: 10,
						boxPadding: 4,
						callbacks: {
							label: (ctx: any) => `  ${Number(ctx.raw).toLocaleString()} ${m.dashboard_operations()}`
						}
					}
				},
				scales: {
					x: {
						grid: { display: false },
						border: { display: false },
						ticks: { color: muted, font: { size: 11 }, maxRotation: 0 }
					},
					y: {
						beginAtZero: true,
						border: { display: false, dash: [4, 4] },
						grid: { color: gridColor },
						ticks: {
							color: muted,
							font: { size: 11 },
							maxTicksLimit: 5,
							callback: (v: any) => Number(v).toLocaleString()
						}
					}
				}
			} as any
		} as any);
	}

	onDestroy(() => { chartInstance?.destroy(); });

	$effect(() => {
		const data = monthlyData;
		const el   = canvas;
		if (el && data.length >= 2) {
			tick().then(() => buildChart());
		}
	});
</script>

<Card.Root class={cls}>
	<Card.Header class="pb-0">
		<div class="flex items-start justify-between">
			<div>
				<Card.Title class="flex items-center gap-2 text-base">
					<LineChart class="h-4 w-4 text-blue-500" />
					{m.dashboard_operations_trend()}
				</Card.Title>
				<Card.Description class="mt-1">{m.dashboard_monthly_evolution()}</Card.Description>
			</div>

			{#if monthlyData.length >= 2}
				{@const pct = trendPct()}
				<div class="flex items-center gap-1 rounded-md px-2 py-1 text-xs font-medium
					{pct > 0 ? 'bg-green-50 text-green-600' : pct < 0 ? 'bg-red-50 text-red-600' : 'bg-muted text-muted-foreground'}">
					{#if pct > 0}
						<TrendingUp class="h-3 w-3" />+{pct}%
					{:else if pct < 0}
						<TrendingDown class="h-3 w-3" />{pct}%
					{:else}
						<Minus class="h-3 w-3" />0%
					{/if}
					<span class="opacity-60 ml-0.5">vs {m.dashboard_previous_month()}</span>
				</div>
			{/if}
		</div>
	</Card.Header>

	<Card.Content class="pt-4 pb-5">
		{#if monthlyData.length === 0}
			<div class="flex flex-col items-center justify-center py-14 text-muted-foreground gap-3">
				<div class="rounded-full bg-blue-50 p-4">
					<LineChart class="h-8 w-8 text-blue-300" />
				</div>
				<div class="text-center">
					<p class="text-sm font-medium">{m.dashboard_no_data_available()}</p>
					<p class="text-xs text-muted-foreground/70 mt-0.5">{m.dashboard_data_will_appear_here()}</p>
				</div>
			</div>
		{:else if monthlyData.length === 1}
			<div class="flex flex-col items-center justify-center py-8 gap-5">
				<div class="text-center">
					<div class="text-5xl font-bold text-blue-600 tabular-nums">{monthlyData[0].value.toLocaleString()}</div>
					<div class="text-sm text-muted-foreground mt-2">
						{m.dashboard_operations_in()} <span class="font-semibold text-foreground">{monthlyData[0].label}</span>
					</div>
				</div>
				<div class="flex items-center gap-2 text-xs text-muted-foreground bg-blue-50 text-blue-600 rounded-full px-4 py-2">
					<LineChart class="h-3.5 w-3.5 shrink-0" />
					{m.dashboard_more_than_one_month_needed()}
				</div>
			</div>
		{:else}
			<!-- Chart -->
			<div class="h-56">
				<canvas bind:this={canvas}></canvas>
			</div>

			<!-- Stats row -->
			<div class="grid grid-cols-3 divide-x border-t mt-4 pt-4">
				<div class="px-4 first:pl-0 last:pr-0">
					<div class="text-lg font-semibold tabular-nums text-blue-600">{total.toLocaleString()}</div>
					<div class="text-xs text-muted-foreground mt-0.5">{m.dashboard_total()}</div>
				</div>
				<div class="px-4">
					<div class="text-lg font-semibold tabular-nums">{average.toLocaleString()}</div>
					<div class="text-xs text-muted-foreground mt-0.5">{m.dashboard_average_per_month()}</div>
				</div>
				<div class="px-4 text-right">
					<div class="text-lg font-semibold tabular-nums">{maxValue.toLocaleString()}</div>
					<div class="text-xs text-muted-foreground mt-0.5">{m.dashboard_maximum()}</div>
				</div>
			</div>
		{/if}
	</Card.Content>
</Card.Root>
