<script lang="ts">
	import { onMount } from 'svelte';
	import { page } from '$app/state';
	import BudgetModule from '$lib/components/dashboard/BudgetModule.svelte';
	import FitnessModule from '$lib/components/dashboard/FitnessModule.svelte';
	import IssuesModule from '$lib/components/dashboard/IssuesModule.svelte';
	import TaskSlideOver from '$lib/components/dashboard/TaskSlideOver.svelte';

	interface QuickTask {
		id: string;
		title: string;
		startDate?: string;
		dueDate?: string;
		isAllDay?: boolean;
		_projectName: string;
		projectId: string;
		_projectId: string;
	}

	const userName = $derived((page as any).data?.user?.display_name || 'there');

	let inventoryIssueCount = $state(0);
	let inventoryReviewCount = $state(0);
	let budgetUncatCount = $state(0);
	let budgetSpending = $state('');
	let budgetIncome = $state('');
	let fitnessCalRemaining = $state(0);
	let fitnessCalLogged = $state(0);
	let fitnessCalGoal = $state(2000);
	let fitnessProtein = $state(0);
	let fitnessCarbs = $state(0);
	let fitnessProteinGoal = $state(150);
	let fitnessCarbsGoal = $state(200);
	let fitnessFat = $state(0);
	let fitnessFatGoal = $state(65);
	let headerTasks = $state<QuickTask[]>([]);
	let headerOverdue = $state(0);
	let headerTotalCount = $state(0);
	let taskPanelOpen = $state(false);

	function getGreeting(): string {
		const h = new Date().getHours();
		if (h < 12) return 'Good morning';
		if (h < 17) return 'Good afternoon';
		return 'Good evening';
	}

	function getDateString(): string {
		return new Date().toLocaleDateString('en-US', {
			weekday: 'long', month: 'long', day: 'numeric'
		});
	}

	function formatTaskTime(t: QuickTask): string {
		const d = t.startDate || t.dueDate;
		if (!d || t.isAllDay) return '';
		try {
			const date = new Date(d);
			const h = date.getHours(), m = date.getMinutes();
			if (h === 0 && m === 0) return '';
			const ampm = h >= 12 ? 'PM' : 'AM';
			const hour = h % 12 || 12;
			return m > 0 ? `${hour}:${String(m).padStart(2, '0')} ${ampm}` : `${hour} ${ampm}`;
		} catch { return ''; }
	}

	const fitPercent = $derived(fitnessCalGoal > 0 ? Math.min(100, Math.round((fitnessCalLogged / fitnessCalGoal) * 100)) : 0);

	async function loadTasks() {
		try {
			const res = await fetch('/api/tasks/today', { credentials: 'include' });
			if (res.ok) {
				const t = await res.json();
				headerOverdue = t.overdueCount || 0;
				const today = t.today || [];
				const overdue = t.overdue || [];
				headerTotalCount = today.length + overdue.length;
				headerTasks = [...overdue, ...today].slice(0, 1);
			}
		} catch { /* silent */ }
	}

	onMount(async () => {
		const n = new Date();
		const today = `${n.getFullYear()}-${String(n.getMonth() + 1).padStart(2, '0')}-${String(n.getDate()).padStart(2, '0')}`;

		try {
			const [invRes, budgetRes, uncatRes, fitTotalsRes, fitGoalsRes] = await Promise.all([
				fetch('/api/inventory/summary', { credentials: 'include' }),
				fetch('/api/budget/summary', { credentials: 'include' }),
				fetch('/api/budget/uncategorized-count', { credentials: 'include' }),
				fetch(`/api/fitness/entries/totals?date=${today}`, { credentials: 'include' }),
				fetch(`/api/fitness/goals/for-date?date=${today}`, { credentials: 'include' }),
			]);
			if (invRes.ok) {
				const data = await invRes.json();
				inventoryIssueCount = data.issueCount || 0;
				inventoryReviewCount = data.reviewCount || 0;
			}
			if (budgetRes.ok) {
				const data = await budgetRes.json();
				budgetSpending = '$' + Math.abs(data.spendingDollars || 0).toLocaleString('en-US');
				budgetIncome = '$' + Math.abs(data.incomeDollars || 0).toLocaleString('en-US');
			}
			if (uncatRes.ok) {
				const data = await uncatRes.json();
				budgetUncatCount = data.count || 0;
			}
			if (fitTotalsRes.ok) {
				const t = await fitTotalsRes.json();
				fitnessCalLogged = Math.round(t.total_calories || 0);
				fitnessProtein = Math.round(t.total_protein || 0);
				fitnessCarbs = Math.round(t.total_carbs || 0);
				fitnessFat = Math.round(t.total_fat || 0);
			}
			if (fitGoalsRes.ok) {
				const g = await fitGoalsRes.json();
				fitnessCalGoal = g.calories || 2000;
				fitnessProteinGoal = g.protein || 150;
				fitnessCarbsGoal = g.carbs || 200;
				fitnessFatGoal = g.fat || 65;
				fitnessCalRemaining = Math.max(0, fitnessCalGoal - fitnessCalLogged);
			}
		} catch { /* silent */ }

		await loadTasks();
	});
