<script lang="ts">
	import { game, currentSet, totalQuestions, playedCount, isFinished, screen } from '$lib/stores/game';
	import { questionSets, findQuestion } from '$lib/question-sets';
	import { celebrate } from '$lib/confetti';
	import type { QuestionRef } from '$lib/types';
	import QuestionSetSelector from '$lib/components/QuestionSetSelector.svelte';
	import GameBoard from '$lib/components/GameBoard.svelte';
	import ScorePanel from '$lib/components/ScorePanel.svelte';
	import HostControls from '$lib/components/HostControls.svelte';
	import QuestionModal from '$lib/components/QuestionModal.svelte';
	import GameResult from '$lib/components/GameResult.svelte';
	import ConfirmDialog from '$lib/components/ConfirmDialog.svelte';

	// ---- Состояние подтверждений ----
	let confirmState = $state<{ kind: 'newGame' | 'changeSet' | null }>({ kind: null });

	// Сигнал для анимации счёта.
	let bumpSignal = $state(0);

	/** Текущий открытый вопрос (объект), если экран вопроса активен. */
	const currentQuestionData = $derived.by(() => {
		const set = $currentSet;
		const ref = $game.current;
		if (!set || !ref) return null;
		return findQuestion(set, ref) ?? null;
	});

	/** Раскрывал ли ведущий подсказку для текущего открытого вопроса. */
	const hintUsedForCurrent = $derived.by(() => {
		const ref = $game.current;
		if (!ref) return false;
		return $game.hintUsed.includes(ref);
	});

	// ---- Действия ведущего ----

	function selectSet(id: string) {
		game.selectQuestionSet(id);
	}

	function openQuestion(ref: QuestionRef) {
		game.openQuestion(ref);
	}

	function closeQuestion() {
		game.closeQuestion();
	}

	function awardQuestion(points: number) {
		const ref = $game.current;
		if (!ref) return;
		game.awardQuestion(ref, points);
		bumpSignal++;
		// Праздничное конфетти — засчитанный ответ!
		celebrate();
	}

	function rejectQuestion() {
		const ref = $game.current;
		if (!ref) return;
		game.rejectQuestion(ref);
	}

	/** Ведущий раскрыл подсказку по текущему вопросу — сохраняем в состоянии. */
	function markCurrentHintUsed() {
		const ref = $game.current;
		if (!ref) return;
		game.markHintUsed(ref);
	}

	function randomQuestion() {
		const set = $currentSet;
		if (!set) return;
		const unplayed: QuestionRef[] = [];
		for (const cat of set.categories) {
			for (const q of cat.questions) {
				const ref = `${cat.id}:${q.id}`;
				if (!$game.played.includes(ref)) unplayed.push(ref);
			}
		}
		if (unplayed.length === 0) return;
		const pick = unplayed[Math.floor(Math.random() * unplayed.length)];
		openQuestion(pick);
	}

	// Подтверждаемые действия — только если игра уже началась (есть прогресс).
	const hasProgress = $derived($game.score > 0 || $game.played.length > 0);

	function askNewGame() {
		if (hasProgress) confirmState = { kind: 'newGame' };
		else game.newGame();
	}

	function askChangeSet() {
		if (hasProgress) confirmState = { kind: 'changeSet' };
		else game.changeSet();
	}

	function confirmAction() {
		if (confirmState.kind === 'newGame') game.newGame();
		else if (confirmState.kind === 'changeSet') game.changeSet();
		confirmState = { kind: null };
	}

	function cancelAction() {
		confirmState = { kind: null };
	}

	// Прогресс в процентах для полоски.
	const progressPct = $derived(
		$totalQuestions > 0 ? Math.round(($playedCount / $totalQuestions) * 100) : 0
	);
</script>

<!-- ===================== Экран выбора набора ===================== -->
{#if $screen === 'select'}
	<QuestionSetSelector sets={questionSets} onSelect={selectSet} />
{:else if $screen === 'result'}
	<GameResult
		score={$game.score}
		playedCount={$playedCount}
		onPlayAgain={() => game.newGame()}
		onChangeSet={() => game.changeSet()}
	/>
{:else if $screen === 'board' || $screen === 'question'}
	{@const set = $currentSet}
	{#if set}
		<!-- Полноэкранная раскладка: всегда влезает во вьюпорт без скролла.
		     h-dvh = «настоящая» высота вьюпорта (учитывает моб. адресную строку).
		     flex-col + board во flex-1/min-h-0 забирает всё оставшееся место. -->
		<div
			class="mx-auto flex h-[100dvh] w-full max-w-[1400px] flex-col gap-3 px-4 py-4 sm:gap-4 sm:px-6 sm:py-5"
		>
			<!-- Шапка табло -->
			<header class="flex flex-wrap items-center justify-between gap-3 sm:gap-4">
				<div class="flex min-w-0 items-center gap-3">
					<span class="text-2xl sm:text-3xl">🌙</span>
					<div class="min-w-0">
						<div
							class="flex items-center gap-2 text-[10px] font-semibold uppercase tracking-widest text-plum-300/70 sm:text-xs"
						>
							📂 Набор вопросов
						</div>
						<h1
							class="truncate font-bold text-white"
							style="font-size: clamp(1.1rem, 2.4vw, 2rem)"
						>
							{set.title}
						</h1>
					</div>
				</div>
				<ScorePanel score={$game.score} bumpSignal={bumpSignal} />
			</header>

			<!-- Прогресс -->
			<div class="shrink-0">
				<div class="mb-1 flex items-center justify-between text-xs text-night-50/50">
					<span>🎯 Прогресс · {$playedCount} из {$totalQuestions}</span>
					<span>{progressPct}%</span>
				</div>
				<div class="h-2 w-full overflow-hidden rounded-full bg-white/5">
					<div
						class="h-full rounded-full bg-gradient-to-r from-mint-400 via-gold-400 to-ember-400 transition-all duration-500 ease-out"
						style="width: {progressPct}%"
					></div>
				</div>
			</div>

			<!-- Само табло — забирает всё свободное место по высоте -->
			<main class="min-h-0 flex-1">
				<GameBoard set={set} played={$game.played} onOpenQuestion={openQuestion} />
			</main>

			<!-- Управление ведущего -->
			<footer class="shrink-0">
				<HostControls
					set={set}
					played={$game.played}
					onRandom={randomQuestion}
					onNewGame={askNewGame}
					onChangeSet={askChangeSet}
				/>
			</footer>
		</div>
	{/if}
{/if}

<!-- ===================== Модальный экран вопроса ===================== -->
{#if $screen === 'question' && currentQuestionData}
	<QuestionModal
		category={currentQuestionData.category}
		question={currentQuestionData.question}
		hintUsed={hintUsedForCurrent}
		onMarkHintUsed={markCurrentHintUsed}
		onAward={awardQuestion}
		onReject={rejectQuestion}
		onClose={closeQuestion}
	/>
{/if}

<!-- ===================== Диалог подтверждения ===================== -->
<ConfirmDialog
	open={confirmState.kind !== null}
	title={confirmState.kind === 'changeSet' ? 'Сменить набор?' : 'Начать новую игру?'}
	message={confirmState.kind === 'changeSet'
		? 'Текущая партия будет завершена, и вы вернётесь к выбору набора. Прогресс не сохранится.'
		: 'Счёт и сыгранные вопросы будут сброшены для этого набора.'}
	confirmLabel={confirmState.kind === 'changeSet' ? 'Сменить набор' : 'Начать заново'}
	onConfirm={confirmAction}
	onCancel={cancelAction}
/>
