<script setup>
import { VueMonacoEditor } from '@guolao/vue-monaco-editor'
import { computed, ref, watch } from 'vue'

const props = defineProps({
    modelValue: String,
    filename: String,
    height: { type: String, default: '600px' },
    readOnly: { type: Boolean, default: false },
    theme: { type: String, default: 'vs-dark' }, // vs | vs-dark | hc-black
    wordWrap: { type: Boolean, default: true },
    lineNumbers: { type: Boolean, default: true },
})

const emit = defineEmits(['update:modelValue'])

const language = computed(() => {
    const ext = props.filename?.split('.').pop()?.toLowerCase()
    return {
        php: 'php', js: 'javascript', mjs: 'javascript', ts: 'typescript', tsx: 'typescript',
        vue: 'html', jsx: 'javascript', html: 'html', htm: 'html', css: 'css', scss: 'scss',
        less: 'less', json: 'json', md: 'markdown', xml: 'xml', svg: 'xml',
        yml: 'yaml', yaml: 'yaml', sh: 'shell', bash: 'shell', sql: 'sql',
        py: 'python', rb: 'ruby', go: 'go', rs: 'rust', java: 'java', c: 'c',
        cpp: 'cpp', cs: 'csharp', conf: 'ini', ini: 'ini', env: 'ini',
        htaccess: 'apache', dockerfile: 'dockerfile', log: 'log', txt: 'plaintext',
    }[ext] || 'plaintext'
})

// Reactive options so toggles in the parent (word-wrap / line-numbers) propagate
// without re-mounting the editor.
const editorOptions = computed(() => ({
    automaticLayout: true,
    fontSize: 14,
    fontFamily: 'Menlo, Monaco, Consolas, "Courier New", monospace',
    lineNumbers: props.lineNumbers ? 'on' : 'off',
    minimap: { enabled: true },
    scrollBeyondLastLine: false,
    tabSize: 4,
    wordWrap: props.wordWrap ? 'on' : 'off',
    renderWhitespace: 'selection',
    bracketPairColorization: { enabled: true },
    readOnly: props.readOnly,
}))

const localValue = ref(props.modelValue ?? '')

// Sync when parent updates the value (e.g. when a new file is opened)
watch(() => props.modelValue, (v) => {
    if (v !== localValue.value) localValue.value = v ?? ''
})
</script>

<template>
    <div class="rounded-lg border border-slate-300 overflow-hidden" :style="{ height }">
        <VueMonacoEditor
            v-model:value="localValue"
            @update:value="emit('update:modelValue', $event)"
            :language="language"
            :theme="theme"
            :options="editorOptions"
            :height="height"
        />
    </div>
</template>
