<script lang="ts">
	import { useConvexClient } from 'convex-svelte';
	import { api } from '@sgse-app/backend/convex/_generated/api';
	import { onMount } from 'svelte';
	import { resolve } from '$app/paths';
	import { BarChart3, Info, DollarSign, Users } from 'lucide-svelte';

	const client = useConvexClient();

	type Row = { _id: string; nome: string; valor: number; count: number };
	let rows: Array<Row> = $state<Array<Row>>([]);
	let isLoading = $state(true);
	let notice = $state<{ kind: 'error' | 'success'; text: string } | null>(null);
	let containerWidth = $state(1200);

	onMount(async () => {
		try {
			const simbolos = await client.query(api.simbolos.getAll, {});
			const funcionarios = await client.query(api.funcionarios.getAll, {});

			const counts: Record<string, number> = {};
			for (const f of funcionarios) {
				const sId = String(f.simboloId);
				counts[sId] = (counts[sId] ?? 0) + 1;
			}

			rows = simbolos.map((s) => ({
				_id: String(s._id),
				nome: s.nome,
				valor: Number(s.valor || 0),
				count: counts[String(s._id)] ?? 0
			}));
		} catch (e) {
			if (e instanceof Error) {
				notice = { kind: 'error', text: e.message };
			} else {
				notice = { kind: 'error', text: 'Falha ao carregar dados de relatórios.' };
			}
		} finally {
			isLoading = false;
		}
	});

	// Dimensões responsivas
	$effect(() => {
		const updateSize = () => {
			const container = document.querySelector('.chart-container');
			if (container) {
				containerWidth = Math.min(container.clientWidth - 32, 1200);
			}
		};

		updateSize();
		window.addEventListener('resize', updateSize);

		return () => window.removeEventListener('resize', updateSize);
	});

	const chartHeight = 350;
	const padding = { top: 20, right: 20, bottom: 80, left: 70 };

	let chartWidth = $derived(containerWidth);

	function getMax<T>(arr: Array<T>, sel: (t: T) => number): number {
		let m = 0;
		for (const a of arr) m = Math.max(m, sel(a));
		return m;
	}

	function scaleY(v: number, max: number): number {
		if (max <= 0) return 0;
		const innerH = chartHeight - padding.top - padding.bottom;
		return (v / max) * innerH;
	}

	function getX(i: number, n: number): number {
		const innerW = chartWidth - padding.left - padding.right;
		return padding.left + (innerW / (n - 1)) * i;
	}

	function createAreaPath(data: Array<Row>, getValue: (r: Row) => number, max: number): string {
		if (data.length === 0) return '';
		const n = data.length;
		let path = `M ${getX(0, n)} ${chartHeight - padding.bottom}`;

		for (let i = 0; i < n; i++) {
			const x = getX(i, n);
			const y = chartHeight - padding.bottom - scaleY(getValue(data[i]), max);
			path += ` L ${x} ${y}`;
		}

		path += ` L ${getX(n - 1, n)} ${chartHeight - padding.bottom}`;
		path += ' Z';
		return path;
	}
</script>

