<script lang="ts">
	import { goto } from '$app/navigation';
	import type { Person } from '$lib/types';
	import { onMount } from 'svelte';
	import { listenToPersonEvents } from '$lib/client/person-events';
	import { gradeLabel, guardianLabel, isLowerGrade } from '$lib/client/person-utils';
	import { personMatchesQuery, sortPersonsByQuery } from '$lib/client/person-search';

	type GradeFilter = 'all' | 'lt4' | 'ge4';
	type VisitorFilter = 'all' | 'besoksplats' | 'lanplats';

	let searchQuery = $state('');
	let searchResults = $state<Person[]>([]);
	let visibleResults = $state<Person[]>([]);
	let searchLoading = $state(false);
	let searchError = $state('');
	let searchInfo = $state('');
	let actionInfo = $state('');
	let gradeFilter = $state<GradeFilter>('all');
	let visitorFilter = $state<VisitorFilter>('all');

	function fullName(person: Person) {
		return `${person.first_name} ${person.last_name}`.trim();
	}

	function matchesFilters(person: Person) {
		if (!person.checked_in) {
			return false;
		}

		const gradeValue = person.grade;
		if (gradeFilter === 'lt4' && (gradeValue == null || gradeValue > 3)) {
			return false;
		}
		if (gradeFilter === 'ge4' && (gradeValue == null || gradeValue <= 3)) {
			return false;
		}

		if (visitorFilter === 'besoksplats' && !person.visitor) {
			return false;
		}
		if (visitorFilter === 'lanplats' && person.visitor) {
			return false;
		}

		const query = searchQuery.trim();
		if (query && !personMatchesQuery(person, query)) {
			return false;
		}

		return true;
	}

	async function apiFetch(url: string, init?: RequestInit) {
		const response = await fetch(url, init);
		if (response.status === 401) {
			await goto('/admin/login');
			return null;
		}
		return response;
	}

	async function loadDefaultList() {
		searchLoading = true;
		searchError = '';
		actionInfo = '';
		try {
			const response = await apiFetch('/api/persons/checked-in?checked=true');
			if (!response) return;
			if (!response.ok) {
				const text = await response.text();
				try {
					const body = JSON.parse(text);
					searchError = body.message ?? 'Kunde inte hämta personer.';
				} catch {
					searchError = text || 'Kunde inte hämta personer.';
				}
				searchResults = [];
				visibleResults = [];
				return;
			}

			const data = await response.json();
			searchResults = data.persons ?? [];
			updateVisibleResults();
		} catch (err) {
			console.error('Initial checkout load failed', err);
			searchError = 'Ett oväntat fel inträffade när listan skulle hämtas.';
			searchResults = [];
			visibleResults = [];
		} finally {
			searchLoading = false;
		}
	}

	async function handleSearch(event?: SubmitEvent) {
		event?.preventDefault();
		actionInfo = '';
		searchError = '';
		searchInfo = '';

		const query = searchQuery.trim();
		if (!query) {
			await loadDefaultList();
			return;
		}

		searchLoading = true;
		try {
			const response = await apiFetch(`/api/persons/search?q=${encodeURIComponent(query)}`);
			if (!response) return;

			if (!response.ok) {
				const body = await response.json().catch(() => ({}));
				searchError = body.message ?? 'Sökningen misslyckades.';
				searchResults = [];
				visibleResults = [];
				return;
			}

			const data = await response.json();
			searchResults = data.persons ?? [];
			updateVisibleResults();
		} catch (err) {
			console.error('Search failed', err);
			searchError = 'Ett oväntat fel inträffade vid sökningen.';
			searchResults = [];
			visibleResults = [];
		} finally {
			searchLoading = false;
		}
	}

	function updatePersonList(updated: Person) {
		let found = false;
		searchResults = searchResults.map((person) => {
			if (person.id === updated.id) {
				found = true;
				return updated;
			}
			return person;
		});
		if (!found && updated.checked_in) {
			searchResults = [updated, ...searchResults];
		}
		updateVisibleResults();
	}

	async function handleCheckout(person: Person) {
		actionInfo = '';
		if (!person.checked_in) {
			return;
		}
		const response = await apiFetch(`/api/persons/${person.id}/checkout`, { method: 'POST' });
		actionInfo = '';
		if (!response) return;

		if (!response.ok) {
			const body = await response.json().catch(() => ({}));
			searchError = body.message ?? 'Kunde inte checka ut personen.';
			return;
		}

		const data = await response.json();
		searchError = '';
		updatePersonList(data.person);
		actionInfo = 'Personen är nu utcheckad.';
	}

	function updateVisibleResults() {
		const filtered = searchResults.filter((person) => matchesFilters(person));
		const query = searchQuery.trim();
		visibleResults = query ? sortPersonsByQuery(filtered, query) : filtered;

		if (searchResults.length === 0 && !searchQuery.trim()) {
			searchInfo = 'Inga personer hämtades.';
		} else if (filtered.length === 0) {
			searchInfo = 'Ingen person matchar de valda filtren just nu.';
		} else {
			searchInfo = '';
		}
	}

	function handleGradeFilterChange(event: Event) {
		const value = (event.currentTarget as HTMLSelectElement).value as GradeFilter;
		gradeFilter = value;
		updateVisibleResults();
	}

	function handleVisitorFilterChange(event: Event) {
		const value = (event.currentTarget as HTMLSelectElement).value as VisitorFilter;
		visitorFilter = value;
		updateVisibleResults();
	}

	onMount(() => {
		void loadDefaultList();
		const stop = listenToPersonEvents((person) => {
			updatePersonList(person);
		});
		return () => {
			stop();
		};
	});
