<script lang="ts">
    import { onMount, onDestroy } from 'svelte';

    interface Props {
        open?: boolean;
        title?: string;
        autoclose?: boolean;
        size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl';
        placement?: 'top-center' | 'center' | 'bottom-center';
        class_li?: string; // Additional classes for the dialog
        header?: import('svelte').Snippet;
        children?: import('svelte').Snippet;
        footer?: import('svelte').Snippet;
    }

    let {
        open = $bindable(false),
        title = '',
        autoclose = true,
        size = 'md',
        placement = 'center',
        class_li = '',
        header,
        children,
        footer
    }: Props = $props();

    let dialog_element: HTMLDialogElement;

    // Open/close dialog reactively
    $effect(() => {
        if (dialog_element) {
            if (open) {
                dialog_element.showModal();
            } else {
                dialog_element.close();
            }
        }
    });

    onMount(() => {
        // Handle backdrop click to close (if autoclose is true)
        dialog_element.addEventListener('click', (event) => {
            if (autoclose && event.target === dialog_element) {
                open = false;
            }
        });

        // Handle Escape key to close
        const handle_keydown = (event: KeyboardEvent) => {
            if (event.key === 'Escape' && open) {
                event.preventDefault(); // Prevent default browser escape behavior (e.g., page back)
                open = false;
            }
        };
        window.addEventListener('keydown', handle_keydown);

        onDestroy(() => {
            window.removeEventListener('keydown', handle_keydown);
        });
    });

    // Determine max-width based on size prop
    let max_width_class = $derived(
        size === 'sm'
            ? 'max-w-sm'
            : size === 'md'
              ? 'max-w-md'
              : size === 'lg'
                ? 'max-w-lg'
                : size === 'xl'
                  ? 'max-w-xl'
                  : size === '2xl'
                    ? 'max-w-2xl'
                    : size === '3xl'
                      ? 'max-w-3xl'
                      : size === '4xl'
                        ? 'max-w-4xl'
                        : size === '5xl'
                          ? 'max-w-5xl'
                          : size === '6xl'
                            ? 'max-w-6xl'
                            : size === '7xl'
                              ? 'max-w-7xl'
                              : 'max-w-md'
    );

    // Determine placement classes
    let placement_class = $derived(
        placement === 'top-center'
            ? 'justify-center items-start pt-[5vh]'
            : placement === 'center'
              ? 'justify-center items-center'
              : placement === 'bottom-center'
                ? 'justify-center items-end pb-[5vh]'
                : 'justify-center items-center' // Default to center
    );
</script>

<dialog
    bind:this={dialog_element}
    class="
        p-0 bg-transparent overflow-visible
        backdrop:bg-black/50 backdrop:backdrop-blur-sm
        "
    onclose={() => (open = false)}
>
    <div
        class="
            bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-200 rounded-lg shadow-xl
            flex flex-col
            mx-auto
            {max_width_class}
            w-full
            {class_li}
            "
    >
        <!-- Modal Header -->
        {#if title || header}
            <header
                class="flex items-center justify-between border-b border-gray-200 p-4 dark:border-gray-700"
            >
                {#if header}
                    {@render header()}
                {:else}
                    <h3 class="text-xl font-semibold">{title}</h3>
                {/if}
                <button
                    onclick={() => (open = false)}
                    class="rounded-full p-1 hover:bg-gray-200 dark:hover:bg-gray-700"
                    title="Close modal"
                >
                    <svg
                        xmlns="http://www.w3.org/2000/svg"
                        class="h-6 w-6"
                        fill="none"
                        viewBox="0 0 24 24"
                        stroke="currentColor"
                    >
                        <path
                            stroke-linecap="round"
                            stroke-linejoin="round"
                            stroke-width="2"
                            d="M6 18L18 6M6 6l12 12"
                        />
                    </svg>
                </button>
            </header>
        {/if}

        <!-- Modal Body -->
        <main class="max-h-[70vh] overflow-y-auto p-4">
            {#if children}
                {@render children()}
            {/if}
        </main>

        <!-- Modal Footer -->
        {#if footer}
            <footer class="border-t border-gray-200 p-4 dark:border-gray-700">
                {@render footer()}
            </footer>
        {/if}
    </div>
</dialog>

<style lang="postcss">
    dialog {
        display: flex; /* Override default to allow flexbox positioning */
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        position: fixed;
    }

    dialog[open] {
        opacity: 0;
        animation: fade-in 0.15s forwards ease-out;
    }

    dialog:not([open]) {
        opacity: 1;
        animation: fade-out 0.15s forwards ease-out;
    }

    @keyframes fade-in {
        from {
            opacity: 0;
        }
        to {
            opacity: 1;
        }
    }

    @keyframes fade-out {
        from {
            opacity: 1;
        }
        to {
            opacity: 0;
            pointer-events: none; /* Disable interaction while fading out */
        }
    }
</style>
