<script lang="ts">
	import type {
		TournamentFieldType,
		TournamentInfo,
		TournamentSignupConfig,
		TournamentSignupField
	} from '$lib/types';

	const props = $props<{ data: { tournament: TournamentInfo } }>();
	const tournament = props.data.tournament;

	function pickMode(value: string | null | undefined) {
		return value === 'team' ? 'team' : 'solo';
	}

	function sanitizeField(field: TournamentSignupField): TournamentSignupField {
		return {
			id: field.id,
			label: field.label,
			field_type: field.field_type ?? 'text',
			required: Boolean(field.required),
			placeholder: field.placeholder ?? null,
			unique: Boolean(field.unique)
		};
	}

	function normalizeSignupConfig(config: TournamentSignupConfig | null | undefined): TournamentSignupConfig {
		if (!config) {
			return {
				mode: 'solo',
				team_size: { min: 1, max: 1 },
				entry_fields: [],
				participant_fields: []
			};
		}

		const mode = pickMode(config.mode);
		let min = Math.max(1, Math.floor(config.team_size?.min ?? 1));
		let max = Math.max(1, Math.floor(config.team_size?.max ?? 1));
		if (max < min) max = min;
		if (mode === 'solo') {
			min = 1;
			max = 1;
		}

		return {
			mode,
			team_size: { min, max },
			entry_fields: (config.entry_fields ?? []).map(sanitizeField),
			participant_fields: (config.participant_fields ?? []).map(sanitizeField)
		};
	}

	type FieldValueMap = Record<string, string>;

	const signupConfig = normalizeSignupConfig(tournament.signup_config);

	function formatDateTime(value: string | null) {
		if (!value) return null;
		const date = new Date(value);
		if (Number.isNaN(date.getTime())) return null;
		return date.toLocaleString('sv-SE', {
			year: 'numeric',
			month: 'long',
			day: 'numeric',
			hour: '2-digit',
			minute: '2-digit',
			hour12: false
		});
	}

	const formattedStart = formatDateTime(tournament.start_at);

	function createFieldMap(fields: TournamentSignupField[]): FieldValueMap {
		const map: FieldValueMap = {};
		for (const field of fields) {
			map[field.id] = '';
		}
		return map;
	}

	function participantDisplayName(index: number) {
		return signupConfig.mode === 'team' ? `Spelare ${index + 1}` : 'Spelare';
	}

	function fieldInputType(field: TournamentFieldType) {
		switch (field) {
			case 'email':
				return 'email';
			case 'tel':
				return 'tel';
			default:
				return 'text';
		}
	}

	const minParticipants = signupConfig.mode === 'team' ? signupConfig.team_size.min : 1;
	const maxParticipants = signupConfig.mode === 'team' ? signupConfig.team_size.max : 1;

	let signup = $state({
		entry: createFieldMap(signupConfig.entry_fields),
		participants: [] as FieldValueMap[],
		submitting: false,
		success: '',
		error: '',
		successRegistrationId: null as number | null,
		submittedEntry: {} as Record<string, string>,
		submittedParticipants: [] as Record<string, string>[],
		showSuccessModal: false
	});



	function initializeParticipants() {
		const initialCount = Math.max(1, signupConfig.mode === 'team' ? signupConfig.team_size.min : 1);
		const list: FieldValueMap[] = [];
		for (let i = 0; i < initialCount; i += 1) {
			list.push(createFieldMap(signupConfig.participant_fields));
		}
		signup.participants = list;
	}

	initializeParticipants();

	function canAddParticipant() {
		return signupConfig.mode === 'team' && signup.participants.length < maxParticipants;
	}

	function canRemoveParticipant() {
		return signupConfig.mode === 'team' && signup.participants.length > minParticipants;
	}

	function addParticipant() {
		if (!canAddParticipant()) return;
		signup.participants = [...signup.participants, createFieldMap(signupConfig.participant_fields)];
	}

	function removeParticipant(index: number) {
		if (!canRemoveParticipant()) return;
		signup.participants = signup.participants.filter((_, idx) => idx !== index);
	}

	function resetSignupForm() {
		signup.entry = createFieldMap(signupConfig.entry_fields);
		signup.participants = [];
		initializeParticipants();
		signup.success = '';
		signup.error = '';
	}

	type SignupPayload = {
		entry: Record<string, string>;
		participants: Record<string, string>[];
	};

	function buildSignupPayload(): SignupPayload {
		const entry: Record<string, string> = {};
		for (const field of signupConfig.entry_fields) {
			entry[field.id] = (signup.entry[field.id] ?? '').trim();
		}

		const participants = signup.participants.map((participant) => {
			const map: Record<string, string> = {};
			for (const field of signupConfig.participant_fields) {
				map[field.id] = (participant[field.id] ?? '').trim();
			}
			return map;
		});

		return { entry, participants };
	}

	async function handleSignupSubmit(event: SubmitEvent) {
		event.preventDefault();
		signup.error = '';
		signup.success = '';

		if (signup.participants.length === 0) {
			signup.error = 'Lägg till minst en spelare.';
			return;
		}

		if (signupConfig.mode === 'team') {
			if (signup.participants.length < minParticipants) {
				signup.error = `Lägg till minst ${minParticipants} spelare.`;
				return;
			}
		}

		signup.submitting = true;
		try {
			const payload = buildSignupPayload();
			const response = await fetch(`/api/tournament/slug/${tournament.slug}/signup`, {
				method: 'POST',
				headers: { 'content-type': 'application/json' },
				body: JSON.stringify(payload)
			});
			const text = await response.text();
			if (!response.ok) {
				let message = 'Kunde inte skicka anmälan.';
				try {
					const body = JSON.parse(text);
					message = body.message ?? message;
				} catch {
					if (text) message = text;
				}
				throw new Error(message);
			}

			let registrationId: number | null = null;
			try {
				const parsed = JSON.parse(text) as { registration_id?: number | string };
				const numeric = Number(parsed?.registration_id);
				if (Number.isFinite(numeric) && numeric > 0) {
					registrationId = numeric;
				}
			} catch {
				// ignored; we handle below
			}

			if (!registrationId) {
				throw new Error('Kunde inte läsa svar från servern.');
			}

			const entrySummary = Object.fromEntries(Object.entries(payload.entry));
			const participantSummary = payload.participants.map((values) => ({ ...values }));

			resetSignupForm();
			signup.successRegistrationId = registrationId;
			signup.submittedEntry = entrySummary;
			signup.submittedParticipants = participantSummary;
			signup.success = 'Tack! Din anmälan har skickats.';
			signup.showSuccessModal = true;
		} catch (err) {
			console.error('Failed to submit signup', err);
			signup.error = err instanceof Error ? err.message : 'Ett oväntat fel inträffade.';
		} finally {
			signup.submitting = false;
		}
	}
