<!--
  Modo Compra — full-screen shopping session view.

  Overlays the app sidebar (position: fixed on the wrapper). Large tap targets
  optimised for thumbs and checkout flow: tap an item to flip it to CHECKED,
  "Finish shopping" marks the list completed and returns to /lists.

  Uses the same Realtime + offline machinery as the regular list detail page —
  imports from $lib/stores/realtimeSync and $lib/sync so mutations stay
  consistent with Fase 2b.1/2b.2.
-->
<script lang="ts">
	import { onDestroy, onMount } from 'svelte';
	import { goto } from '$app/navigation';
	import { page } from '$app/stores';
	import { flip } from 'svelte/animate';
	import { currentUser } from '$lib/stores/auth';
	import { loadItems, checkItem, completeList } from '$lib/stores/lists';
	import {
		subscribeToList,
		applyItemEvent,
		type RealtimeSubscription
	} from '$lib/stores/realtimeSync';
	import { getSupabase } from '$lib/supabase';
	import SyncBanner from '$lib/components/SyncBanner.svelte';
	import type { ShoppingList, ShoppingItem } from '@colectivo/types';
	import { ArrowLeft, Check } from 'lucide-svelte';
	import * as m from '$lib/paraglide/messages';

	const listId = $page.params.id!;

	let list = $state<ShoppingList | null>(null);
	let items = $state<ShoppingItem[]>([]);
	let loading = $state(true);
	let finishing = $state(false);
	let showFinishModal = $state(false);

	const uncheckedItems = $derived(items.filter((i) => !i.is_checked));
	const checkedItems = $derived(items.filter((i) => i.is_checked));

	let sub: RealtimeSubscription | null = null;

	onMount(async () => {
		const [listRes, itemsRes] = await Promise.all([
			getSupabase().from('shopping_lists').select('*').eq('id', listId).single(),
			loadItems(listId)
		]);
		if (listRes.error || !listRes.data) {
			goto('/lists');
			return;
		}
		list = listRes.data as ShoppingList;
		items = itemsRes;
		loading = false;

		sub = await subscribeToList(listId, (evt) => {
			items = applyItemEvent(items, evt);
		});
	});

	onDestroy(async () => {
		await sub?.unsubscribe();
	});

	async function toggleCheck(item: ShoppingItem) {
		if (!$currentUser) return;
		const checked = !item.is_checked;
		items = items.map((i) =>
			i.id === item.id
				? {
						...i,
						is_checked: checked,
						checked_by: checked ? $currentUser!.id : null,
						checked_at: checked ? new Date().toISOString() : null
					}
				: i
		);
		await checkItem(item.id, $currentUser.id, checked);
	}

	async function confirmFinish() {
		if (finishing) return;
		finishing = true;
		await completeList(listId);
		goto('/lists');
	}

	const flipMs = 250;
</script>

<div
	data-testid="shopping-session"
	class="fixed inset-0 z-50 flex flex-col bg-background text-text-primary"
>
	<!-- Header: back + list name -->
	<header class="flex items-center gap-3 border-b border-surface-raised px-4 py-3">
		<a
			href="/lists/{listId}"
			aria-label="Back"
			class="rounded-md p-2 hover:bg-black/5 dark:hover:bg-white/5"
		>
			<ArrowLeft size={20} strokeWidth={1.75} />
		</a>
		<h1 class="flex-1 truncate text-lg font-semibold tracking-[-0.01em]">
			{list?.name ?? ''}
		</h1>
	</header>

	<SyncBanner />

	<main class="flex-1 overflow-y-auto px-4 pb-36 pt-2">
		{#if loading}
			<p class="text-center text-sm text-text-muted py-8">{m.loading()}</p>
		{:else if items.length === 0}
			<p class="py-16 text-center text-sm text-text-muted">{m.list_items_empty()}</p>
		{:else}
			<section>
				<p class="mb-1 text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">
					{m.list_to_buy()} ({uncheckedItems.length})
				</p>
				<ul class="divide-y divide-surface-raised">
					{#each uncheckedItems as item (item.id)}
						<li
							role="listitem"
							animate:flip={{ duration: flipMs }}
							class="flex items-center gap-4 py-4"
						>
							<button
								onclick={() => toggleCheck(item)}
								aria-label="Toggle item"
								class="shrink-0 h-14 w-14 rounded-full border-2 border-slate-300 dark:border-slate-600
									flex items-center justify-center hover:border-slate-400 dark:hover:border-slate-500
									active:scale-95 transition"
							></button>
							<div class="flex-1 min-w-0">
								<p class="truncate text-base font-medium">{item.name}</p>
								{#if item.quantity}
									<p class="text-sm text-text-muted">{item.quantity}</p>
								{/if}
							</div>
						</li>
					{/each}
				</ul>
			</section>

			{#if checkedItems.length > 0}
				<section class="mt-8 opacity-60">
					<p class="mb-1 text-[13px] font-semibold uppercase tracking-[0.05em] text-text-secondary">
						{m.list_checked()} ({checkedItems.length})
					</p>
					<ul class="divide-y divide-surface-raised">
						{#each checkedItems as item (item.id)}
							<li
								role="listitem"
								animate:flip={{ duration: flipMs }}
								class="flex items-center gap-4 py-4"
							>
								<button
									onclick={() => toggleCheck(item)}
									aria-label="Uncheck item"
									class="shrink-0 h-14 w-14 rounded-full border-2 border-slate-400 bg-slate-400
										dark:border-slate-500 dark:bg-slate-500
										flex items-center justify-center active:scale-95 transition"
								>
									<Check size={28} strokeWidth={2.5} class="text-white dark:text-slate-900" />
								</button>
								<div class="flex-1 min-w-0">
									<p class="truncate text-base line-through text-text-muted">{item.name}</p>
								</div>
							</li>
						{/each}
					</ul>
				</section>
			{/if}
		{/if}
	</main>

	<!-- Finish shopping CTA -->
	<div
		class="absolute bottom-0 left-0 right-0 border-t border-surface-raised bg-background/90
			px-4 py-3 backdrop-blur-[8px]"
	>
		<button
			onclick={() => (showFinishModal = true)}
			class="h-14 w-full rounded-lg bg-slate-900 text-base font-semibold text-slate-50
				hover:bg-slate-800 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-200
				active:scale-[0.98] transition"
		>
			{m.list_finish_shopping()}
		</button>
	</div>

	{#if showFinishModal}
		<div
			role="dialog"
			aria-modal="true"
			class="absolute inset-0 z-10 flex items-center justify-center bg-black/40"
			onclick={(e) => {
				if (e.target === e.currentTarget) showFinishModal = false;
			}}
			onkeydown={(e) => {
				if (e.key === 'Escape') showFinishModal = false;
			}}
			tabindex="-1"
		>
			<div class="mx-4 max-w-sm w-full rounded-lg bg-surface p-5 shadow-lg">
				<p class="mb-4 text-base font-medium">{m.list_finish_confirm()}</p>
				<div class="flex justify-end gap-2">
					<button
						onclick={() => (showFinishModal = false)}
						class="rounded-md px-3 py-2 text-sm hover:bg-black/5 dark:hover:bg-white/5"
					>
						{m.list_finish_confirm_no()}
					</button>
					<button
						onclick={confirmFinish}
						disabled={finishing}
						class="rounded-md bg-slate-900 px-3 py-2 text-sm font-semibold text-slate-50
							hover:bg-slate-800 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-200
							disabled:opacity-60"
					>
						{m.list_finish_confirm_yes()}
					</button>
				</div>
			</div>
		</div>
	{/if}
</div>
