<script lang="ts">
	import { goto } from '$app/navigation';
	import { page } from '$app/stores';
	import { onMount } from 'svelte';
	import type {
		TournamentFieldType,
		TournamentInfo,
		TournamentSection,
		TournamentSignupConfig,
		TournamentSignupField
	} from '$lib/types';
	import { listenToTournamentEvents } from '$lib/client/tournament-events';

	const props = $props<{ data: { tournaments: TournamentInfo[] } }>();
	const initialTournaments: TournamentInfo[] = props.data.tournaments ?? [];

	type TabKey = 'overview' | 'create' | 'manage';

	type SignupFieldForm = TournamentSignupField & {
		placeholder: string;
	};

	const ATTENDANCE_FIELD_ID = 'attendance-id';
	const ATTENDANCE_FIELD_LABEL = 'Deltagar-ID';
	const ATTENDANCE_FIELD_PLACEHOLDER = 'Ange ditt deltagar-ID från närvarolistan';

	function isAttendanceField(field: { id: string }): boolean {
		return field.id === ATTENDANCE_FIELD_ID;
	}

	function createAttendanceField(): SignupFieldForm {
		return {
			id: ATTENDANCE_FIELD_ID,
			label: ATTENDANCE_FIELD_LABEL,
			field_type: 'text',
			required: true,
			placeholder: ATTENDANCE_FIELD_PLACEHOLDER,
			unique: true
		};
	}

	type SignupConfigForm = {
		mode: 'solo' | 'team';
		team_size: { min: number; max: number };
		entry_fields: SignupFieldForm[];
		participant_fields: SignupFieldForm[];
	};

	type TournamentForm = {
		title: string;
		game: string;
		slug: string;
		tagline: string;
		start_at: string;
		location: string;
		description: string;
		contact: string;
		sections: TournamentSection[];
		signup: SignupConfigForm;
	};

	function createEmptyForm(): TournamentForm {
		return {
			title: '',
			game: '',
			slug: '',
			tagline: '',
			start_at: '',
			location: '',
			description: '',
			contact: '',
			sections: [],
			signup: createDefaultSignup()
		};
	}

	function cloneSections(sections: TournamentSection[]): TournamentSection[] {
		return sections.map((section) => ({ title: section.title, body: section.body }));
	}

	const fieldTypeOptions: { value: TournamentFieldType; label: string }[] = [
		{ value: 'text', label: 'Text' },
		{ value: 'email', label: 'E-post' },
		{ value: 'tel', label: 'Telefon' },
		{ value: 'discord', label: 'Discord' }
	];

	let fieldIdCounter = 0;

	function nextFieldId(label: string) {
		const base = slugify(label) || 'field';
		fieldIdCounter += 1;
		return `${base}-${fieldIdCounter.toString(36)}`;
	}

	function createSignupField(
		label: string,
		field_type: TournamentFieldType = 'text'
	): SignupFieldForm {
		return {
			id: nextFieldId(label),
			label,
			field_type,
			required: true,
			placeholder: '',
			unique: false
		};
	}

	function cloneSignupField(field: TournamentSignupField): SignupFieldForm {
		if (field.id === ATTENDANCE_FIELD_ID) {
			const label = field.label?.trim() || ATTENDANCE_FIELD_LABEL;
			const placeholder = (field.placeholder ?? '').trim() || ATTENDANCE_FIELD_PLACEHOLDER;
			return {
				id: ATTENDANCE_FIELD_ID,
				label,
				field_type: 'text',
				required: true,
				placeholder,
				unique: true
			};
		}
		return {
			id: field.id || nextFieldId(field.label),
			label: field.label,
			field_type: field.field_type ?? 'text',
			required: Boolean(field.required),
			placeholder: field.placeholder ?? '',
			unique: Boolean(field.unique)
		};
	}

	function ensureAttendanceField(fields: SignupFieldForm[]): SignupFieldForm[] {
		let attendanceField: SignupFieldForm | null = null;
		const others: SignupFieldForm[] = [];

		for (const field of fields) {
			if (isAttendanceField(field)) {
				const label = field.label.trim() || ATTENDANCE_FIELD_LABEL;
				const placeholder = field.placeholder.trim() || ATTENDANCE_FIELD_PLACEHOLDER;
				attendanceField = {
					id: ATTENDANCE_FIELD_ID,
					label,
					field_type: 'text',
					required: true,
					placeholder,
					unique: true
				};
			} else {
				others.push(field);
			}
		}

		if (!attendanceField) {
			attendanceField = createAttendanceField();
		}

		return [attendanceField, ...others];
	}

	function createDefaultSignup(): SignupConfigForm {
		return {
			mode: 'solo',
			team_size: { min: 1, max: 1 },
			entry_fields: ensureAttendanceField([createSignupField('Lag / spelarnamn')]),
			participant_fields: []
		};
	}

	function cloneSignupConfig(config: TournamentSignupConfig | null | undefined): SignupConfigForm {
		if (!config) return createDefaultSignup();
		let entry_fields = ensureAttendanceField((config.entry_fields ?? []).map(cloneSignupField));
		let participant_fields = (config.participant_fields ?? []).map(cloneSignupField);
		if (entry_fields.length === 1) {
			entry_fields = ensureAttendanceField([
				...entry_fields,
				createSignupField('Lag / spelarnamn')
			]);
		}
		if (participant_fields.length === 0) {
			participant_fields.push(createSignupField('Spelare'));
		}
		const mode = config.mode === 'team' ? 'team' : 'solo';
		if (mode === 'solo') {
			participant_fields = [];
		}
		return {
			mode,
			team_size: {
				min: config.team_size?.min ?? 1,
				max: config.team_size?.max ?? 1
			},
			entry_fields,
			participant_fields
		};
	}

	function signupFieldKey(index: number, field?: SignupFieldForm) {
		const suffix = field?.id ?? index;
		return `signup-${suffix}`;
	}

	function addEntryField(form: TournamentForm) {
		form.signup.entry_fields = ensureAttendanceField([
			...form.signup.entry_fields,
			createSignupField('Nytt fält')
		]);
	}

	function removeEntryField(form: TournamentForm, index: number) {
		const target = form.signup.entry_fields[index];
		if (!target || isAttendanceField(target)) return;
		const remaining = form.signup.entry_fields.filter((_, idx) => idx !== index);
		form.signup.entry_fields = ensureAttendanceField(remaining);
	}

	function addParticipantField(form: TournamentForm) {
		form.signup.participant_fields = [
			...form.signup.participant_fields,
			createSignupField('Spelarinfo')
		];
	}

	function removeParticipantField(form: TournamentForm, index: number) {
		if (form.signup.participant_fields.length <= 1) return;
		form.signup.participant_fields = form.signup.participant_fields.filter(
			(_, idx) => idx !== index
		);
	}

	function setSignupMode(form: TournamentForm, mode: 'solo' | 'team') {
		form.signup.mode = mode;
		if (mode === 'solo') {
			form.signup.team_size.min = 1;
			form.signup.team_size.max = 1;
			form.signup.participant_fields = [];
		} else {
			if (form.signup.team_size.min < 1) form.signup.team_size.min = 1;
			if (form.signup.team_size.max < form.signup.team_size.min) {
				form.signup.team_size.max = form.signup.team_size.min;
			}
			if (form.signup.participant_fields.length === 0) {
				form.signup.participant_fields = [createSignupField('Spelare')];
			}
		}
	}

	function setTeamSize(form: TournamentForm, key: 'min' | 'max', value: string) {
		const parsed = Number.parseInt(value, 10);
		const fallback = key === 'min' ? 1 : form.signup.team_size.min;
		const numeric = Number.isNaN(parsed) ? fallback : Math.max(1, parsed);
		form.signup.team_size[key] = numeric;
	}

	function slugify(value: string) {
		let slug = value
			.trim()
			.toLowerCase()
			.split('')
			.map((char) => (/[a-z0-9]/.test(char) ? char : '-'))
			.join('');

		while (slug.includes('--')) {
			slug = slug.replace('--', '-');
		}

		slug = slug.replace(/^[-]+|[-]+$/g, '');

		return slug;
	}

	function normalizedSlug(value: string, fallbackTitle: string) {
		const source = value.trim() ? value : fallbackTitle;
		const slug = slugify(source);
		return slug || 'turnering';
	}

	function toLocalInput(value: string | null) {
		if (!value) return '';
		const date = new Date(value);
		if (Number.isNaN(date.getTime())) return '';
		const pad = (num: number) => `${num}`.padStart(2, '0');
		return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
	}

	function toIsoString(value: string) {
		if (!value) return null;
		const date = new Date(value);
		if (Number.isNaN(date.getTime())) return null;
		return date.toISOString();
	}

	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
		});
	}

	function payloadSections(sections: TournamentSection[]) {
		return sections
			.map((section) => ({
				title: section.title.trim(),
				body: section.body.trim()
			}))
			.filter((section) => section.title || section.body);
	}

	function payloadSignup(signup: SignupConfigForm): TournamentSignupConfig {
		const allowedTypes: TournamentFieldType[] = ['text', 'email', 'tel', 'discord'];

		const normalizeField = (field: SignupFieldForm): TournamentSignupField => {
			if (isAttendanceField(field)) {
				const label = field.label.trim() || ATTENDANCE_FIELD_LABEL;
				const placeholder = field.placeholder.trim() || ATTENDANCE_FIELD_PLACEHOLDER;

				return {
					id: ATTENDANCE_FIELD_ID,
					label,
					field_type: 'text',
					required: true,
					placeholder,
					unique: true
				};
			}
			const baseId = field.id.trim() || field.label;
			const id = slugify(baseId) || 'field';
			const label = field.label.trim() || 'Fält';
			const placeholder = field.placeholder.trim();
			const type = allowedTypes.includes(field.field_type) ? field.field_type : 'text';

			return {
				id,
				label,
				field_type: type,
				required: Boolean(field.required),
				placeholder: placeholder ? placeholder : null,
				unique: Boolean(field.unique)
			};
		};

		const toNumber = (value: number) => {
			if (Number.isFinite(value)) {
				return Math.max(1, Math.floor(value));
			}
			return 1;
		};

		const mode = signup.mode === 'team' ? 'team' : 'solo';
		let min = toNumber(signup.team_size.min);
		let max = toNumber(signup.team_size.max);
		if (max < min) max = min;
		if (mode === 'solo') {
			min = 1;
			max = 1;
		}

		const entry_fields = ensureAttendanceField(signup.entry_fields).map(normalizeField);
		const participant_fields = mode === 'team' ? signup.participant_fields.map(normalizeField) : [];

		return {
			mode,
			team_size: { min, max },
			entry_fields,
			participant_fields
		};
	}

	function buildPayload(form: TournamentForm) {
		const slug = normalizedSlug(form.slug, form.title);
		return {
			title: form.title.trim(),
			game: form.game.trim(),
			slug,
			tagline: form.tagline.trim() || null,
			start_at: toIsoString(form.start_at) ?? null,
			location: form.location.trim() || null,
			description: form.description.trim() || null,
			registration_url: null,
			contact: form.contact.trim() || null,
			sections: payloadSections(form.sections),
			signup_config: payloadSignup(form.signup)
		};
	}

	let tournaments = $state<TournamentInfo[]>([]);
	let overviewGameFilter = $state('all');
	const activeTab = $derived((): TabKey => {
		const param = $page.url.searchParams.get('tab');
		return param === 'create' || param === 'manage' ? param : 'overview';
	});
	const slugParam = $derived(() => {
		const value = $page.url.searchParams.get('slug');
		if (!value) return null;
		const trimmed = value.trim();
		return trimmed ? trimmed : null;
	});

	let refreshPromise: Promise<void> | null = null;

	async function refreshTournaments(options: { preferredId?: number | null } = {}) {
		if (refreshPromise) {
			await refreshPromise;
			return;
		}

		const preferredId = options.preferredId ?? null;
		refreshPromise = (async () => {
			try {
				const response = await fetch('/api/tournament');
				if (!response.ok) {
					console.error('Failed to refresh tournaments', await response.text());
					return;
				}
				const data = await response.json();
				const list = (data?.tournaments ?? []) as TournamentInfo[];
				tournaments = list;
				if (preferredId !== null) {
					const match = list.find((item) => item.id === preferredId);
					if (match) {
						manageState.selectedId = match.id;
					}
				}
			} catch (err) {
				console.error('Failed to refresh tournaments', err);
			} finally {
				refreshPromise = null;
			}
		})();

		await refreshPromise;
	}

	function setTab(tab: TabKey, options: { slug?: string | null; replace?: boolean } = {}) {
		const currentTab = activeTab();
		const currentSlug = slugParam();
		const targetSlug = options.slug ?? null;
		if (currentTab === tab && (currentSlug ?? null) === (targetSlug ?? null)) {
			return;
		}

		const url = new URL($page.url);
		if (tab === 'overview') {
			url.searchParams.delete('tab');
		} else {
			url.searchParams.set('tab', tab);
		}

		if (targetSlug) {
			url.searchParams.set('slug', targetSlug);
		} else {
			url.searchParams.delete('slug');
		}

		void goto(`${url.pathname}${url.search}`, {
			replaceState: options.replace ?? false,
			keepFocus: true,
			noScroll: true
		});
	}

	function selectTournament(tournament: TournamentInfo, options: { replace?: boolean } = {}) {
		manageState.selectedId = tournament.id;
		manageState.success = '';
		manageState.error = '';
		setTab('manage', {
			slug: tournament.slug,
			replace: options.replace ?? false
		});
	}

	$effect(() => {
		if (tournaments.length === 0 && initialTournaments.length > 0) {
			tournaments = [...initialTournaments];
		}
	});

	$effect(() => {
		const slug = slugParam();
		if (!slug) return;
		if (activeTab() !== 'manage') {
			setTab('manage', { slug, replace: true });
			return;
		}
		if (tournaments.length === 0) return;
		if (manageState.selectedId !== null) return;
		const match = tournaments.find((item) => item.slug === slug);
		if (match) {
			manageState.selectedId = match.id;
		}
	});

	const availableGames = $derived(() => {
		const set = new Set<string>();
		for (const tournament of tournaments) {
			if (tournament.game) set.add(tournament.game);
		}
		return Array.from(set).sort((a, b) => a.localeCompare(b, 'sv')) satisfies string[];
	});

	$effect(() => {
		const games = availableGames();
		if (overviewGameFilter !== 'all' && !games.includes(overviewGameFilter)) {
			overviewGameFilter = 'all';
		}
	});

	const filteredOverview = $derived(() => {
		return tournaments.filter((tournament) => {
			if (overviewGameFilter !== 'all' && tournament.game !== overviewGameFilter) {
				return false;
			}
			return true;
		}) satisfies TournamentInfo[];
	});

	onMount(() => {
		const stop = listenToTournamentEvents(
			(tournament) => {
				void refreshTournaments({ preferredId: tournament.id });
			},
			(tournamentId) => {
				const preferredId = manageState.selectedId === tournamentId ? null : manageState.selectedId;
				void refreshTournaments({ preferredId: preferredId ?? undefined });
			}
		);
		return () => {
			stop();
		};
	});

	$effect(() => {
		if (tournaments.length === 0 && activeTab() === 'manage') {
			setTab('overview', { replace: true });
		}
	});

	type CreateState = {
		form: TournamentForm;
		saving: boolean;
		success: string;
		error: string;
		autoSlug: boolean;
	};

	type ManageState = {
		form: TournamentForm;
		saving: boolean;
		success: string;
		error: string;
		autoSlug: boolean;
		selectedId: number | null;
	};

	let createState = $state<CreateState>({
		form: createEmptyForm(),
		saving: false,
		success: '',
		error: '',
		autoSlug: true
	});

	$effect(() => {
		const title = createState.form.title;
		if (!createState.autoSlug) return;
		if (!title.trim()) {
			createState.form.slug = '';
			return;
		}
		const next = slugify(title);
		if (next && createState.form.slug !== next) {
			createState.form.slug = next;
		}
	});

	let manageState = $state<ManageState>({
		form: createEmptyForm(),
		saving: false,
		success: '',
		error: '',
		autoSlug: false,
		selectedId: null
	});

	let manageSlug = $state('');
	$effect(() => {
		manageSlug = manageState.form.slug.trim();
	});

	function populateManageForm(tournament: TournamentInfo) {
		manageState.form.title = tournament.title;
		manageState.form.game = tournament.game;
		manageState.form.slug = tournament.slug;
		manageState.form.tagline = tournament.tagline ?? '';
		manageState.form.start_at = toLocalInput(tournament.start_at);
		manageState.form.location = tournament.location ?? '';
		manageState.form.description = tournament.description ?? '';
		manageState.form.contact = tournament.contact ?? '';
		manageState.form.sections = cloneSections(tournament.sections ?? []);
		manageState.form.signup = cloneSignupConfig(tournament.signup_config);
	}

	$effect(() => {
		if (manageState.selectedId === null && tournaments.length > 0) {
			manageState.selectedId = tournaments[0].id;
		}
	});

	$effect(() => {
		const selected = tournaments.find((item) => item.id === manageState.selectedId);
		if (!selected) {
			if (tournaments.length === 0) {
				manageState.selectedId = null;
				manageState.form = createEmptyForm();
			} else {
				manageState.selectedId = tournaments[0].id;
			}
			return;
		}
		populateManageForm(selected);
	});

	$effect(() => {
		if (activeTab() !== 'manage') return;
		const selected = tournaments.find((item) => item.id === manageState.selectedId);
		const currentSlug = slugParam();
		const desiredSlug = selected?.slug ?? null;
		if ((currentSlug ?? null) === (desiredSlug ?? null)) {
			return;
		}
		setTab('manage', { slug: desiredSlug, replace: true });
	});

	function addSection(target: TournamentForm) {
		target.sections = [...target.sections, { title: '', body: '' }];
	}

	function removeSection(target: TournamentForm, index: number) {
		target.sections = target.sections.filter((_, idx) => idx !== index);
	}

	async function handleCreate(event: SubmitEvent) {
		event.preventDefault();
		createState.error = '';
		createState.success = '';

		if (!createState.form.title.trim()) {
			createState.error = 'Ange en titel för turneringen.';
			return;
		}

		if (!createState.form.game.trim()) {
			createState.error = 'Ange vilket spel som spelas.';
			return;
		}

		const payload = buildPayload(createState.form);
		if (!payload.slug) {
			createState.error = 'Ange en giltig slug.';
			return;
		}
		createState.form.slug = payload.slug;

		createState.saving = true;
		try {
			const response = await fetch('/api/tournament', {
				method: 'POST',
				headers: { 'content-type': 'application/json' },
				body: JSON.stringify(payload)
			});
			const text = await response.text();
			if (!response.ok) {
				let message = 'Kunde inte skapa turneringen.';
				try {
					const body = JSON.parse(text);
					message = body.message ?? message;
				} catch {
					if (text) message = text;
				}
				throw new Error(message);
			}

			const body = JSON.parse(text) as { tournament: TournamentInfo };
			if (body?.tournament) {
				createState.success = 'Turneringen skapades.';
				createState.form = createEmptyForm();
				createState.autoSlug = true;
				await refreshTournaments();
			}
		} catch (err) {
			console.error('Failed to create tournament', err);
			createState.error = err instanceof Error ? err.message : 'Ett oväntat fel inträffade.';
		} finally {
			createState.saving = false;
		}
	}

	async function handleUpdate(event: SubmitEvent) {
		event.preventDefault();
		manageState.error = '';
		manageState.success = '';

		if (manageState.selectedId === null) {
			manageState.error = 'Ingen turnering vald.';
			return;
		}

		if (!manageState.form.title.trim()) {
			manageState.error = 'Ange en titel för turneringen.';
			return;
		}

		if (!manageState.form.game.trim()) {
			manageState.error = 'Ange vilket spel som spelas.';
			return;
		}

		const payload = buildPayload(manageState.form);
		if (!payload.slug) {
			manageState.error = 'Ange en giltig slug.';
			return;
		}
		manageState.form.slug = payload.slug;

		manageState.saving = true;
		try {
			const response = await fetch(`/api/tournament/${manageState.selectedId}`, {
				method: 'PUT',
				headers: { 'content-type': 'application/json' },
				body: JSON.stringify(payload)
			});
			const text = await response.text();
			if (!response.ok) {
				let message = 'Kunde inte uppdatera turneringen.';
				try {
					const body = JSON.parse(text);
					message = body.message ?? message;
				} catch {
					if (text) message = text;
				}
				throw new Error(message);
			}

			const body = JSON.parse(text) as { tournament: TournamentInfo };
			if (body?.tournament) {
				manageState.success = 'Turneringen uppdaterades.';
				await refreshTournaments({ preferredId: body.tournament.id });
			}
		} catch (err) {
			console.error('Failed to update tournament', err);
			manageState.error = err instanceof Error ? err.message : 'Ett oväntat fel inträffade.';
		} finally {
			manageState.saving = false;
		}
	}

	async function handleDelete() {
		if (manageState.selectedId === null) {
			return;
		}
		manageState.error = '';
		manageState.success = '';
		manageState.saving = true;
		try {
			const response = await fetch(`/api/tournament/${manageState.selectedId}`, {
				method: 'DELETE'
			});
			const text = await response.text();
			if (!response.ok) {
				let message = 'Kunde inte ta bort turneringen.';
				try {
					const body = JSON.parse(text);
					message = body.message ?? message;
				} catch {
					if (text) message = text;
				}
				throw new Error(message);
			}

			const deletedId = manageState.selectedId;
			tournaments = tournaments.filter((item) => item.id !== deletedId);
			manageState.selectedId = tournaments[0]?.id ?? null;
			manageState.success = 'Turneringen togs bort.';
			await refreshTournaments();
		} catch (err) {
			console.error('Failed to delete tournament', err);
			manageState.error = err instanceof Error ? err.message : 'Ett oväntat fel inträffade.';
		} finally {
			manageState.saving = false;
		}
	}

	function overviewCardSubtitle(tournament: TournamentInfo) {
		const start = formatDateTime(tournament.start_at);
		return start ? `${tournament.game} • ${start}` : tournament.game;
	}

	function registrationSummary(tournament: TournamentInfo) {
		const totalRegistrations = tournament.total_registrations ?? 0;
		const totalParticipants = tournament.total_participants ?? 0;

		if (tournament.signup_config.mode === 'team') {
			if (totalRegistrations === 0) {
				return 'Inga anmälningar ännu';
			}
			const teamLabel = `${totalRegistrations} ${totalRegistrations === 1 ? 'lag' : 'lag'}`;
			const playerLabel = `${totalParticipants} ${totalParticipants === 1 ? 'spelare' : 'spelare'}`;
			return `${teamLabel} · ${playerLabel}`;
		}

		const count = Math.max(totalParticipants, totalRegistrations);
		return count === 0
			? 'Inga anmälningar ännu'
			: `${count} ${count === 1 ? 'spelare' : 'spelare'}`;
	}

	const selectedTournamentInfo = $derived(() => {
		if (manageState.selectedId === null) {
			return null;
		}
		return tournaments.find((item) => item.id === manageState.selectedId) ?? null;
	});

	function sectionKey(index: number) {
		return `section-${index}`;
	}
