<template>
  <div ref="editorContainer" class="codemirror-editor"></div>
</template>

<script setup>
import { ref, onMounted, watch, onBeforeUnmount, computed, nextTick } from 'vue'
import {
  EditorView, lineNumbers, highlightActiveLineGutter, keymap,
  EditorState, Compartment,
  defaultKeymap, history,
  bracketMatching, defaultHighlightStyle, syntaxHighlighting,
  oneDark
} from '@/utils/codemirrorExports'
import { useThemeStore } from '@/stores/theme'
import { loadLanguageExtension, getLanguageFromExtension } from '@/utils/codeMirrorLoader'

// ==================== 主题定义 ====================

// 亮色主题的基础样式
const lightTheme = EditorView.theme({
  '&': { backgroundColor: '#ffffff' },
  '.cm-gutters': { backgroundColor: '#f7f7f7', color: '#999', border: 'none' },
  '.cm-activeLineGutter': { backgroundColor: '#e8e8e8', color: '#333' },
  '.cm-line': { caretColor: '#000' },
  '.cm-selection': { backgroundColor: '#d9d9d9' },
  '.cm-cursor': { borderLeftColor: '#000' }
})

// ==================== Props & Emits ====================

const props = defineProps({
  modelValue: { type: String, required: true },
  fileExtension: { type: String, default: '' }
})

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

// ==================== 状态管理 ====================

const themeStore = useThemeStore()
const editorContainer = ref(null)
let view = null

// 使用 Compartment 实现动态切换，避免重建编辑器
const themeCompartment = new Compartment()
const languageCompartment = new Compartment()

// ==================== 防抖处理 ====================

let emitTimeout = null
const debouncedEmit = (value) => {
  if (emitTimeout) {
    clearTimeout(emitTimeout)
  }
  emitTimeout = setTimeout(() => {
    emit('update:modelValue', value)
  }, 150)
}

// 获取当前主题扩展
const getThemeExtension = () => {
  if (themeStore.isDark) {
    return [oneDark]
  } else {
    // 亮色主题：使用默认语法高亮样式
    return [
      EditorView.theme({
        '&': { backgroundColor: '#ffffff' },
        '.cm-gutters': { backgroundColor: '#f7f7f7', color: '#999', border: 'none' },
        '.cm-activeLineGutter': { backgroundColor: '#e8e8e8', color: '#333' },
        '.cm-line': { caretColor: '#000' },
        '.cm-selection': { backgroundColor: '#d9d9d9' },
        '.cm-cursor': { borderLeftColor: '#000' }
      }),
      syntaxHighlighting(defaultHighlightStyle)
    ]
  }
}

// ==================== 扩展配置 ====================

const createExtensions = () => {
  const extensions = [
    lineNumbers(),
    highlightActiveLineGutter(),
    history(),
    keymap.of(defaultKeymap),
    bracketMatching(),

    // 内容更新监听（带防抖）
    EditorView.updateListener.of((update) => {
      if (update.docChanged) {
        debouncedEmit(update.state.doc.toString())
      }
    }),

    // 基础样式
    EditorView.theme({
      '&': { height: '100%', fontSize: '13px' },
      '.cm-scroller': { overflow: 'auto', fontFamily: 'Consolas, Monaco, Courier New, monospace' },
      '.cm-content': { padding: '8px', minHeight: '100%' },
      '.cm-line': { padding: '0 0' },
      '&.cm-focused': { outline: 'none' }
    }),

    // 使用 Compartment 支持动态切换主题
    themeCompartment.of(getThemeExtension()),

    // 使用 Compartment 支持动态切换语言
    languageCompartment.of([])
  ]

  return extensions
}

// ==================== 语言管理 ====================

const initLanguage = async () => {
  const language = getLanguageFromExtension(props.fileExtension)
  if (language === 'text') return

  try {
    const langExtension = await loadLanguageExtension(language)
    if (langExtension && view) {
      view.dispatch({
        effects: languageCompartment.reconfigure(langExtension)
      })
    }
  } catch (error) {
    console.warn(`[CodeEditor] 加载语言包失败: ${language}`, error)
  }
}

// ==================== 编辑器创建 ====================

const createEditor = (docContent = '') => {
  if (!editorContainer.value) return

  const state = EditorState.create({
    doc: docContent,
    extensions: createExtensions()
  })

  view = new EditorView({ state, parent: editorContainer.value })

  // 初始化语言
  initLanguage()
}

// ==================== 生命周期 ====================

onMounted(() => {
  createEditor(props.modelValue || '')

  // 确保主题正确应用（在下一 tick）
  nextTick(() => {
    if (view) {
      view.dispatch({
        effects: themeCompartment.reconfigure(getThemeExtension())
      })
    }
  })
})

onBeforeUnmount(() => {
  if (emitTimeout) {
    clearTimeout(emitTimeout)
  }
  view?.destroy()
  view = null
})

// ==================== 监听器 ====================

// 监听外部内容变化
watch(() => props.modelValue, (newValue) => {
  if (view && newValue !== view.state.doc.toString()) {
    view.dispatch({
      changes: { from: 0, to: view.state.doc.length, insert: newValue || '' }
    })
  }
})

// 监听主题变化（使用 Compartment 重建，不丢失状态）
watch(() => themeStore.isDark, () => {
  if (view) {
    view.dispatch({
      effects: themeCompartment.reconfigure(getThemeExtension())
    })
  }
})

// 监听文件扩展名变化（重新加载语言）
watch(() => props.fileExtension, () => {
  initLanguage()
})
</script>

<style scoped>
.codemirror-editor {
  height: 100%;
  width: 100%;
  overflow: hidden;
}

.codemirror-editor :deep(.cm-editor) {
  height: 100%;
  width: 100%;
}

.codemirror-editor :deep(.cm-scroller) {
  overflow: auto;
  height: 100%;
}

.codemirror-editor :deep(.cm-content) {
  height: 100%;
}
</style>