</script>

<div class="space-y-6">
	<section class="rounded-lg border border-slate-200 bg-white p-6 shadow-sm">
		<h3 class="text-lg font-semibold text-slate-800">Checka ut</h3>
		<p class="mb-4 text-sm text-slate-500">
			Sök på namn, id, vårdnadshavare eller telefonnummer för att hitta personer som ska
			checkas ut.
		</p>
		<form
			class="grid gap-3 md:grid-cols-[2fr_1fr_1fr_auto]"
			onsubmit={handleSearch}
		>
			<div class="flex flex-col gap-1">
				<label for="checkout-query" class="text-sm font-medium text-slate-600">Sök</label>
				<input
					type="text"
					id="checkout-query"
					placeholder="Exempel: Anna Andersson, 42 eller 0701234567"
					bind:value={searchQuery}
					class="w-full rounded-md border border-slate-300 px-3 py-2 text-slate-900 focus:border-indigo-500 focus:ring focus:ring-indigo-100 focus:outline-none"
				/>
			</div>
			<div class="flex flex-col gap-1">
				<label for="checkout-grade" class="text-sm font-medium text-slate-600"
					>Årskurs</label
				>
				<select
					id="checkout-grade"
					bind:value={gradeFilter}
					onchange={handleGradeFilterChange}
					class="w-full rounded-md border border-slate-300 px-3 py-2 text-sm text-slate-900 focus:border-indigo-500 focus:ring focus:ring-indigo-100 focus:outline-none"
				>
					<option value="all">Alla</option>
					<option value="lt4">Årskurs 3 eller yngre</option>
					<option value="ge4">Årskurs 4 eller äldre</option>
				</select>
			</div>
			<div class="flex flex-col gap-1">
				<label for="checkout-visitor" class="text-sm font-medium text-slate-600"
					>Plats</label
				>
				<select
					id="checkout-visitor"
					bind:value={visitorFilter}
					onchange={handleVisitorFilterChange}
					class="w-full rounded-md border border-slate-300 px-3 py-2 text-sm text-slate-900 focus:border-indigo-500 focus:ring focus:ring-indigo-100 focus:outline-none"
				>
					<option value="all">Alla</option>
					<option value="besoksplats">Besöksplats</option>
					<option value="lanplats">Lanplats</option>
				</select>
			</div>
			<div class="flex items-end">
				<button
					type="submit"
					disabled={searchLoading}
					class="w-full rounded-md bg-indigo-600 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-indigo-700 disabled:cursor-not-allowed disabled:opacity-70"
				>
					{searchLoading ? 'Söker…' : 'Sök'}
				</button>
			</div>
		</form>
		{#if searchError}
			<p class="mt-4 rounded-md bg-red-50 px-3 py-2 text-sm text-red-600">{searchError}</p>
		{/if}
		{#if searchInfo}
			<p class="mt-4 rounded-md bg-amber-50 px-3 py-2 text-sm text-amber-700">{searchInfo}</p>
		{/if}
		{#if actionInfo}
			<p class="mt-4 rounded-md bg-emerald-50 px-3 py-2 text-sm text-emerald-700">{actionInfo}</p>
		{/if}

		{#if visibleResults.length > 0}
			<ul class="mt-6 space-y-4">
				{#each visibleResults as person}
					<li class="rounded-lg border border-slate-200 p-4 shadow-sm">
						<div class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
							<div>
								<h4 class="text-base font-semibold text-slate-800">{fullName(person)}</h4>
								<p class="text-sm text-slate-500">
									ID: {person.id} · Klass: {gradeLabel(person)}
								</p>
								<p class="text-sm text-slate-500">
									Vårdnadshavare: {guardianLabel(person)}
								</p>
							</div>
							<div class="flex flex-wrap gap-2">
								<span
									class={`rounded-full px-3 py-1 text-xs font-semibold ${
										person.checked_in
											? 'bg-emerald-100 text-emerald-700'
											: 'bg-slate-100 text-slate-600'
									}`}>{person.checked_in ? 'Incheckad' : 'Inte incheckad'}</span
								>
								<span
									class={`rounded-full px-3 py-1 text-xs font-semibold ${
										person.inside ? 'bg-blue-100 text-blue-700' : 'bg-slate-100 text-slate-600'
									}`}>{person.inside ? 'Inne' : 'Ute'}</span
								>
							{#if person.visitor}
								<span class="rounded-full bg-amber-100 px-3 py-1 text-xs font-semibold text-amber-700">
									Besöksplats
								</span>
								{/if}
								{#if person.sleeping_spot}
									<span class="rounded-full bg-indigo-100 px-3 py-1 text-xs font-semibold text-indigo-700">
										Behöver sovplats
									</span>
								{/if}
							</div>
						</div>
					    <!--
						{#if isLowerGrade(person)}
							<p class="mt-2 rounded-md bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-800">
								Observera: elev i årskurs 3 eller yngre – ska hem senast 22:00.
							</p>
						{/if}
					    -->
						<div class="mt-4 flex gap-3">
							<button
								type="button"
								onclick={() => handleCheckout(person)}
								disabled={!person.checked_in || searchLoading}
								class={`rounded-md px-4 py-2 text-sm font-semibold transition-colors ${
									person.checked_in
										? 'bg-red-600 text-white hover:bg-red-700'
										: 'cursor-not-allowed bg-slate-200 text-slate-600'
								}`}
							>
								Checka ut
							</button>
						</div>
					</li>
				{/each}
			</ul>
		{/if}
	</section>
</div>
