<script module>
	// Store for managing dialog state
	export let dialogStore = $state({
		open: false,
		title: 'Dialog',
		message: '',
		buttons: ['OK', 'Cancel'],
		type: 'confirm',
		resolve: null
	});

	/**
	 * Show a dialog and return a promise that resolves with the clicked button text
	 * @param {Object} options
	 * @param {string} [options.title='Dialog']
	 * @param {string} [options.message='']
	 * @param {string[]} [options.buttons=['OK', 'Cancel']]
	 * @param {'confirm'|'warning'|'error'|'info'} [options.type='confirm']
	 * @returns {Promise<string|null>} Button text or null if dismissed
	 */
	export function show(options = {}) {
		return new Promise((resolve) => {
			// Close any existing dialog
			if (dialogStore.resolve) {
				dialogStore.resolve(null);
			}

			dialogStore.open = true;
			dialogStore.title = options.title || 'Dialog';
			dialogStore.message = options.message || '';
			dialogStore.buttons = options.buttons || ['OK', 'Cancel'];
			dialogStore.type = options.type || 'confirm';
			dialogStore.resolve = resolve;
		});
	}

	/**
	 * Close the current dialog with a result
	 * @param {string|null} result
	 */
	export function closeDialog(result = null) {
		if (dialogStore.resolve) {
			dialogStore.resolve(result);
		}
		dialogStore.open = false;
		dialogStore.resolve = null;
	}

	// Convenience methods for common dialog types
	export const dialogs = {
		/** Show a confirmation dialog */
		confirm: (message, title = 'Confirm') =>
			show({ title, message, buttons: ['Confirm', 'Cancel'], type: 'confirm' }).then(
				(result) => result === 'Confirm'
			),

		/** Show a warning dialog */
		warning: (message, title = 'Warning') =>
			show({ title, message, buttons: ['Continue', 'Cancel'], type: 'warning' }).then(
				(result) => result === 'Continue'
			),

		/** Show an error dialog */
		error: (message, title = 'Error') =>
			show({ title, message, buttons: ['OK'], type: 'error' }).then(() => {}),

		/** Show an info dialog */
		info: (message, title = 'Information') =>
			show({ title, message, buttons: ['OK'], type: 'info' }).then(() => {})
	};
</script>

<script>
	import { onMount, onDestroy } from 'svelte';
	import { fly, fade } from 'svelte/transition';
	import Button from '$lib/components/Button.svelte';

	// Props for declarative usage
	let {
		open = false,
		title = 'Dialog',
		message = '',
		buttons = ['OK', 'Cancel'],
		type = 'confirm',
		onresult = null // callback function
	} = $props();

	// Determine if we're using imperative mode (via store)
	let usingStore = $state(false);
	let dialogRef = $state(null);

	// Module store is accessible via module exports
	// dialogStore and closeDialog are defined in module script

	// Computed state based on mode
	const currentOpen = $derived(usingStore ? dialogStore.open : open);
	const currentTitle = $derived(usingStore ? dialogStore.title : title);
	const currentMessage = $derived(usingStore ? dialogStore.message : message);
	const currentButtons = $derived(usingStore ? dialogStore.buttons : buttons);
	const currentType = $derived(usingStore ? dialogStore.type : type);

	// Switch to store mode when store dialog opens
	$effect(() => {
		if (dialogStore.open && !open) {
			usingStore = true;
		} else if (!dialogStore.open && usingStore) {
			// Delay reset to allow animations
			setTimeout(() => {
				if (!dialogStore.open) {
					usingStore = false;
				}
			}, 200);
		}
	});

	function handleButtonClick(button) {
		if (usingStore) {
			closeDialog(button);
		} else {
			open = false;
			// Call result callback for declarative usage
			onresult?.(button);
		}
	}

	function handleClose() {
		if (usingStore) {
			closeDialog(null);
		} else {
			open = false;
			onresult?.(null);
		}
	}

	function handleKeydown(event) {
		if (event.key === 'Escape') {
			event.preventDefault();
			handleClose();
		} else if (event.key === 'Enter' && currentButtons.length > 0) {
			// Enter triggers the first button
			handleButtonClick(currentButtons[0]);
		}
	}

	function handleBackdropClick(event) {
		if (event.target === event.currentTarget) {
			handleClose();
		}
	}

	// Manage keyboard listeners
	onMount(() => {
		if (currentOpen) {
			document.addEventListener('keydown', handleKeydown);
		}
	});

	onDestroy(() => {
		document.removeEventListener('keydown', handleKeydown);
	});

	$effect(() => {
		if (currentOpen) {
			document.addEventListener('keydown', handleKeydown);
			// Focus dialog for keyboard navigation
			setTimeout(() => {
				if (dialogRef) {
					dialogRef.focus();
				}
			}, 10);
		} else {
			document.removeEventListener('keydown', handleKeydown);
		}
	});

	// Helper to determine button style based on text and dialog type
	function getButtonStyle(buttonText) {
		const lower = buttonText.toLowerCase();
		if (lower.includes('cancel') || lower.includes('no') || lower.includes('dismiss')) {
			return 'black';
		}
		if (currentType === 'warning' || currentType === 'error' || currentType === 'info') {
			if (
				lower.includes('ok') ||
				lower.includes('yes') ||
				lower.includes('confirm') ||
				lower.includes('continue')
			) {
				return 'accent';
			}
		}
		if (currentType === 'confirm') {
			if (lower.includes('ok') || lower.includes('yes') || lower.includes('confirm')) {
				return 'accent';
			}
		}
		return 'black';
	}