</script>

<svelte:head>
	<title>{tournament.title} – VBytes LAN</title>
</svelte:head>

<div class="min-h-screen bg-slate-950 text-slate-100">
	<div class="mx-auto flex min-h-screen max-w-4xl flex-col gap-8 px-4 py-12">
		<nav class="flex items-center justify-between text-sm text-slate-400">
			<a href="/tournament" class="inline-flex items-center gap-2 transition hover:text-indigo-300">
				<span aria-hidden="true">←</span>
				<span>Tillbaka till turneringsöversikten</span>
			</a>
			<span class="uppercase tracking-[0.4em] text-indigo-300">{tournament.game}</span>
		</nav>

		<header class="space-y-4 rounded-2xl bg-slate-900/70 p-6 shadow-lg">
			<div class="space-y-2">
				<p class="text-xs uppercase tracking-[0.4em] text-indigo-200">VBytes LAN</p>
				<h1 class="text-3xl font-bold sm:text-4xl">{tournament.title}</h1>
				{#if tournament.tagline}
					<p class="text-base text-slate-300">{tournament.tagline}</p>
				{/if}
			</div>
			<div class="grid gap-3 sm:grid-cols-2">
				{#if formattedStart}
					<div class="rounded-lg border border-slate-800 bg-slate-900/40 p-3">
						<p class="text-xs uppercase tracking-wide text-indigo-200">Start</p>
						<p class="text-sm text-slate-100">{formattedStart}</p>
					</div>
				{/if}
				{#if tournament.location}
					<div class="rounded-lg border border-slate-800 bg-slate-900/40 p-3">
						<p class="text-xs uppercase tracking-wide text-indigo-200">Plats</p>
						<p class="text-sm text-slate-100">{tournament.location}</p>
					</div>
				{/if}
				{#if tournament.contact}
					<div class="rounded-lg border border-slate-800 bg-slate-900/40 p-3 sm:col-span-2">
						<p class="text-xs uppercase tracking-wide text-indigo-200">Kontakt</p>
						<p class="text-sm text-slate-100">{tournament.contact}</p>
					</div>
				{/if}
			</div>
		</header>

		{#if tournament.description}
			<section class="space-y-3 rounded-2xl border border-slate-800 bg-slate-900/50 p-6">
				<h2 class="text-lg font-semibold text-slate-100">Beskrivning</h2>
				<p class="whitespace-pre-line text-sm leading-relaxed text-slate-200">{tournament.description}</p>
			</section>
		{/if}

		{#if tournament.sections.length > 0}
			<section class="space-y-4">
				{#each tournament.sections as section, index (section.title + index)}
					<article class="space-y-2 rounded-2xl border border-slate-800 bg-slate-900/50 p-6">
						<h3 class="text-base font-semibold text-indigo-200">{section.title}</h3>
						<p class="whitespace-pre-line text-sm leading-relaxed text-slate-200">{section.body}</p>
					</article>
				{/each}
			</section>
		{/if}

		<section class="space-y-5 rounded-2xl border border-slate-800 bg-slate-900/50 p-6">
			<header class="space-y-1">
				<h2 class="text-lg font-semibold text-slate-100">Anmälan</h2>
				{#if signupConfig.mode === 'team'}
					<p class="text-sm text-slate-300">Lagstorlek: {signupConfig.team_size.min}–{signupConfig.team_size.max} spelare.</p>
				{:else}
					<p class="text-sm text-slate-300">Individuell anmälan.</p>
				{/if}
			</header>

			<form class="space-y-5" onsubmit={handleSignupSubmit}>
				{#if signupConfig.entry_fields.length > 0}
					<div class="space-y-3">
						<h3 class="text-sm font-semibold uppercase tracking-wide text-slate-400">Lag / deltagare</h3>
						<div class="grid gap-3 md:grid-cols-2">
							{#each signupConfig.entry_fields as field}
								<label class="flex flex-col gap-1 text-sm font-medium text-slate-200">
									<span>{field.label}</span>
									<input
										type={fieldInputType(field.field_type)}
										required={field.required}
										placeholder={field.placeholder ?? ''}
										value={signup.entry[field.id]}
										oninput={(event) => (signup.entry[field.id] = (event.currentTarget as HTMLInputElement).value)}
										class="rounded-md border border-slate-700 bg-slate-900 px-3 py-2 text-sm text-slate-100 focus:border-indigo-500 focus:outline-none focus:ring focus:ring-indigo-500/40"
									/>
								</label>
							{/each}
</div>
</div>

{#if signup.showSuccessModal}
	<div class="fixed inset-0 z-50 flex items-center justify-center bg-slate-950/80 px-4">
		<div
			class="w-full max-w-2xl space-y-6 rounded-2xl border border-slate-800 bg-slate-900 p-6 shadow-2xl"
			role="dialog"
			aria-modal="true"
			aria-labelledby="signup-success-title"
		>
			<header class="space-y-2 text-center">
				<p class="text-xs uppercase tracking-[0.4em] text-indigo-300">VBytes LAN</p>
				<h2 id="signup-success-title" class="text-2xl font-semibold text-slate-100 sm:text-3xl">
					Anmälan bekräftad
				</h2>
				<p class="text-sm text-slate-300">Du är registrerad till {tournament.title}.</p>
				{#if signup.successRegistrationId}
					<p class="text-xs uppercase tracking-wide text-indigo-200">Anmälan #{signup.successRegistrationId}</p>
				{/if}
			</header>

			<section class="grid gap-4 rounded-2xl border border-slate-800 bg-slate-900/70 p-4 md:grid-cols-2">
				<div class="space-y-2 text-left">
					<h3 class="text-sm font-semibold uppercase tracking-wide text-indigo-200">Turnering</h3>
					<p class="text-sm text-slate-300"><span class="font-medium text-slate-100">Spel:</span> {tournament.game}</p>
					{#if tournament.start_at}
						<p class="text-sm text-slate-300">
							<span class="font-medium text-slate-100">Start:</span>
							{formatDateTime(tournament.start_at) ?? tournament.start_at}
						</p>
					{/if}
					{#if tournament.location}
						<p class="text-sm text-slate-300">
							<span class="font-medium text-slate-100">Plats:</span> {tournament.location}
						</p>
					{/if}
				</div>
				<div class="space-y-2 text-left">
					<h3 class="text-sm font-semibold uppercase tracking-wide text-indigo-200">Format</h3>
					{#if signupConfig.mode === 'team'}
						<p class="text-sm text-slate-300">
							Lag {signupConfig.team_size.min}–{signupConfig.team_size.max} spelare
						</p>
					{:else}
						<p class="text-sm text-slate-300">Individuell anmälan</p>
					{/if}
					{#if tournament.contact}
						<p class="text-sm text-slate-300">
							<span class="font-medium text-slate-100">Kontakt:</span> {tournament.contact}
						</p>
					{/if}
				</div>
			</section>

			<section class="space-y-3">
				<h3 class="text-base font-semibold text-slate-100">Anmälningsuppgifter</h3>
				{#if signupConfig.entry_fields.length === 0}
					<p class="rounded-md border border-dashed border-slate-700 px-4 py-3 text-sm text-slate-300">
						Den här turneringen kräver inga uppgifter utöver spelare.
					</p>
				{:else}
					<div class="grid gap-3 md:grid-cols-2">
						{#each signupConfig.entry_fields as field}
							<div class="rounded-md border border-slate-800 bg-slate-900 px-4 py-3">
								<p class="text-xs uppercase tracking-wide text-indigo-200">{field.label}</p>
								<p class="mt-1 text-sm text-slate-100">{signup.submittedEntry[field.id] || '—'}</p>
							</div>
						{/each}
					</div>
				{/if}
			</section>

			<section class="space-y-3">
				<h3 class="text-base font-semibold text-slate-100">Spelare</h3>
				{#if signupConfig.participant_fields.length === 0}
					{#if signup.submittedParticipants.length === 0}
						<p class="text-sm text-slate-300">Inga spelare angivna.</p>
					{:else}
						<p class="text-sm text-slate-300">Antal spelare: {signup.submittedParticipants.length}</p>
					{/if}
				{:else if signup.submittedParticipants.length === 0}
					<p class="text-sm text-slate-300">Inga spelare angivna.</p>
				{:else}
					<div class="space-y-3">
						{#each signup.submittedParticipants as participant, index}
							<div class="rounded-md border border-slate-800 bg-slate-900 px-4 py-3">
								<p class="text-xs font-semibold uppercase tracking-wide text-indigo-200">Spelare {index + 1}</p>
								<ul class="mt-2 space-y-1 text-sm text-slate-100">
									{#each signupConfig.participant_fields as field}
										<li>
											<span class="font-medium text-slate-300">{field.label}:</span>
											<span class="ml-1">{participant[field.id] || '—'}</span>
										</li>
									{/each}
								</ul>
							</div>
						{/each}
					</div>
				{/if}
			</section>

			<div class="flex justify-center pt-2">
				<a
					href="/"
					class="inline-flex items-center justify-center rounded-full border border-emerald-300 px-5 py-2 text-sm font-semibold text-emerald-200 transition hover:border-emerald-400 hover:bg-emerald-500/10"
				>
					Stäng
				</a>
			</div>
		</div>
	</div>
{/if}

				{/if}

				<div class="space-y-3">
					<div class="flex items-center justify-between">
						<h3 class="text-sm font-semibold uppercase tracking-wide text-slate-400">Spelare</h3>
						{#if signupConfig.mode === 'team'}
							<button
								type="button"
								onclick={addParticipant}
								disabled={!canAddParticipant() || signup.submitting}
								class="rounded-full border border-indigo-300 px-3 py-1 text-xs font-semibold text-indigo-200 transition hover:border-indigo-400 hover:bg-indigo-500/10 disabled:cursor-not-allowed disabled:opacity-60"
							>
								Lägg till spelare
							</button>
						{/if}
					</div>

					{#if signup.participants.length > 0}
						<div class="space-y-4">
							{#each signup.participants as participant, index (index)}
								<div class="space-y-3 rounded-md border border-slate-800 bg-slate-900/60 p-4">
									<div class="flex items-center justify-between">
										<span class="text-sm font-semibold text-slate-200">{participantDisplayName(index)}</span>
										{#if signupConfig.mode === 'team' && canRemoveParticipant()}
											<button
												type="button"
												onclick={() => removeParticipant(index)}
												disabled={signup.submitting}
												class="rounded-full border border-red-300 px-3 py-1 text-xs font-semibold text-red-200 transition hover:border-red-400 hover:bg-red-500/10 disabled:cursor-not-allowed disabled:opacity-60"
											>
												Ta bort
											</button>
										{/if}
									</div>

									{#if signupConfig.participant_fields.length > 0}
										<div class="grid gap-3 md:grid-cols-2">
											{#each signupConfig.participant_fields as field}
												<label class="flex flex-col gap-1 text-sm font-medium text-slate-200">
													<span>{field.label}</span>
													<input
														type={fieldInputType(field.field_type)}
														required={field.required}
														placeholder={field.placeholder ?? ''}
														value={participant[field.id] ?? ''}
														oninput={(event) => (participant[field.id] = (event.currentTarget as HTMLInputElement).value)}
														class="rounded-md border border-slate-700 bg-slate-900 px-3 py-2 text-sm text-slate-100 focus:border-indigo-500 focus:outline-none focus:ring focus:ring-indigo-500/40"
													/>
												</label>
											{/each}
										</div>
									{:else}
										<p class="text-xs text-slate-400">Inga spelarspecifika fält krävs.</p>
									{/if}
								</div>
							{/each}
						</div>
					{/if}
				</div>

		<div class="space-y-2 text-sm">
			{#if signup.error}
				<p class="rounded-md border border-red-400 bg-red-500/10 px-4 py-2 text-red-200">{signup.error}</p>
			{:else if signup.success}
				<p class="rounded-md border border-emerald-400 bg-emerald-500/10 px-4 py-2 text-emerald-200">{signup.success}</p>
			{:else}
				<p class="text-slate-400">Din anmälan skickas direkt till arrangören.</p>
			{/if}
		</div>

				<button
					type="submit"
					disabled={signup.submitting}
					class="inline-flex items-center justify-center rounded-full bg-indigo-500 px-5 py-2 text-sm font-semibold text-white transition hover:bg-indigo-600 disabled:cursor-not-allowed disabled:opacity-60"
				>
					{signup.submitting ? 'Skickar…' : 'Skicka anmälan'}
				</button>
			</form>
		</section>

		<footer class="mt-auto flex items-center justify-between text-xs text-slate-500">
			<p>Senast uppdaterad {formatDateTime(tournament.updated_at) ?? tournament.updated_at}</p>
			<a href="/admin/tournament" class="rounded-full border border-indigo-300 px-4 py-2 font-semibold text-indigo-300 transition hover:border-indigo-400 hover:bg-indigo-50/5">
				Administrera
			</a>
		</footer>
	</div>
</div>