</script>

<svelte:head>
	<title>Turneringsadmin</title>
</svelte:head>

<div class="space-y-6">
	{#if activeTab() === 'overview'}
		<section class="space-y-5 rounded-lg border border-slate-200 bg-white p-6 shadow-sm">
			<header class="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
				<div>
					<h2 class="text-xl font-semibold text-slate-900">Översikt</h2>
					<p class="text-sm text-slate-600">Filtrera turneringar och öppna deras publika sidor.</p>
				</div>
				<div class="flex flex-wrap items-center gap-3">
					<label class="flex items-center gap-2 text-sm text-slate-600">
						<span>Spel</span>
						<select
							bind:value={overviewGameFilter}
							class="rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-indigo-500 focus:ring focus:ring-indigo-100 focus:outline-none"
						>
							<option value="all">Alla spel</option>
							{#each availableGames() as game}
								<option value={game}>{game}</option>
							{/each}
						</select>
					</label>
				</div>
			</header>

			{#if filteredOverview().length > 0}
				<div class="grid gap-4 md:grid-cols-2">
					{#each filteredOverview() as tournament (tournament.id)}
						<article
							class="flex h-full flex-col justify-between rounded-xl border border-slate-200 bg-white p-5 shadow-sm"
						>
							<div class="space-y-2">
								<p class="text-xs font-semibold tracking-[0.3em] text-indigo-400 uppercase">
									{tournament.game}
								</p>
								<h3 class="text-lg font-semibold text-slate-900">{tournament.title}</h3>
								{#if tournament.tagline}
									<p class="text-sm text-slate-600">{tournament.tagline}</p>
								{/if}
								{#if tournament.start_at}
									<p class="text-xs text-slate-500">
										{formatDateTime(tournament.start_at) ?? tournament.start_at}
									</p>
								{/if}
								<p class="text-xs text-slate-500">{registrationSummary(tournament)}</p>
							</div>
							<div class="mt-4 flex flex-wrap gap-2">
								<a
									href={`/tournament/${tournament.slug}`}
									target="_blank"
									rel="noreferrer"
									class="rounded-full bg-indigo-600 px-4 py-2 text-xs font-semibold tracking-wide text-white uppercase transition hover:bg-indigo-700"
								>
									Öppna sida
								</a>
								{#if tournament.slug}
									<a
										href={`/admin/tournament/${tournament.slug}/registrations`}
										class="rounded-full border border-slate-300 px-4 py-2 text-xs font-semibold tracking-wide text-slate-600 uppercase transition hover:bg-slate-100"
									>
										Visa anmälningar
									</a>
								{/if}
								<button
									type="button"
									onclick={() => selectTournament(tournament)}
									class="rounded-full border border-slate-300 px-4 py-2 text-xs font-semibold tracking-wide text-slate-600 uppercase transition hover:bg-slate-100"
								>
									Redigera
								</button>
							</div>
						</article>
					{/each}
				</div>
			{:else}
				<p
					class="rounded-md border border-dashed border-slate-300 px-4 py-6 text-center text-sm text-slate-500"
				>
					Inga turneringar hittades. Skapa en ny via fliken "Skapa ny".
				</p>
			{/if}
		</section>
	{:else if activeTab() === 'create'}
		<section class="space-y-6 rounded-lg border border-slate-200 bg-white p-6 shadow-sm">
			<header class="space-y-1">
				<h2 class="text-xl font-semibold text-slate-900">Skapa turnering</h2>
				<p class="text-sm text-slate-600">
					Fälten används även för att automatiskt bygga anmälningssidan.
				</p>
			</header>

			<form class="space-y-5" onsubmit={handleCreate}>
				<div class="grid gap-4 md:grid-cols-2">
					<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
						<span>Titel</span>
						<input
							required
							type="text"
							bind:value={createState.form.title}
							class="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"
						/>
					</label>
					<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
						<span>Spel</span>
						<input
							required
							type="text"
							bind:value={createState.form.game}
							placeholder="Counter-Strike 2, Valorant, Rocket League …"
							class="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"
						/>
					</label>
					<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
						<span>Slug (URL)</span>
						<input
							required
							type="text"
							value={createState.form.slug}
							oninput={(event) => {
								const value = (event.currentTarget as HTMLInputElement).value;
								createState.autoSlug = false;
								createState.form.slug = slugify(value);
							}}
							placeholder="ex. valorant-final"
							class="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"
						/>
					</label>
					<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
						<span>Starttid</span>
						<input
							type="datetime-local"
							bind:value={createState.form.start_at}
							class="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"
						/>
					</label>
					<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
						<span>Tagline</span>
						<input
							type="text"
							bind:value={createState.form.tagline}
							placeholder="En kort slogan"
							class="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"
						/>
					</label>
					<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
						<span>Plats</span>
						<input
							type="text"
							bind:value={createState.form.location}
							placeholder="Arena, adress eller digital länk"
							class="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"
						/>
					</label>
					<label class="flex flex-col gap-1 text-sm font-medium text-slate-700 md:col-span-2">
						<span>Beskrivning</span>
						<textarea
							rows={4}
							bind:value={createState.form.description}
							placeholder="Berätta vad turneringen handlar om, format, regler och mer."
							class="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"
						></textarea>
					</label>
					<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
						<span>Kontakt</span>
						<input
							type="text"
							bind:value={createState.form.contact}
							placeholder="E-post, Discord eller telefon"
							class="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"
						/>
					</label>
				</div>

				<section class="space-y-3">
					<header class="flex items-center justify-between">
						<h3 class="text-sm font-semibold tracking-wide text-slate-500 uppercase">
							Sektioner för anmälningssidan
						</h3>
						<button
							type="button"
							onclick={() => addSection(createState.form)}
							class="rounded-full border border-indigo-200 px-3 py-1 text-xs font-semibold text-indigo-600 transition hover:border-indigo-400 hover:bg-indigo-50"
						>
							Lägg till sektion
						</button>
					</header>

					{#if createState.form.sections.length === 0}
						<p
							class="rounded-md border border-dashed border-slate-300 px-4 py-4 text-sm text-slate-500"
						>
							Lägg till sektioner som beskriver regler, format eller andra detaljer.
						</p>
					{:else}
						<div class="space-y-4">
							{#each createState.form.sections as section, index (sectionKey(index))}
								<div class="rounded-md border border-slate-200 p-4">
									<div class="flex items-start justify-between gap-3">
										<label class="flex-1 text-sm font-medium text-slate-700">
											<span class="block text-xs tracking-wide text-slate-500 uppercase">Titel</span
											>
											<input
												type="text"
												bind:value={section.title}
												class="mt-1 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"
											/>
										</label>
										<button
											type="button"
											onclick={() => removeSection(createState.form, index)}
											class="mt-1 shrink-0 rounded-full border border-red-200 px-3 py-1 text-xs font-semibold text-red-600 transition hover:border-red-400 hover:bg-red-50"
										>
											Ta bort
										</button>
									</div>
									<label class="mt-3 block text-sm font-medium text-slate-700">
										<span class="block text-xs tracking-wide text-slate-500 uppercase"
											>Innehåll</span
										>
										<textarea
											rows={3}
											bind:value={section.body}
											class="mt-1 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"
										></textarea>
									</label>
								</div>
							{/each}
						</div>
					{/if}
				</section>

				<section class="space-y-4 rounded-lg border border-slate-200 bg-white p-6 shadow-sm">
					<header class="space-y-1">
						<h3 class="text-sm font-semibold tracking-wide text-slate-500 uppercase">
							Anmälningsinställningar
						</h3>
						<p class="text-sm text-slate-600">
							Ställ in vad som krävs när spelare eller lag registrerar sig.
						</p>
					</header>

					<div class="grid gap-4 md:grid-cols-2">
						<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
							<span>Format</span>
							<select
								value={createState.form.signup.mode}
								onchange={(event) =>
									setSignupMode(
										createState.form,
										(event.currentTarget as HTMLSelectElement).value as 'solo' | 'team'
									)}
								class="rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-indigo-500 focus:ring focus:ring-indigo-100 focus:outline-none"
							>
								<option value="solo">Individuell</option>
								<option value="team">Lag</option>
							</select>
						</label>
						{#if createState.form.signup.mode === 'team'}
							<div class="grid grid-cols-2 gap-3">
								<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
									<span>Min. spelare</span>
									<input
										type="number"
										min={1}
										value={createState.form.signup.team_size.min}
										oninput={(event) =>
											setTeamSize(
												createState.form,
												'min',
												(event.currentTarget as HTMLInputElement).value
											)}
										class="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"
									/>
								</label>
								<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
									<span>Max. spelare</span>
									<input
										type="number"
										min={createState.form.signup.team_size.min}
										value={createState.form.signup.team_size.max}
										oninput={(event) =>
											setTeamSize(
												createState.form,
												'max',
												(event.currentTarget as HTMLInputElement).value
											)}
										class="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"
									/>
								</label>
							</div>
						{/if}
					</div>

					<div class="space-y-3">
						<div class="flex items-center justify-between">
							<h4 class="text-sm font-semibold tracking-wide text-slate-500 uppercase">
								Anmälningsfält
							</h4>
							<button
								type="button"
								onclick={() => addEntryField(createState.form)}
								class="rounded-full border border-indigo-200 px-3 py-1 text-xs font-semibold text-indigo-600 transition hover:border-indigo-400 hover:bg-indigo-50"
							>
								Lägg till fält
							</button>
						</div>

						{#if createState.form.signup.entry_fields.length === 0}
							<p
								class="rounded-md border border-dashed border-slate-300 px-4 py-4 text-sm text-slate-500"
							>
								Ange vilka uppgifter laget eller spelaren ska fylla i vid anmälan.
							</p>
						{:else}
							<div class="space-y-4">
								{#each createState.form.signup.entry_fields as field, index (signupFieldKey(index, field))}
									<div class="space-y-3 rounded-md border border-slate-200 p-4">
										<div class="grid gap-3 md:grid-cols-[1fr,160px,120px,auto] md:items-end">
											<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
												<span>Etikett</span>
												<input
													type="text"
													bind:value={field.label}
													class="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"
												/>
											</label>
											<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
												<span class="flex items-center gap-2">
													Typ
													{#if isAttendanceField(field)}
														<span
															class="rounded-full bg-indigo-50 px-2 py-0.5 text-xs font-semibold text-indigo-600"
															>låst</span
														>
													{/if}
												</span>
												<select
													bind:value={field.field_type}
													disabled={isAttendanceField(field)}
													class="rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-indigo-500 focus:ring focus:ring-indigo-100 focus:outline-none"
												>
													{#each fieldTypeOptions as option}
														<option value={option.value}>{option.label}</option>
													{/each}
												</select>
											</label>
											<label class="flex items-center gap-2 text-sm font-medium text-slate-700">
												<input
													type="checkbox"
													bind:checked={field.required}
													disabled={isAttendanceField(field)}
													class="h-4 w-4 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500"
												/>
												<span>Krävs</span>
											</label>
											<label class="flex items-center gap-2 text-sm font-medium text-slate-700">
												<input
													type="checkbox"
													bind:checked={field.unique}
													disabled={isAttendanceField(field)}
													class="h-4 w-4 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500"
												/>
												<span>Måste vara unik</span>
											</label>
											<button
												type="button"
												onclick={() => removeEntryField(createState.form, index)}
												disabled={isAttendanceField(field) ||
													createState.form.signup.entry_fields.length <= 1}
												class="rounded-full border border-red-200 px-3 py-1 text-xs font-semibold text-red-600 transition hover:border-red-400 hover:bg-red-50 disabled:cursor-not-allowed disabled:opacity-60"
											>
												Ta bort
											</button>
										</div>
										<label class="block text-sm font-medium text-slate-700">
											<span class="block text-xs tracking-wide text-slate-500 uppercase"
												>Plats­hållare (valfritt)</span
											>
											<input
												type="text"
												bind:value={field.placeholder}
												class="mt-1 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"
											/>
											{#if isAttendanceField(field)}
												<p class="mt-2 text-xs text-slate-500">
													Detta fält kopplar anmälan till närvarolistan och kan inte tas bort.
												</p>
											{/if}
										</label>
									</div>
								{/each}
							</div>
						{/if}
					</div>

					{#if createState.form.signup.mode === 'team'}
						<div class="space-y-3">
							<div class="flex items-center justify-between">
								<h4 class="text-sm font-semibold tracking-wide text-slate-500 uppercase">
									Spelaruppgifter
								</h4>
								<button
									type="button"
									onclick={() => addParticipantField(createState.form)}
									class="rounded-full border border-indigo-200 px-3 py-1 text-xs font-semibold text-indigo-600 transition hover:border-indigo-400 hover:bg-indigo-50"
								>
									Lägg till fält
								</button>
							</div>

							{#if createState.form.signup.participant_fields.length === 0}
								<p
									class="rounded-md border border-dashed border-slate-300 px-4 py-4 text-sm text-slate-500"
								>
									Lägg till fält för varje spelare, t.ex. nick eller kontaktuppgifter.
								</p>
							{:else}
								<div class="space-y-4">
									{#each createState.form.signup.participant_fields as field, index (signupFieldKey(index, field))}
										<div class="space-y-3 rounded-md border border-slate-200 p-4">
											<div class="grid gap-3 md:grid-cols-[1fr,160px,120px,auto] md:items-end">
												<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
													<span>Etikett</span>
													<input
														type="text"
														bind:value={field.label}
														class="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"
													/>
												</label>
												<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
													<span>Typ</span>
													<select
														bind:value={field.field_type}
														class="rounded-md border border-slate-300 px-3 py-2 text-sm focus:border-indigo-500 focus:ring focus:ring-indigo-100 focus:outline-none"
													>
														{#each fieldTypeOptions as option}
															<option value={option.value}>{option.label}</option>
														{/each}
													</select>
												</label>
												<label class="flex items-center gap-2 text-sm font-medium text-slate-700">
													<input
														type="checkbox"
														bind:checked={field.required}
														class="h-4 w-4 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500"
													/>
													<span>Krävs</span>
												</label>
												<label class="flex items-center gap-2 text-sm font-medium text-slate-700">
													<input
														type="checkbox"
														bind:checked={field.unique}
														class="h-4 w-4 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500"
													/>
													<span>Måste vara unik</span>
												</label>
												<button
													type="button"
													onclick={() => removeParticipantField(createState.form, index)}
													disabled={createState.form.signup.participant_fields.length <= 1}
													class="rounded-full border border-red-200 px-3 py-1 text-xs font-semibold text-red-600 transition hover:border-red-400 hover:bg-red-50 disabled:cursor-not-allowed disabled:opacity-60"
												>
													Ta bort
												</button>
											</div>
											<label class="block text-sm font-medium text-slate-700">
												<span class="block text-xs tracking-wide text-slate-500 uppercase"
													>Plats­hållare (valfritt)</span
												>
												<input
													type="text"
													bind:value={field.placeholder}
													class="mt-1 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"
												/>
											</label>
										</div>
									{/each}
								</div>
							{/if}
						</div>
					{/if}
				</section>

				<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
					<div class="text-sm text-slate-500">
						{#if createState.success}
							<span class="text-emerald-600">{createState.success}</span>
						{:else if createState.error}
							<span class="text-red-600">{createState.error}</span>
						{:else if createState.saving}
							<span>Sparar…</span>
						{:else}
							<span>Förhandsgranska och spara turneringen.</span>
						{/if}
					</div>
					<button
						type="submit"
						disabled={createState.saving}
						class="inline-flex items-center justify-center rounded-full bg-indigo-600 px-5 py-2 text-sm font-semibold text-white transition hover:bg-indigo-700 disabled:cursor-not-allowed disabled:opacity-70"
					>
						{createState.saving ? 'Skapar…' : 'Skapa turnering'}
					</button>
				</div>
			</form>

			{#if createState.form.title.trim()}
				<section class="rounded-lg border border-slate-200 bg-white p-6 shadow-sm">
					<h3 class="text-lg font-semibold text-slate-900">Förhandsvisning av anmälningssida</h3>
					<p class="mt-2 text-sm text-slate-500">
						Visas för deltagare på /tournament/{createState.form.slug || 'slug'}.
					</p>

					<div class="mt-5 space-y-4 rounded-2xl bg-slate-900 p-6 text-slate-100">
						<div class="space-y-1">
							<p class="text-xs tracking-[0.4em] text-indigo-300 uppercase">
								{createState.form.game || 'Spel'}
							</p>
							<h4 class="text-2xl font-bold sm:text-3xl">{createState.form.title || 'Titel'}</h4>
							{#if createState.form.tagline.trim()}
								<p class="text-sm text-slate-300">{createState.form.tagline}</p>
							{/if}
						</div>
						{#if createState.form.start_at}
							<p class="text-sm text-indigo-200">
								Start {formatDateTime(new Date(createState.form.start_at).toISOString()) ?? ''}
							</p>
						{/if}
						{#if createState.form.location.trim()}
							<p class="text-sm text-slate-200">Plats: {createState.form.location}</p>
						{/if}
						{#if createState.form.description.trim()}
							<p class="text-sm whitespace-pre-line text-slate-200">
								{createState.form.description}
							</p>
						{/if}
						{#if createState.form.sections.length > 0}
							<div class="space-y-3">
								{#each payloadSections(createState.form.sections) as section, index (sectionKey(index))}
									<div>
										<p class="text-sm font-semibold text-indigo-200">{section.title}</p>
										<p class="text-sm whitespace-pre-line text-slate-200">{section.body}</p>
									</div>
								{/each}
							</div>
						{/if}
						{#if createState.form.contact.trim()}
							<p class="text-xs tracking-wide text-indigo-100 uppercase">
								Kontakt: {createState.form.contact}
							</p>
						{/if}
						{#if createState.form.signup.entry_fields.length > 0}
							<div class="space-y-2 rounded-lg border border-slate-800 bg-slate-900/70 p-3">
								<p class="text-xs font-semibold tracking-wide text-indigo-200 uppercase">
									Anmälningsfält
								</p>
								<ul class="space-y-1 text-sm text-slate-200">
									{#each createState.form.signup.entry_fields as field}
										<li>
											{field.label} · {field.field_type === 'text' ? 'Text' : field.field_type}
											{field.required ? '• obligatoriskt' : ''}
											{field.unique ? '• unikt' : ''}
										</li>
									{/each}
								</ul>
							</div>
						{/if}
						{#if createState.form.signup.mode === 'team' && createState.form.signup.participant_fields.length > 0}
							<div class="space-y-2 rounded-lg border border-slate-800 bg-slate-900/70 p-3">
								<p class="text-xs font-semibold tracking-wide text-indigo-200 uppercase">
									Spelaruppgifter
								</p>
								<ul class="space-y-1 text-sm text-slate-200">
									{#each createState.form.signup.participant_fields as field}
										<li>
											{field.label} · {field.field_type === 'text' ? 'Text' : field.field_type}
											{field.required ? '• obligatoriskt' : ''}
											{field.unique ? '• unikt' : ''}
										</li>
									{/each}
								</ul>
							</div>
						{/if}
					</div>
				</section>
			{/if}
		</section>
	{:else}
		<section class="space-y-6 rounded-lg border border-slate-200 bg-white p-6 shadow-sm">
			<header class="space-y-1">
				<h2 class="text-xl font-semibold text-slate-900">Hantera turneringar</h2>
				<p class="text-sm text-slate-600">
					Välj en turnering i listan för att uppdatera innehållet.
				</p>
				{#if selectedTournamentInfo()}
					{@const selected = selectedTournamentInfo()!}
					<p class="text-sm text-indigo-600">{registrationSummary(selected)}</p>
				{/if}
			</header>

			<div class="flex flex-col gap-6 lg:flex-row lg:items-start">
				<aside class="w-full max-w-xs space-y-3 rounded-lg border border-slate-200 bg-slate-50 p-4">
					<div class="flex items-center justify-between">
						<h3 class="text-sm font-semibold tracking-wide text-slate-500 uppercase">
							Turneringar
						</h3>
						<button
							type="button"
							onclick={() => setTab('create')}
							class="rounded-full border border-indigo-200 px-3 py-1 text-xs font-semibold text-indigo-600 transition hover:border-indigo-400 hover:bg-indigo-50"
						>
							Ny
						</button>
					</div>

					<ul class="space-y-2">
						{#each tournaments as tournament (tournament.id)}
							<li>
								<button
									type="button"
									onclick={() => selectTournament(tournament, { replace: true })}
									class={`w-full rounded-md px-3 py-2 text-left text-sm font-medium transition ${
										manageState.selectedId === tournament.id
											? 'bg-indigo-600 text-white shadow'
											: 'bg-white text-slate-700 hover:bg-slate-100'
									}`}
								>
									{tournament.title}
									<span class="block text-xs font-normal text-indigo-200/90"
										>{overviewCardSubtitle(tournament)}</span
									>
								</button>
								{#if tournament.slug}
									<div class="mt-2 flex flex-wrap gap-2 text-xs">
										<a
											href={`/admin/tournament/${tournament.slug}/registrations`}
											class="inline-flex items-center rounded-full border border-slate-300 px-3 py-1 font-semibold text-slate-600 transition hover:border-slate-400 hover:bg-slate-100"
										>
											Visa anmälningar
										</a>
										<a
											href={`/tournament/${tournament.slug}`}
											target="_blank"
											rel="noreferrer"
											class="inline-flex items-center rounded-full border border-indigo-300 px-3 py-1 font-semibold text-indigo-600 transition hover:border-indigo-400 hover:bg-indigo-50"
										>
											Publik sida
										</a>
									</div>
								{/if}
							</li>
						{:else}
							<li
								class="rounded-md border border-dashed border-slate-300 px-3 py-6 text-center text-sm text-slate-500"
							>
								Inga sparade turneringar ännu.
							</li>
						{/each}
					</ul>
				</aside>

				<div class="flex-1 space-y-5">
					<form class="space-y-5" onsubmit={handleUpdate}>
						<div class="grid gap-4 md:grid-cols-2">
							<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
								<span>Titel</span>
								<input
									required
									type="text"
									bind:value={manageState.form.title}
									class="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"
								/>
							</label>
							<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
								<span>Spel</span>
								<input
									required
									type="text"
									bind:value={manageState.form.game}
									class="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"
								/>
							</label>
							<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
								<span>Slug (URL)</span>
								<input
									required
									type="text"
									value={manageState.form.slug}
									oninput={(event) => {
										const value = (event.currentTarget as HTMLInputElement).value;
										manageState.form.slug = slugify(value);
									}}
									class="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"
								/>
							</label>
							<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
								<span>Starttid</span>
								<input
									type="datetime-local"
									bind:value={manageState.form.start_at}
									class="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"
								/>
							</label>
							<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
								<span>Tagline</span>
								<input
									type="text"
									bind:value={manageState.form.tagline}
									class="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"
								/>
							</label>
							<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
								<span>Plats</span>
								<input
									type="text"
									bind:value={manageState.form.location}
									class="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"
								/>
							</label>
							<label class="flex flex-col gap-1 text-sm font-medium text-slate-700 md:col-span-2">
								<span>Beskrivning</span>
								<textarea
									rows={4}
									bind:value={manageState.form.description}
									class="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"
								></textarea>
							</label>
							<label class="flex flex-col gap-1 text-sm font-medium text-slate-700">
								<span>Kontakt</span>
								<input
									type="text"
									bind:value={manageState.form.contact}
									class="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"
								/>
							</label>
						</div>

						<section class="space-y-3">
							<header class="flex items-center justify-between">
								<h3 class="text-sm font-semibold tracking-wide text-slate-500 uppercase">
									Sektioner
								</h3>
								<button
									type="button"
									onclick={() => addSection(manageState.form)}
									class="rounded-full border border-indigo-200 px-3 py-1 text-xs font-semibold text-indigo-600 transition hover:border-indigo-400 hover:bg-indigo-50"
								>
									Lägg till sektion
								</button>
							</header>

							{#if manageState.form.sections.length === 0}
								<p
									class="rounded-md border border-dashed border-slate-300 px-4 py-4 text-sm text-slate-500"
								>
									Inga sektioner ännu. Lägg till regler, format eller andra detaljer.
								</p>
							{:else}
								<div class="space-y-4">
									{#each manageState.form.sections as section, index (sectionKey(index))}
										<div class="rounded-md border border-slate-200 p-4">
											<div class="flex items-start justify-between gap-3">
												<label class="flex-1 text-sm font-medium text-slate-700">
													<span class="block text-xs tracking-wide text-slate-500 uppercase"
														>Titel</span
													>
													<input
														type="text"
														bind:value={section.title}
														class="mt-1 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"
													/>
												</label>
												<button
													type="button"
													onclick={() => removeSection(manageState.form, index)}
													class="mt-1 shrink-0 rounded-full border border-red-200 px-3 py-1 text-xs font-semibold text-red-600 transition hover:border-red-400 hover:bg-red-50"
												>
													Ta bort
												</button>
											</div>
											<label class="mt-3 block text-sm font-medium text-slate-700">
												<span class="block text-xs tracking-wide text-slate-500 uppercase"
													>Innehåll</span
												>
												<textarea
													rows={3}
													bind:value={section.body}
													class="mt-1 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"
												></textarea>
											</label>
										</div>
									{/each}
								</div>
							{/if}
						</section>

						<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
							<div class="text-sm text-slate-500">
								{#if manageState.success}
									<span class="text-emerald-600">{manageState.success}</span>
								{:else if manageState.error}
									<span class="text-red-600">{manageState.error}</span>
								{:else if manageState.saving}
									<span>Sparar…</span>
								{:else}
									<span>Ändringarna publiceras direkt.</span>
								{/if}
							</div>
							<div class="flex flex-wrap gap-2">
								{#if manageState.selectedId !== null}
									<button
										type="button"
										onclick={handleDelete}
										disabled={manageState.saving}
										class="rounded-full border border-red-200 px-4 py-2 text-sm font-semibold text-red-600 transition hover:border-red-400 hover:bg-red-50 disabled:cursor-not-allowed disabled:opacity-60"
									>
										Ta bort
									</button>
								{/if}
								<button
									type="submit"
									disabled={manageState.saving}
									class="inline-flex items-center justify-center rounded-full bg-indigo-600 px-5 py-2 text-sm font-semibold text-white transition hover:bg-indigo-700 disabled:cursor-not-allowed disabled:opacity-70"
								>
									{manageState.saving
										? 'Sparar…'
										: manageState.selectedId === null
											? 'Skapa turnering'
											: 'Spara ändringar'}
								</button>
							</div>
						</div>
					</form>

					{#if manageState.form.title.trim()}
						<section class="rounded-lg border border-slate-200 bg-white p-6 shadow-sm">
							<h3 class="text-lg font-semibold text-slate-900">
								Förhandsvisning av anmälningssida
							</h3>
							<p class="mt-2 text-sm text-slate-500">
								Visas för deltagare på /tournament/{manageState.form.slug || 'slug'}.
							</p>

							<div class="mt-5 space-y-4 rounded-2xl bg-slate-900 p-6 text-slate-100">
								<div class="space-y-1">
									<p class="text-xs tracking-[0.4em] text-indigo-300 uppercase">
										{manageState.form.game || 'Spel'}
									</p>
									<h4 class="text-2xl font-bold sm:text-3xl">
										{manageState.form.title || 'Titel'}
									</h4>
									{#if manageState.form.tagline.trim()}
										<p class="text-sm text-slate-300">{manageState.form.tagline}</p>
									{/if}
								</div>
								{#if manageState.form.start_at}
									<p class="text-sm text-indigo-200">
										Start {formatDateTime(new Date(manageState.form.start_at).toISOString()) ?? ''}
									</p>
								{/if}
								{#if manageState.form.location.trim()}
									<p class="text-sm text-slate-200">Plats: {manageState.form.location}</p>
								{/if}
								{#if manageState.form.description.trim()}
									<p class="text-sm whitespace-pre-line text-slate-200">
										{manageState.form.description}
									</p>
								{/if}
								{#if manageState.form.sections.length > 0}
									<div class="space-y-3">
										{#each payloadSections(manageState.form.sections) as section, index (sectionKey(index))}
											<div>
												<p class="text-sm font-semibold text-indigo-200">{section.title}</p>
												<p class="text-sm whitespace-pre-line text-slate-200">{section.body}</p>
											</div>
										{/each}
									</div>
								{/if}
								{#if manageState.form.contact.trim()}
									<p class="text-xs tracking-wide text-indigo-100 uppercase">
										Kontakt: {manageState.form.contact}
									</p>
								{/if}
								{#if manageState.form.signup.entry_fields.length > 0}
									<div class="space-y-2 rounded-lg border border-slate-800 bg-slate-900/70 p-3">
										<p class="text-xs font-semibold tracking-wide text-indigo-200 uppercase">
											Anmälningsfält
										</p>
										<ul class="space-y-1 text-sm text-slate-200">
											{#each manageState.form.signup.entry_fields as field}
												<li>
													{field.label} · {field.field_type === 'text' ? 'Text' : field.field_type}
													{field.required ? '• obligatoriskt' : ''}
													{field.unique ? '• unikt' : ''}
												</li>
											{/each}
										</ul>
									</div>
								{/if}
								{#if manageState.form.signup.mode === 'team' && manageState.form.signup.participant_fields.length > 0}
									<div class="space-y-2 rounded-lg border border-slate-800 bg-slate-900/70 p-3">
										<p class="text-xs font-semibold tracking-wide text-indigo-200 uppercase">
											Spelaruppgifter
										</p>
										<ul class="space-y-1 text-sm text-slate-200">
											{#each manageState.form.signup.participant_fields as field}
												<li>
													{field.label} · {field.field_type === 'text' ? 'Text' : field.field_type}
													{field.required ? '• obligatoriskt' : ''}
													{field.unique ? '• unikt' : ''}
												</li>
											{/each}
										</ul>
									</div>
								{/if}
							</div>
						</section>
					{/if}

					{#if manageState.selectedId !== null}
						<div class="flex flex-wrap gap-2">
							<a
								href={manageSlug ? `/tournament/${manageSlug}` : '#'}
								target={manageSlug ? '_blank' : undefined}
								rel={manageSlug ? 'noreferrer' : undefined}
								class={`inline-flex items-center justify-center rounded-full border px-4 py-2 text-sm font-semibold transition ${
									manageSlug
										? 'border-indigo-300 text-indigo-600 hover:border-indigo-400 hover:bg-indigo-50'
										: 'pointer-events-none border-indigo-200 text-indigo-300 opacity-60'
								}`}
							>
								Visa publika sidan
							</a>
						</div>
					{/if}
				</div>
			</div>
		</section>
	{/if}
</div>