</script>

{#if currentOpen}
	<div
		class="dialog-backdrop"
		in:fade={{ duration: 150 }}
		out:fade={{ duration: 150 }}
		onclick={handleBackdropClick}
		aria-hidden="true"
	>
		<div
			class="dialog-container"
			in:fly={{ duration: 200, y: 20 }}
			out:fade={{ duration: 150 }}
			bind:this={dialogRef}
			tabindex="-1"
			role="dialog"
			aria-modal="true"
			aria-labelledby="dialog-title"
			aria-describedby="dialog-message"
		>
			<div class="dialog-header">
				<h3 id="dialog-title" class="dialog-title">{currentTitle}</h3>
				<div class="dialog-type-indicator {currentType}"></div>
			</div>
			<div class="dialog-content">
				<p id="dialog-message" class="dialog-content-text">{currentMessage}</p>
			</div>
			<div class="dialog-actions">
				{#each currentButtons as button (button)}
					<Button style={getButtonStyle(button)} onclick={() => handleButtonClick(button)}>
						{button}
					</Button>
				{/each}
			</div>
		</div>
	</div>
{/if}

<style>
	.dialog-backdrop {
		position: fixed;
		top: 0;
		left: 0;
		width: 100vw;
		height: 100vh;
		background-color: rgba(0, 0, 0, 0.5);
		display: flex;
		align-items: center;
		justify-content: center;
		z-index: 9999;
	}

	.dialog-container {
		background-color: var(--light);
		border-radius: 0.5rem;
		padding: 1.5rem;
		min-width: 300px;
		max-width: 500px;
		max-height: 80vh;
		overflow-y: auto;
		display: flex;
		flex-direction: column;
		gap: 1rem;
		outline: none;
		border: 2px solid var(--);
	}

	.dialog-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 1rem;
		padding-bottom: 0.5rem;
	}

	.dialog-title {
		margin: 0;
		font-size: 1.2rem;
		font-weight: 500;
		color: var(--black);
	}

	.dialog-type-indicator {
		width: 10px;
		height: 10px;
		border-radius: 50%;
		flex-shrink: 0;
	}

	.dialog-type-indicator.confirm {
		background-color: var(--accent);
	}

	.dialog-type-indicator.warning {
		background-color: var(--warning);
	}

	.dialog-type-indicator.error {
		background-color: var(--error);
	}

	.dialog-type-indicator.info {
		background-color: var(--warning);
	}

	.dialog-content {
		flex: 1;
		color: var(--black);
		line-height: 1.5;
		max-height: 50vh;
		overflow-y: auto;
		padding: 0.5rem 0;
	}

	.dialog-content p {
		margin: 0;
	}

	.dialog-actions {
		display: flex;
		justify-content: flex-end;
		gap: 0.75rem;
		padding-top: 0.5rem;
	}
</style>
