<script lang="ts">
/**
 * @file ae_comp__modal_journal_export.svelte
 * @description Modal component for bulk exporting journal entries.
 * Allows exporting entries using various templates (Markdown, HTML, JSON).
 * @author One Sky IT
 */

import { Modal } from 'flowbite-svelte';
import {
    Code,
    Copy,
    Download,
    FileJson,
    FileType,
    Settings2
} from '@lucide/svelte';
import { ae_util } from '$lib/ae_utils/ae_utils';
import type { ae_JournalEntry, ae_Journal } from '$lib/types/ae_types';
import {
    EXPORT_TEMPLATES,
    type ExportTemplate
} from '$lib/ae_journals/ae_journals_export_templates';

interface Props {
    open: boolean;
    entries: ae_JournalEntry[];
    journal?: ae_Journal;
    on_close: () => void;
}

let {
    open = $bindable(false),
    entries = [],
    journal,
    on_close
}: Props = $props();

// State
let selected_template_id: string = $state('standard_markdown');
let export_preview: string = $state('');
let export_count: number = $derived(entries.length);

const templates = Object.values(EXPORT_TEMPLATES);
const selected_template = $derived(
    EXPORT_TEMPLATES[selected_template_id as keyof typeof EXPORT_TEMPLATES] ||
        EXPORT_TEMPLATES.standard_markdown
);

// Auto-select template based on journal type when modal opens
$effect(() => {
    if (open && journal?.type_code) {
        if (
            journal.type_code === 'personal_log' &&
            EXPORT_TEMPLATES.personal_log
        ) {
            selected_template_id = 'personal_log';
        } else if (
            journal.type_code === 'amazon_vine' &&
            EXPORT_TEMPLATES.amazon_vine
        ) {
            selected_template_id = 'amazon_vine';
        }
    }
});

// Re-generate preview when entries or template changes
$effect(() => {
    if (open && entries.length > 0) {
        generate_preview();
    }
});

function generate_preview() {
    if (!selected_template) return;
    export_preview = selected_template.formatter(entries);
}

/**
 * Downloads the generated content as a file.
 */
function handle_download() {
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const filename = `journal_export_${timestamp}.${selected_template.extension}`;
    const blob = new Blob([export_preview], {
        type: 'text/plain;charset=utf-8'
    });

    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
}

/**
 * Copies the generated content to the clipboard.
 */
async function handle_copy() {
    try {
        await navigator.clipboard.writeText(export_preview);
        alert('Content copied to clipboard!');
    } catch (err) {
        console.error('Failed to copy:', err);
        alert('Failed to copy to clipboard.');
    }
}
</script>

<Modal
    title="Export Journal Entries"
    bind:open
    autoclose={false}
    size="xl"
    class="w-full">
    <div class="space-y-4">
        <div
            class="flex items-center justify-between rounded-lg bg-blue-50 p-4 text-blue-800 dark:bg-blue-900/20 dark:text-blue-200">
            <div>
                <strong>Ready to Export:</strong>
                {export_count} entries.
            </div>
            {#if journal}
                <div class="text-xs opacity-70">
                    Journal Type: <span class="font-mono"
                        >{journal.type_code || 'standard'}</span>
                </div>
            {/if}
        </div>

        <!-- Template Selection -->
        <div class="space-y-2">
            <label class="label flex items-center gap-2">
                <Settings2 size="1em" />
                <span class="label-text font-bold">Select Export Template</span>
            </label>
            <div class="grid grid-cols-2 gap-2 md:grid-cols-3 lg:grid-cols-5">
                {#each templates as template (template.id)}
                    <button
                        type="button"
                        class="btn preset-outlined-surface flex h-24 flex-col items-center justify-center gap-1 border-2 p-2 text-center {selected_template_id ===
                        template.id
                            ? 'border-primary-500 bg-primary-50 dark:bg-primary-900/20'
                            : 'opacity-60'}"
                        onclick={() => {
                            selected_template_id = template.id;
                            generate_preview();
                        }}>
                        {#if template.extension === 'json'}
                            <FileJson size="1.5em" />
                        {:else if template.extension === 'html'}
                            <Code size="1.5em" />
                        {:else}
                            <FileType size="1.5em" />
                        {/if}
                        <span class="text-xs leading-tight font-bold"
                            >{template.name}</span>
                        <span class="text-[10px] opacity-70"
                            >.{template.extension}</span>
                    </button>
                {/each}
            </div>
        </div>

        <!-- Preview Area -->
        <div class="form-control">
            <div class="label flex items-center justify-between">
                <span class="label-text">Preview</span>
                <span class="text-[10px] tracking-widest uppercase opacity-50"
                    >{selected_template.name}</span>
            </div>
            <textarea
                class="textarea h-64 bg-gray-50 font-mono text-xs dark:bg-gray-900"
                readonly
                value={export_preview.substring(0, 5000) +
                    (export_preview.length > 5000
                        ? '\n... (truncated for preview)'
                        : '')}></textarea>
        </div>

        <!-- Actions -->
        <div class="modal-action flex items-center justify-between">
            <button
                type="button"
                class="btn preset-tonal-secondary"
                onclick={on_close}>Close</button>

            <div class="flex gap-2">
                <button
                    type="button"
                    class="btn preset-tonal-primary"
                    onclick={handle_copy}>
                    <Copy class="mr-2" size="1.2em" /> Copy to Clipboard
                </button>
                <button
                    type="button"
                    class="btn preset-filled-primary"
                    onclick={handle_download}>
                    <Download class="mr-2" size="1.2em" /> Download File
                </button>
            </div>
        </div>
    </div>
</Modal>
