<script lang="ts">
	import MdiIcon from './MdiIcon.svelte';
	import { t } from '$lib/i18n';
	import { portal } from '$lib/portal';

	let { open = false, title = '', onclose, children } = $props<{
		open: boolean;
		title?: string;
		onclose: () => void;
		children: import('svelte').Snippet;
	}>();

	let visible = $state(false);
	let mounted = $state(false);
	let panelEl = $state<HTMLDivElement | undefined>();
	let previouslyFocused: HTMLElement | null = null;
	let closeTimer: ReturnType<typeof setTimeout> | null = null;

	const uniqueId = `modal-${Math.random().toString(36).slice(2, 9)}`;
	const TRANSITION_MS = 250;

	$effect(() => {
		if (open) {
			if (closeTimer) {
				clearTimeout(closeTimer);
				closeTimer = null;
			}
			previouslyFocused = document.activeElement as HTMLElement | null;
			mounted = true;
			requestAnimationFrame(() => {
				visible = true;
				// Focus first focusable element inside the modal
				requestAnimationFrame(() => {
					const focusable = panelEl?.querySelector<HTMLElement>(
						'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
					);
					focusable?.focus();
				});
			});
		} else if (mounted) {
			visible = false;
			// Restore focus to the previously focused element
			if (previouslyFocused && typeof previouslyFocused.focus === 'function') {
				previouslyFocused.focus();
				previouslyFocused = null;
			}
			if (closeTimer) clearTimeout(closeTimer);
			closeTimer = setTimeout(() => {
				mounted = false;
				closeTimer = null;
			}, TRANSITION_MS);
		}
	});

	function handleKeydown(e: KeyboardEvent) {
		if (e.key === 'Escape') {
			onclose();
			return;
		}
		// Focus trap: Tab / Shift+Tab
		if (e.key === 'Tab' && panelEl) {
			const focusableElements = panelEl.querySelectorAll<HTMLElement>(
				'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
			);
			if (focusableElements.length === 0) return;
			const first = focusableElements[0];
			const last = focusableElements[focusableElements.length - 1];
			if (e.shiftKey) {
				if (document.activeElement === first) {
					e.preventDefault();
					last.focus();
				}
			} else {
				if (document.activeElement === last) {
					e.preventDefault();
					first.focus();
				}
			}
		}
	}

	function handleBackdropKeydown(e: KeyboardEvent) {
		if (e.key === 'Escape') onclose();
	}
</script>

<svelte:window onkeydown={open ? handleKeydown : undefined} />

{#if mounted}
	<div use:portal class="modal-portal-root">
		<div
			class="modal-backdrop"
			class:visible
			onclick={onclose}
			onkeydown={handleBackdropKeydown}
			role="button"
			tabindex="-1"
			aria-label={t('common.close')}
		>
			<!-- svelte-ignore a11y_click_events_have_key_events -->
			<div
				bind:this={panelEl}
				class="modal-panel"
				class:visible
				role="dialog"
				tabindex="-1"
				aria-modal="true"
				aria-labelledby="modal-title-{uniqueId}"
				onclick={(e) => e.stopPropagation()}
			>
				<div class="modal-head">
					<h3 id="modal-title-{uniqueId}" class="modal-title">{title}</h3>
					<button class="modal-close" onclick={onclose} aria-label={t('common.close')}>
						<MdiIcon name="mdiClose" size={18} />
					</button>
				</div>
				<div class="modal-body">
					{@render children()}
				</div>
			</div>
		</div>
	</div>
{/if}

<style>
	.modal-portal-root {
		position: fixed;
		inset: 0;
		z-index: 9999;
	}

	.modal-backdrop {
		position: absolute;
		inset: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		background: rgba(0, 0, 0, 0);
		backdrop-filter: blur(0px);
		transition: background 0.25s ease, backdrop-filter 0.25s ease;
	}

	.modal-backdrop.visible {
		background: rgba(0, 0, 0, 0.55);
		backdrop-filter: blur(8px) saturate(120%);
		-webkit-backdrop-filter: blur(8px) saturate(120%);
	}

	.modal-panel {
		--modal-solid-bg: #131520;
		background: var(--modal-solid-bg);
		border: 1px solid var(--color-rule-strong);
		border-radius: 18px;
		width: 100%;
		max-width: 32rem;
		max-height: 80vh;
		margin: 1rem;
		display: flex;
		flex-direction: column;
		opacity: 0;
		transform: translateY(12px) scale(0.97);
		transition: opacity 0.25s ease, transform 0.25s ease;
		box-shadow:
			var(--shadow-card),
			0 30px 80px -20px rgba(0, 0, 0, 0.6);
		position: relative;
		overflow: hidden;
	}
	.modal-panel::after {
		content: '';
		position: absolute; inset: 0;
		border-radius: inherit;
		pointer-events: none;
		background: linear-gradient(180deg, var(--color-highlight), transparent 30%);
		opacity: 0.4;
	}

	:global([data-theme="light"]) .modal-panel { --modal-solid-bg: #fafafe; }

	.modal-panel.visible {
		opacity: 1;
		transform: translateY(0) scale(1);
	}

	.modal-head {
		position: relative;
		z-index: 1;
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 1.4rem 1.5rem 1rem;
	}

	.modal-title {
		font-family: var(--font-display);
		font-weight: 400;
		font-size: 1.4rem;
		letter-spacing: -0.02em;
		color: var(--color-foreground);
		margin: 0;
	}

	.modal-body {
		position: relative;
		z-index: 1;
		padding: 0 1.5rem 1.5rem;
		overflow-y: auto;
		overscroll-behavior: contain;
	}

	.modal-close {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 2.5rem;
		height: 2.5rem;
		border-radius: 10px;
		border: 1px solid transparent;
		background: transparent;
		color: var(--color-muted-foreground);
		cursor: pointer;
		transition: all 0.15s ease;
	}

	.modal-close:hover {
		background: var(--color-glass-strong);
		border-color: var(--color-border);
		color: var(--color-foreground);
	}
</style>
