<script lang="ts">
    import { onMount } from "svelte";
    import { UploadOutline } from "flowbite-svelte-icons";
    import * as monaco from "monaco-editor";

    monaco.editor.defineTheme("forge-dark", {
        base: "vs-dark",
        inherit: true,
        rules: [],
        colors: {
            "editor.background": "#1E1F22FF",
        },
    });
    let {
        stream_data,
        height,
        save,
    }: {
        stream_data: string;
        height: number;
        save: (updated_data: string) => void;
    } = $props();

    let editorContainer: HTMLElement;
    let editor: monaco.editor.IStandaloneCodeEditor;

    let isEdited = $state(false);
    let last_data: string | undefined = $state(undefined);

    onMount(() => {
        editor = monaco.editor.create(editorContainer, {
            value: "",
            language: "plaintext",
            theme: "forge-dark",
            minimap: { enabled: false },
            scrollBeyondLastLine: false,
            fontSize: 14,
            automaticLayout: true,
        });

        loadContents(stream_data);

        editor.onDidChangeModelContent(() => {
            isEdited = editor.getValue() !== stream_data;
        });

        editor.addCommand(
            monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS,
            (context, args) => {
                if (isEdited) {
                    save(editor.getValue());
                }
            },
        );

        window.addEventListener("keydown", (event) => {
            if ((event.ctrlKey || event.metaKey) && event.key === "s") {
                event.preventDefault();
            }
        });

        return () => {
            editor.dispose();
        };
    });

    $effect(() => {
        loadContents(stream_data);
    });

    function loadContents(stream_data: string | undefined) {
        if (!stream_data || !editor) return;

        if (last_data === stream_data) {
            return;
        }

        isEdited = false;
        last_data = stream_data;
        editor.setValue(stream_data);
    }
</script>

<div class="relative">
    <div bind:this={editorContainer} style:height={height + "px"}></div>
    {#if isEdited}
        <button onclick={() => save(editor.getValue())} class="save-button">
            <UploadOutline size="xl" />
        </button>
    {/if}
</div>

<style lang="postcss">
    .save-button {
        @apply p-2 bg-forge-sec text-forge-text border-t border-forge-bound cursor-pointer;
        position: absolute;
        right: 2em;
        bottom: 0px;
        width: 48px;
        height: 48px;
    }

    .save-button:hover {
        background-color: #3c3d41;
    }
</style>
