<script lang="ts">
    // WARNING: This is deprecated. Do not use!

    import { run } from 'svelte/legacy';

    // This will be the wrapper for the CodeMirror editor. It should hide most of the configuration requirements.
    // WARNING: This has not been fully updated to Svelte version 5. It is a work in progress.
    // *** Import Svelte version 5 specific
    import { browser } from '$app/environment';

    import { onMount, onDestroy } from 'svelte';
    import { ensureCodeMirrorModules } from '../elements/codemirror_modules';

    interface Props {
        // Props
        content?: string;
        new_content?: string;
        editorView?: any; // Added to interface
        // export let language: Extension = markdown(); // javascript()
        theme_mode?: string; // 'dark' | 'light'
        extensions?: any[]; // Changed to any[] because Extension type is not directly available here
        editable?: boolean;
        readonly?: boolean;
        placeholder?: string;
        show_line_numbers?: boolean;
        wrap_lines?: boolean;
        use_tab?: boolean;
        tab_size?: number;
        class?: string;
    }

    let {
        content = 'test test test test',
        new_content = $bindable(),
        editorView = $bindable(), // Exposed for external control
        theme_mode = $bindable('light'),
        extensions = [],
        editable = true,
        readonly = false,
        placeholder = 'Start typing...',
        show_line_numbers = false,
        wrap_lines = true,
        use_tab = true,
        tab_size = 4,
        class: classes = ''
    }: Props = $props();

    let editor_element: HTMLDivElement | undefined = $state();
    // let editorView: any = $state(); // Removed redundant declaration
    let cm_modules: any = $state(); // To hold the dynamically loaded CodeMirror modules
    let editor_extensions: any[] = $state([]);

    async function initializeCodeMirror() {
        if (!browser) return;

        cm_modules = await ensureCodeMirrorModules();
        if (!cm_modules) return;

        // Reactive declaration for extensions
        editor_extensions = [
            // Core extensions
            cm_modules.highlightSpecialChars(),
            cm_modules.history(),
            cm_modules.foldGutter(),
            cm_modules.drawSelection(),
            cm_modules.dropCursor(),
            cm_modules.EditorState_allowMultipleSelections.of(true),
            cm_modules.indentOnInput(),
            cm_modules.bracketMatching(),
            cm_modules.closeBrackets(),
            cm_modules.autocompletion(),
            cm_modules.rectangularSelection(),
            cm_modules.crosshairCursor(),
            cm_modules.highlightActiveLine(),
            cm_modules.highlightActiveLineGutter(),
            cm_modules.keymap.of([
                ...cm_modules.defaultKeymap,
                ...cm_modules.searchKeymap,
                ...cm_modules.historyKeymap,
                ...cm_modules.foldKeymap,
                ...cm_modules.completionKeymap,
                ...cm_modules.lintKeymap
            ]),
            cm_modules.markdown({
                base: cm_modules.markdownLanguage,
                codeLanguages: cm_modules.languages
            }),
            theme_mode == 'dark' ? cm_modules.oneDark : cm_modules.EditorView.baseTheme(),
            cm_modules.EditorView.contentAttributes.of({ spellcheck: 'true' }), // Enable spell check

            // Sync document changes back to Svelte
            cm_modules.EditorView.updateListener.of((update: any) => {
                if (update.docChanged) {
                    new_content = update.state.doc.toString();
                }
            }),

            // Conditional extensions based on props
            editable ? cm_modules.EditorView.editable.of(true) : null,
            readonly ? cm_modules.EditorState.readOnly.of(true) : null,
            placeholder ? cm_modules.placeholderExt(placeholder) : null,
            show_line_numbers ? cm_modules.lineNumbers() : null,
            wrap_lines ? cm_modules.EditorView_lineWrapping : null,
            use_tab ? cm_modules.keymap.of([cm_modules.indentWithTab]) : null,
            tab_size ? cm_modules.indentUnit.of(' '.repeat(tab_size)) : null,

            ...extensions // Add any custom extensions passed in props
        ].filter(Boolean);

        if (!editor_element) {
            console.error('Editor element not found.');
            return;
        }

        editorView = new cm_modules.EditorView({
            state: cm_modules.EditorState.create({
                doc: content,
                extensions: editor_extensions
            }),
            parent: editor_element as HTMLElement
        });
    }

    // Initialize CodeMirror on mount
    onMount(async () => {
        await initializeCodeMirror();
    });

    // Clean up on destroy
    onDestroy(() => {
        editorView?.destroy();
    });

    // Update editor content when `content` prop changes
    $effect(() => {
        if (editorView && content !== editorView.state.doc.toString()) {
            editorView.dispatch({
                changes: { from: 0, to: editorView.state.doc.length, insert: content || '' }
            });
        }
    });
</script>

{#if browser}
    <!-- flex flex-col flex-wrap items-center justify-center -->
    <div
        bind:this={editor_element}
        class="codemirror-wrapper h-100 max-h-full w-100 max-w-6xl {classes}"
    ></div>
{:else}
    <div class="scm-waiting {classes}">
        <div class="scm-waiting__loading scm-loading">
            <p class="scm-loading__text">Loading editor...</p>
        </div>

        <pre class="scm-pre cm-editor">{content}</pre>
    </div>
{/if}

<style>
    /* .codemirror-wrapper :global(.cm-focused) {
    outline: none;
} */

    .codemirror-wrapper {
        flex-grow: 1;
        /* flex-shrink: 1; */
        /* flex-basis: 100%; */

        /* font-size: 1rem; */
        width: 100%;
        max-width: 100%;
        height: 100%;
        max-height: 100%;
        /* overflow: auto; */
        /* background-color: var(--cm-background); */

        text-wrap: wrap;
        overflow-wrap: break-word;
    }
    .codemirror-wrapper :global(.cm-editor) {
        /* font-size: .8rem; */
        text-wrap: wrap;
        overflow-wrap: break-word;

        /* max-width: 100%; */
        /* max-height: 100%; */

        /* overflow: auto; */

        /* width: 100%; */
        /* height: 100%; */

        /* background-color: var(--cm-background); */
        /* color: var(--cm-text); */
    }

    /* .codemirror-wrapper :global(.cm-gutters) {
    background-color: var(--cm-gutter-background);
    color: var(--cm-gutter-text);
}
.codemirror-wrapper :global(.cm-gutter) {
    background-color: var(--cm-gutter-background);
    color: var(--cm-gutter-text);
}
.codemirror-wrapper :global(.cm-gutterElement) {
    background-color: var(--cm-gutter-background);
    color: var(--cm-gutter-text);
} */
</style>