</script>

<div class="page">
	<div class="db-surface">

		<!-- ═══ HEADER ═══ -->
		<div class="db-header">
			<div>
				<div class="db-date">{getDateString()}</div>
				<h1 class="db-greeting">{getGreeting()}, <strong>{userName}</strong></h1>
			</div>
			<button class="task-pill" onclick={() => taskPanelOpen = true}>
				<span class="tp-dot" class:tp-overdue={headerOverdue > 0}></span>
				<span class="tp-text"><b>{headerTotalCount} task{headerTotalCount !== 1 ? 's' : ''}</b>
					{#if headerTasks[0]} &middot; Next: {headerTasks[0].title}{/if}
				</span>
				<svg class="tp-arrow" width="13" height="13" viewBox="0 0 13 13" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M5 3l3.5 3.5L5 10"/></svg>
			</button>
		</div>

		<TaskSlideOver bind:open={taskPanelOpen} onclose={() => { taskPanelOpen = false; loadTasks(); }} />

		<!-- ═══ BENTO ROW 1: Budget (2fr) + Inventory (1fr) ═══ -->
		<div class="bento stagger">
			<a href="/budget" class="bc bc-emerald">
				<div class="bc-top">
					<span class="bc-label">Budget</span>
					<div class="bc-icon emerald">
						<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>
					</div>
				</div>
				<div class="bc-value">{budgetUncatCount}</div>
				<div class="bc-desc">uncategorized transactions<br><strong>{budgetSpending} spent</strong> &middot; {budgetIncome} income</div>
				<div class="bc-action">Review <svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M4 2l3.5 3.5L4 9"/></svg></div>
			</a>

			<a href="/inventory" class="bc bc-rose">
				<div class="bc-top">
					<span class="bc-label">Inventory</span>
					<div class="bc-icon rose">
						<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/></svg>
					</div>
				</div>
				<div class="bc-value-sm">{inventoryIssueCount} issues</div>
				<div class="bc-desc">{inventoryReviewCount} needs review<br>{inventoryIssueCount + inventoryReviewCount} items need attention</div>
				<div class="bc-action">View <svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M4 2l3.5 3.5L4 9"/></svg></div>
			</a>
		</div>

		<!-- ═══ BENTO ROW 2: Calories (1fr) + Fitness detail (1fr) ═══ -->
		<div class="bento-row2 stagger">
			<a href="/fitness" class="bc bc-emerald">
				<div class="bc-top">
					<span class="bc-label">Calories</span>
					<div class="bc-icon emerald">
						<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
					</div>
				</div>
				<div class="bc-value">{fitnessCalRemaining.toLocaleString()}</div>
				<div class="bc-desc">remaining today<br><strong>{fitnessCalLogged.toLocaleString()} logged</strong> &middot; {fitnessProtein}g protein &middot; {fitnessCarbs}g carbs</div>
				<div class="bc-action">Log food <svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M4 2l3.5 3.5L4 9"/></svg></div>
			</a>

			<div class="bc">
				<div class="fit-header">
					<div class="fit-av">Y</div>
					<div>
						<div class="fit-name">{userName}</div>
						<div class="fit-sub">{fitnessCalLogged.toLocaleString()} cal &middot; {fitnessCalRemaining.toLocaleString()} left</div>
					</div>
				</div>
				<div class="fit-bar"><div class="fit-fill" style="width: {fitPercent}%"></div></div>
				<div class="fit-macros">
					<div><span class="fm-v">{fitnessProtein}<span class="fm-u">/{fitnessProteinGoal}g</span></span><div class="fm-l">protein</div></div>
					<div><span class="fm-v">{fitnessCarbs}<span class="fm-u">/{fitnessCarbsGoal}g</span></span><div class="fm-l">carbs</div></div>
					<div><span class="fm-v">{fitnessFat}<span class="fm-u">/{fitnessFatGoal}g</span></span><div class="fm-l">fat</div></div>
				</div>
			</div>
		</div>

		<!-- ═══ MODULES: Budget detail (7fr) + Issues (3fr) ═══ -->
		<div class="db-modules">
			<BudgetModule />
			<IssuesModule />
		</div>

	</div>
</div>

<style>
	/* ═══ Dashboard — matches React mockup exactly ═══ */

	.db-surface {
		max-width: 1280px;
		width: 100%;
		margin: 0 auto;
		padding: 0 24px;
	}

	/* ── Header ── */
	.db-header {
		display: flex;
		align-items: flex-end;
		justify-content: space-between;
		gap: 32px;
		margin-bottom: 28px;
	}

	.db-date {
		font-size: 11px;
		font-weight: 600;
		color: var(--accent);
		text-transform: uppercase;
		letter-spacing: 0.1em;
		margin-bottom: 4px;
	}

	.db-greeting {
		font-size: 28px;
		font-weight: 400;
		letter-spacing: -0.03em;
		line-height: 1.1;
		color: var(--text-1);
		margin: 0;
	}
	.db-greeting strong { font-weight: 800; }

	/* ── Task pill ── */
	.task-pill {
		display: flex;
		align-items: center;
		gap: 10px;
		padding: 8px 14px 8px 10px;
		border-radius: 999px;
		background: var(--card);
		border: 1px solid var(--border);
		box-shadow: var(--shadow-sm);
		cursor: pointer;
		flex-shrink: 0;
		white-space: nowrap;
		transition: all 0.25s cubic-bezier(0.16,1,0.3,1);
		font-family: var(--font);
	}
	.task-pill:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
	.task-pill:active { transform: scale(0.97); }

	.tp-dot {
		width: 7px;
		height: 7px;
		border-radius: 50%;
		background: var(--accent);
		flex-shrink: 0;
		animation: breathe 2.5s ease-in-out infinite;
	}
	.tp-dot.tp-overdue { background: var(--error); }

	@keyframes breathe {
		0%, 100% { opacity: 1; transform: scale(1); }
		50% { opacity: 0.4; transform: scale(0.85); }
	}

	.tp-text { font-size: 12px; font-weight: 500; color: var(--text-3); }
	.tp-text b { color: var(--text-1); font-weight: 600; }

	.tp-arrow { color: var(--text-4); transition: all 0.2s; }
	.task-pill:hover .tp-arrow { color: var(--accent); transform: translateX(2px); }

	/* ── Bento grids ── */
	.bento {
		display: grid;
		grid-template-columns: 2fr 1fr;
		gap: 10px;
		margin-bottom: 10px;
	}
	.bento-row2 {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 10px;
		margin-bottom: 10px;
	}

	/* ── Bento card ── */
	.bc {
		background: var(--card);
		border: 1px solid var(--border);
		border-radius: 16px;
		padding: 22px 24px;
		box-shadow: var(--shadow-sm);
		cursor: pointer;
		position: relative;
		overflow: hidden;
		text-decoration: none;
		color: inherit;
		display: flex;
		flex-direction: column;
		border-top: 2px solid transparent;
		transition: all 0.3s cubic-bezier(0.16,1,0.3,1);
	}
	.bc:hover {
		transform: translateY(-3px);
		box-shadow: var(--shadow-md);
	}
	.bc:active { transform: scale(0.985); }
	.bc.bc-emerald:hover { border-top-color: var(--accent); }
	.bc.bc-rose:hover { border-top-color: var(--error); }

	.bc-top {
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin-bottom: 14px;
	}
	.bc-label {
		font-size: 10px;
		font-weight: 700;
		text-transform: uppercase;
		letter-spacing: 0.12em;
		color: var(--text-4);
	}
	.bc-icon {
		width: 28px;
		height: 28px;
		border-radius: 8px;
		display: flex;
		align-items: center;
		justify-content: center;
	}
	.bc-icon.emerald { background: var(--accent-dim); color: var(--accent); }
	.bc-icon.rose { background: var(--error-dim); color: var(--error); }

	.bc-value {
		font-size: 32px;
		font-weight: 700;
		font-family: var(--mono);
		letter-spacing: -0.04em;
		line-height: 1;
		color: var(--text-1);
		margin-bottom: 6px;
	}
	.bc-value-sm {
		font-size: 20px;
		font-weight: 700;
		font-family: var(--mono);
		letter-spacing: -0.03em;
		color: var(--text-1);
		margin-bottom: 4px;
	}
	.bc-desc {
		font-size: 13px;
		color: var(--text-3);
		line-height: 1.5;
	}
	.bc-desc :global(strong) { color: var(--text-2); font-weight: 500; }

	.bc-action {
		display: inline-flex;
		align-items: center;
		gap: 4px;
		font-size: 11px;
		font-weight: 600;
		color: var(--accent);
		margin-top: 10px;
		letter-spacing: 0.02em;
		transition: gap 0.2s;
	}
	.bc:hover .bc-action { gap: 7px; }

	/* ── Fitness card (inline) ── */
	.fit-header { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
	.fit-av {
		width: 34px; height: 34px; border-radius: 50%;
		background: var(--accent-dim); color: var(--accent);
		display: flex; align-items: center; justify-content: center;
		font-size: 12px; font-weight: 700;
	}
	.fit-name { font-size: 13px; font-weight: 600; color: var(--text-1); }
	.fit-sub { font-size: 11px; color: var(--text-4); margin-top: 1px; }
	.fit-bar {
		height: 4px; background: var(--card-hover); border-radius: 2px;
		margin-bottom: 14px; overflow: hidden;
	}
	.fit-fill {
		height: 100%; border-radius: 2px; background: var(--accent);
		transition: width 1s cubic-bezier(0.16,1,0.3,1);
	}
	.fit-macros { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px; }
	.fm-v { font-size: 14px; font-weight: 600; font-family: var(--mono); color: var(--text-1); }
	.fm-u { font-size: 10px; color: var(--text-4); }
	.fm-l { font-size: 10px; color: var(--text-4); margin-top: 1px; }

	/* ── Modules ── */
	.db-modules {
		display: grid;
		grid-template-columns: 7fr 3fr;
		gap: 10px;
		align-items: start;
	}
	.db-modules > :global(.module) {
		padding: 22px 24px;
		border-radius: 16px;
		min-width: 0;
	}

	/* ── Mobile ── */
	@media (max-width: 900px) {
		.db-header { flex-direction: column; align-items: flex-start; gap: 12px; }
		.db-greeting { font-size: 22px; }
		.task-pill { width: 100%; }
	}

	@media (max-width: 768px) {
		.db-surface { padding: 0 16px; }
		.bento, .bento-row2, .db-modules { grid-template-columns: 1fr; }
		.bento > *, .bento-row2 > *, .db-modules > :global(*) { min-width: 0; max-width: 100%; }
		.bc-value { font-size: 24px; }
	}
</style>