<div class="container mx-auto max-w-7xl px-4 py-6">
	<!-- Breadcrumb -->
	<div class="breadcrumbs mb-4 text-sm">
		<ul>
			<li><a href={resolve('/')} class="hover:text-primary">Dashboard</a></li>
			<li>
				<a href={resolve('/recursos-humanos')} class="hover:text-primary">Recursos Humanos</a>
			</li>
			<li>
				<a href={resolve('/recursos-humanos/funcionarios')} class="hover:text-primary"
					>Funcionários</a
				>
			</li>
			<li class="text-primary font-semibold">Relatórios</li>
		</ul>
	</div>

	<!-- Header -->
	<div class="mb-8 flex items-center gap-4">
		<div class="bg-primary/10 rounded-xl p-3">
			<BarChart3 class="text-primary h-8 w-8" strokeWidth={2} />
		</div>
		<div>
			<h1 class="text-base-content text-3xl font-bold">Relatórios de Funcionários</h1>
			<p class="text-base-content/60 mt-1">
				Análise de distribuição de salários e funcionários por símbolo
			</p>
		</div>
	</div>

	{#if notice}
		<div
			class="alert mb-6"
			class:alert-error={notice.kind === 'error'}
			class:alert-success={notice.kind === 'success'}
		>
			<Info class="h-6 w-6 shrink-0 stroke-current" strokeWidth={2} />
			<span>{notice.text}</span>
		</div>
	{/if}

	{#if isLoading}
		<div class="flex items-center justify-center py-20">
			<span class="loading loading-spinner loading-lg text-primary"></span>
		</div>
	{:else}
		<div class="chart-container space-y-6">
			<!-- Gráfico 1: Símbolo x Salário (Valor) - Layer Chart -->
			<div
				class="card bg-base-100 border-base-300 border shadow-lg transition-shadow hover:shadow-xl"
			>
				<div class="card-body p-6">
					<div class="mb-6 flex items-center gap-3">
						<div class="bg-primary/10 rounded-lg p-2.5">
							<DollarSign class="text-primary h-6 w-6" strokeWidth={2} />
						</div>
						<div class="flex-1">
							<h3 class="text-base-content text-lg font-bold">
								Distribuição de Salários por Símbolo
							</h3>
							<p class="text-base-content/60 mt-0.5 text-sm">
								Valores dos símbolos cadastrados no sistema
							</p>
						</div>
					</div>
					<div class="bg-base-200/30 w-full overflow-x-auto rounded-xl p-4">
						<svg
							width={chartWidth}
							height={chartHeight}
							role="img"
							aria-label="Gráfico de área: salário por símbolo"
						>
							{#if rows.length === 0}
								<text x="16" y="32" class="opacity-60">Sem dados</text>
							{:else}
								{@const max = getMax(rows, (r) => r.valor)}

								<!-- Grid lines -->
								{#each [0, 1, 2, 3, 4, 5] as t (t)}
									{@const val = Math.round((max / 5) * t)}
									{@const y = chartHeight - padding.bottom - scaleY(val, max)}
									<line
										x1={padding.left}
										y1={y}
										x2={chartWidth - padding.right}
										y2={y}
										stroke="currentColor"
										stroke-opacity="0.1"
										stroke-dasharray="4,4"
									/>
									<text
										x={padding.left - 8}
										y={y + 4}
										text-anchor="end"
										class="text-[10px] opacity-70">{`R$ ${val.toLocaleString('pt-BR')}`}</text
									>
								{/each}

								<!-- Eixos -->
								<line
									x1={padding.left}
									y1={chartHeight - padding.bottom}
									x2={chartWidth - padding.right}
									y2={chartHeight - padding.bottom}
									stroke="currentColor"
									stroke-opacity="0.3"
									stroke-width="2"
								/>
								<line
									x1={padding.left}
									y1={padding.top}
									x2={padding.left}
									y2={chartHeight - padding.bottom}
									stroke="currentColor"
									stroke-opacity="0.3"
									stroke-width="2"
								/>

								<!-- Area fill (camada) -->
								<path
									d={createAreaPath(rows, (r) => r.valor, max)}
									fill="url(#gradient-salary)"
									opacity="0.7"
								/>

								<!-- Line -->
								<polyline
									points={rows
										.map((r, i) => {
											const x = getX(i, rows.length);
											const y = chartHeight - padding.bottom - scaleY(r.valor, max);
											return `${x},${y}`;
										})
										.join(' ')}
									fill="none"
									stroke="rgb(59, 130, 246)"
									stroke-width="3"
								/>

								<!-- Data points -->
								{#each rows as r, i (r._id)}
									{@const x = getX(i, rows.length)}
									{@const y = chartHeight - padding.bottom - scaleY(r.valor, max)}
									<circle
										cx={x}
										cy={y}
										r="5"
										fill="rgb(59, 130, 246)"
										stroke="white"
										stroke-width="2"
									/>
									<text
										{x}
										y={y - 12}
										text-anchor="middle"
										class="fill-primary text-[10px] font-semibold"
									>
										{`R$ ${r.valor.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}`}
									</text>
								{/each}

								<!-- Eixo X labels -->
								{#each rows as r, i (r._id)}
									{@const x = getX(i, rows.length)}
									<foreignObject
										x={x - 40}
										y={chartHeight - padding.bottom + 15}
										width="80"
										height="70"
									>
										<div class="flex items-center justify-center text-center">
											<span
												class="text-base-content/80 text-[11px] leading-tight font-medium"
												style="word-wrap: break-word; hyphens: auto;"
											>
												{r.nome}
											</span>
										</div>
									</foreignObject>
								{/each}

								<!-- Gradient definition -->
								<defs>
									<linearGradient id="gradient-salary" x1="0%" y1="0%" x2="0%" y2="100%">
										<stop offset="0%" style="stop-color:rgb(59, 130, 246);stop-opacity:0.8" />
										<stop offset="100%" style="stop-color:rgb(59, 130, 246);stop-opacity:0.1" />
									</linearGradient>
								</defs>
							{/if}
						</svg>
					</div>
				</div>
			</div>

			<!-- Gráfico 2: Quantidade de Funcionários por Símbolo - Layer Chart -->
			<div
				class="card bg-base-100 border-base-300 border shadow-lg transition-shadow hover:shadow-xl"
			>
				<div class="card-body p-6">
					<div class="mb-6 flex items-center gap-3">
						<div class="bg-secondary/10 rounded-lg p-2.5">
							<Users class="text-secondary h-6 w-6" strokeWidth={2} />
						</div>
						<div class="flex-1">
							<h3 class="text-base-content text-lg font-bold">
								Distribuição de Funcionários por Símbolo
							</h3>
							<p class="text-base-content/60 mt-0.5 text-sm">
								Quantidade de funcionários alocados em cada símbolo
							</p>
						</div>
					</div>
					<div class="bg-base-200/30 w-full overflow-x-auto rounded-xl p-4">
						<svg
							width={chartWidth}
							height={chartHeight}
							role="img"
							aria-label="Gráfico de área: quantidade por símbolo"
						>
							{#if rows.length === 0}
								<text x="16" y="32" class="opacity-60">Sem dados</text>
							{:else}
								{@const maxC = getMax(rows, (r) => r.count)}

								<!-- Grid lines -->
								{#each [0, 1, 2, 3, 4, 5] as t (t)}
									{@const val = Math.round((maxC / 5) * t)}
									{@const y = chartHeight - padding.bottom - scaleY(val, Math.max(1, maxC))}
									<line
										x1={padding.left}
										y1={y}
										x2={chartWidth - padding.right}
										y2={y}
										stroke="currentColor"
										stroke-opacity="0.1"
										stroke-dasharray="4,4"
									/>
									<text
										x={padding.left - 6}
										y={y + 4}
										text-anchor="end"
										class="text-[10px] opacity-70">{val}</text
									>
								{/each}

								<!-- Eixos -->
								<line
									x1={padding.left}
									y1={chartHeight - padding.bottom}
									x2={chartWidth - padding.right}
									y2={chartHeight - padding.bottom}
									stroke="currentColor"
									stroke-opacity="0.3"
									stroke-width="2"
								/>
								<line
									x1={padding.left}
									y1={padding.top}
									x2={padding.left}
									y2={chartHeight - padding.bottom}
									stroke="currentColor"
									stroke-opacity="0.3"
									stroke-width="2"
								/>

								<!-- Area fill (camada) -->
								<path
									d={createAreaPath(rows, (r) => r.count, Math.max(1, maxC))}
									fill="url(#gradient-count)"
									opacity="0.7"
								/>

								<!-- Line -->
								<polyline
									points={rows
										.map((r, i) => {
											const x = getX(i, rows.length);
											const y = chartHeight - padding.bottom - scaleY(r.count, Math.max(1, maxC));
											return `${x},${y}`;
										})
										.join(' ')}
									fill="none"
									stroke="rgb(236, 72, 153)"
									stroke-width="3"
								/>

								<!-- Data points -->
								{#each rows as r, i (r._id)}
									{@const x = getX(i, rows.length)}
									{@const y = chartHeight - padding.bottom - scaleY(r.count, Math.max(1, maxC))}
									<circle
										cx={x}
										cy={y}
										r="5"
										fill="rgb(236, 72, 153)"
										stroke="white"
										stroke-width="2"
									/>
									<text
										{x}
										y={y - 12}
										text-anchor="middle"
										class="fill-secondary text-[10px] font-semibold"
									>
										{r.count}
									</text>
								{/each}

								<!-- Eixo X labels -->
								{#each rows as r, i (r._id)}
									{@const x = getX(i, rows.length)}
									<foreignObject
										x={x - 40}
										y={chartHeight - padding.bottom + 15}
										width="80"
										height="70"
									>
										<div class="flex items-center justify-center text-center">
											<span
												class="text-base-content/80 text-[11px] leading-tight font-medium"
												style="word-wrap: break-word; hyphens: auto;"
											>
												{r.nome}
											</span>
										</div>
									</foreignObject>
								{/each}

								<!-- Gradient definition -->
								<defs>
									<linearGradient id="gradient-count" x1="0%" y1="0%" x2="0%" y2="100%">
										<stop offset="0%" style="stop-color:rgb(236, 72, 153);stop-opacity:0.8" />
										<stop offset="100%" style="stop-color:rgb(236, 72, 153);stop-opacity:0.1" />
									</linearGradient>
								</defs>
							{/if}
						</svg>
					</div>
				</div>
			</div>

			<!-- Tabela Resumo -->
			<div class="card bg-base-100 border-base-300 border shadow-lg">
				<div class="card-body p-6">
					<div class="mb-6 flex items-center gap-3">
						<div class="bg-accent/10 rounded-lg p-2.5">
							<svg
								xmlns="http://www.w3.org/2000/svg"
								class="text-accent h-6 w-6"
								fill="none"
								viewBox="0 0 24 24"
								stroke="currentColor"
							>
								<path
									stroke-linecap="round"
									stroke-linejoin="round"
									stroke-width="2"
									d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"
								/>
							</svg>
						</div>
						<div class="flex-1">
							<h3 class="text-base-content text-lg font-bold">
								Tabela Resumo - Símbolos e Funcionários
							</h3>
							<p class="text-base-content/60 mt-0.5 text-sm">
								Visão detalhada dos dados apresentados nos gráficos
							</p>
						</div>
					</div>

					<div class="overflow-x-auto">
						<table class="table-zebra table">
							<thead>
								<tr>
									<th class="bg-base-200">Símbolo</th>
									<th class="bg-base-200 text-right">Valor (R$)</th>
									<th class="bg-base-200 text-right">Funcionários</th>
									<th class="bg-base-200 text-right">Total (R$)</th>
								</tr>
							</thead>
							<tbody>
								{#if rows.length === 0}
									<tr>
										<td colspan="4" class="text-base-content/60 py-8 text-center"
											>Nenhum dado disponível</td
										>
									</tr>
								{:else}
									{#each rows as row (row._id)}
										<tr class="hover">
											<td class="font-semibold">{row.nome}</td>
											<td class="text-right font-mono">
												{row.valor.toLocaleString('pt-BR', {
													minimumFractionDigits: 2,
													maximumFractionDigits: 2
												})}
											</td>
											<td class="text-right">
												<span class="badge badge-primary badge-outline">{row.count}</span>
											</td>
											<td class="text-primary text-right font-mono font-semibold">
												{(row.valor * row.count).toLocaleString('pt-BR', {
													minimumFractionDigits: 2,
													maximumFractionDigits: 2
												})}
											</td>
										</tr>
									{/each}
									<!-- Total Geral -->
									<tr class="bg-base-200 border-base-300 border-t-2 font-bold">
										<td>TOTAL GERAL</td>
										<td class="text-right font-mono">
											{rows
												.reduce((sum, r) => sum + r.valor, 0)
												.toLocaleString('pt-BR', {
													minimumFractionDigits: 2,
													maximumFractionDigits: 2
												})}
										</td>
										<td class="text-right">
											<span class="badge badge-primary"
												>{rows.reduce((sum, r) => sum + r.count, 0)}</span
											>
										</td>
										<td class="text-primary text-right font-mono text-lg">
											{rows
												.reduce((sum, r) => sum + r.valor * r.count, 0)
												.toLocaleString('pt-BR', {
													minimumFractionDigits: 2,
													maximumFractionDigits: 2
												})}
										</td>
									</tr>
								{/if}
							</tbody>
						</table>
					</div>
				</div>
			</div>
		</div>
	{/if}
</div>
