<template>
  <div ref="editorContainer" class="monaco-editor-container" :style="{ height: height + 'px' }"></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import * as monaco from 'monaco-editor'

const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  language: {
    type: String,
    default: 'plaintext'
  },
  theme: {
    type: String,
    default: 'vs-dark'
  },
  height: {
    type: Number,
    default: 400
  },
  options: {
    type: Object,
    default: () => ({})
  },
  readOnly: {
    type: Boolean,
    default: false
  }
})

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

const editorContainer = ref(null)
let editor = null

// 默认编辑器选项
const defaultOptions = {
  automaticLayout: true,
  fontSize: 14,
  fontFamily: 'SF Mono, Monaco, Cascadia Code, Roboto Mono, Consolas, Courier New, monospace',
  lineHeight: 1.6,
  minimap: { enabled: true },
  scrollBeyondLastLine: false,
  wordWrap: 'on',
  tabSize: 2,
  insertSpaces: true,
  detectIndentation: true,
  renderWhitespace: 'selection',
  renderLineHighlight: 'all',
  cursorBlinking: 'smooth',
  cursorSmoothCaretAnimation: true,
  smoothScrolling: true,
  mouseWheelScrollSensitivity: 1,
  fastScrollSensitivity: 5,
  scrollbar: {
    vertical: 'visible',
    horizontal: 'visible',
    useShadows: false,
    verticalHasArrows: false,
    horizontalHasArrows: false,
    verticalScrollbarSize: 10,
    horizontalScrollbarSize: 10
  },
  // 语法高亮增强配置
  semanticHighlighting: {
    enabled: true
  },
  colorDecorators: true,
  // 代码提示和补全
  suggestOnTriggerCharacters: true,
  acceptSuggestionOnEnter: 'on',
  acceptSuggestionOnCommitCharacter: true,
  quickSuggestions: {
    other: true,
    comments: false,
    strings: false
  },
  quickSuggestionsDelay: 100,
  parameterHints: {
    enabled: true,
    cycle: true
  },
  hover: {
    enabled: true,
    delay: 300
  },
  // 格式化
  formatOnPaste: true,
  formatOnType: true,
  autoIndent: 'advanced',
  // 括号配对和颜色
  bracketPairColorization: {
    enabled: true,
    independentColorPoolPerBracketType: true
  },
  guides: {
    bracketPairs: true,
    bracketPairsHorizontal: true,
    highlightActiveBracketPair: true,
    indentation: true,
    highlightActiveIndentation: true
  },
  // 代码折叠
  folding: true,
  foldingStrategy: 'auto',
  foldingHighlight: true,
  foldingImportsByDefault: false,
  showFoldingControls: 'mouseover',
  // 其他增强功能
  links: true,
  occurrencesHighlight: true,
  selectionHighlight: true,
  codeLens: true,
  lightbulb: {
    enabled: true
  },
  // 匹配括号
  matchBrackets: 'always',
  // 选择相关
  selectOnLineNumbers: true,
  selectionClipboard: false,
  // 渲染相关
  renderControlCharacters: false,
  renderFinalNewline: true,
  renderValidationDecorations: 'on'
}

// 语言映射
const getLanguageByExtension = (filename) => {
  if (!filename) return 'plaintext'
  
  const ext = filename.split('.').pop()?.toLowerCase()
  
  const languageMap = {
    // Web 技术
    'js': 'javascript',
    'jsx': 'javascript',
    'ts': 'typescript',
    'tsx': 'typescript',
    'html': 'html',
    'htm': 'html',
    'css': 'css',
    'scss': 'scss',
    'sass': 'sass',
    'less': 'less',
    'vue': 'html', // Vue SFC 使用 HTML 语法高亮
    'json': 'json',
    'xml': 'xml',
    
    // 编程语言
    'py': 'python',
    'java': 'java',
    'c': 'c',
    'cpp': 'cpp',
    'cxx': 'cpp',
    'cc': 'cpp',
    'h': 'c',
    'hpp': 'cpp',
    'cs': 'csharp',
    'php': 'php',
    'rb': 'ruby',
    'go': 'go',
    'rs': 'rust',
    'swift': 'swift',
    'kt': 'kotlin',
    'scala': 'scala',
    'r': 'r',
    'pl': 'perl',
    'lua': 'lua',
    
    // Shell 和配置
    'sh': 'shell',
    'bash': 'shell',
    'zsh': 'shell',
    'fish': 'shell',
    'ps1': 'powershell',
    'bat': 'bat',
    'cmd': 'bat',
    'dockerfile': 'dockerfile',
    'yaml': 'yaml',
    'yml': 'yaml',
    'toml': 'toml',
    'ini': 'ini',
    'conf': 'ini',
    'cfg': 'ini',
    
    // 数据格式
    'sql': 'sql',
    'md': 'markdown',
    'markdown': 'markdown',
    'tex': 'latex',
    
    // 其他
    'log': 'plaintext',
    'txt': 'plaintext'
  }
  
  return languageMap[ext] || 'plaintext'
}

// 初始化编辑器
const initEditor = async () => {
  if (!editorContainer.value) return
  
  try {
    // 设置自定义主题
    setupCustomThemes()
    
    // 配置语言特性
    configureLanguageFeatures()
    
    // 合并选项
    const editorOptions = {
      ...defaultOptions,
      ...props.options,
      value: props.modelValue,
      language: props.language,
      theme: props.theme,
      readOnly: props.readOnly
    }
    
    // 创建编辑器实例
    editor = monaco.editor.create(editorContainer.value, editorOptions)
    
    // 监听内容变化
    editor.onDidChangeModelContent(() => {
      const value = editor.getValue()
      emit('update:modelValue', value)
      emit('change', value)
    })
    
    // 监听保存快捷键 (Ctrl+S)
    editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
      emit('save')
    })
    
    // 添加更多快捷键
    setupKeyboardShortcuts()
    
    console.log('Monaco Editor 初始化成功')
  } catch (error) {
    console.error('Monaco Editor 初始化失败:', error)
  }
}

// 配置语言特性
const configureLanguageFeatures = () => {
  // JavaScript/TypeScript 语言配置
  monaco.languages.typescript.javascriptDefaults.setEagerModelSync(true)
  monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true)
  
  // 设置编译选项
  monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
    target: monaco.languages.typescript.ScriptTarget.ES2020,
    allowNonTsExtensions: true,
    moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
    module: monaco.languages.typescript.ModuleKind.CommonJS,
    noEmit: true,
    esModuleInterop: true,
    jsx: monaco.languages.typescript.JsxEmit.React,
    reactNamespace: 'React',
    allowJs: true,
    typeRoots: ['node_modules/@types']
  })
  
  // CSS 语言配置
  monaco.languages.css.cssDefaults.setOptions({
    validate: true,
    lint: {
      compatibleVendorPrefixes: 'ignore',
      vendorPrefix: 'warning',
      duplicateProperties: 'warning',
      emptyRules: 'warning',
      importStatement: 'ignore',
      boxModel: 'ignore',
      universalSelector: 'ignore',
      zeroUnits: 'ignore',
      fontFaceProperties: 'warning',
      hexColorLength: 'error',
      argumentsInColorFunction: 'error',
      unknownProperties: 'warning',
      ieHack: 'ignore',
      unknownVendorSpecificProperties: 'ignore',
      propertyIgnoredDueToDisplay: 'warning',
      important: 'ignore',
      float: 'ignore',
      idSelector: 'ignore'
    }
  })
  
  // HTML 语言配置
  monaco.languages.html.htmlDefaults.setOptions({
    format: {
      tabSize: 2,
      insertSpaces: true,
      wrapLineLength: 120,
      unformatted: 'default"',
      contentUnformatted: 'pre,code,textarea',
      indentInnerHtml: false,
      preserveNewLines: true,
      maxPreserveNewLines: undefined,
      indentHandlebars: false,
      endWithNewline: false,
      extraLiners: 'head, body, /html',
      wrapAttributes: 'auto'
    },
    suggest: {},
    validate: true
  })
  
  // JSON 语言配置
  monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
    validate: true,
    allowComments: false,
    schemas: [],
    enableSchemaRequest: true
  })
}

// 设置键盘快捷键
const setupKeyboardShortcuts = () => {
  if (!editor) return
  
  // 格式化代码 (Shift+Alt+F)
  editor.addCommand(monaco.KeyMod.Shift | monaco.KeyMod.Alt | monaco.KeyCode.KeyF, () => {
    editor.getAction('editor.action.formatDocument').run()
  })
  
  // 查找 (Ctrl+F)
  editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyF, () => {
    editor.getAction('actions.find').run()
  })
  
  // 替换 (Ctrl+H)
  editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyH, () => {
    editor.getAction('editor.action.startFindReplaceAction').run()
  })
  
  // 转到行 (Ctrl+G)
  editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyG, () => {
    editor.getAction('editor.action.gotoLine').run()
  })
  
  // 注释/取消注释 (Ctrl+/)
  editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Slash, () => {
    editor.getAction('editor.action.commentLine').run()
  })
}

// 设置自定义主题
const setupCustomThemes = () => {
  // 定义自定义深色主题 - 增强版
  monaco.editor.defineTheme('custom-dark', {
    base: 'vs-dark',
    inherit: true,
    rules: [
      // 注释
      { token: 'comment', foreground: '6A9955', fontStyle: 'italic' },
      { token: 'comment.line', foreground: '6A9955', fontStyle: 'italic' },
      { token: 'comment.block', foreground: '6A9955', fontStyle: 'italic' },
      
      // 关键字
      { token: 'keyword', foreground: '569CD6', fontStyle: 'bold' },
      { token: 'keyword.control', foreground: 'C586C0', fontStyle: 'bold' },
      { token: 'keyword.operator', foreground: '569CD6' },
      { token: 'keyword.other', foreground: '569CD6' },
      
      // 字符串
      { token: 'string', foreground: 'CE9178' },
      { token: 'string.quoted', foreground: 'CE9178' },
      { token: 'string.template', foreground: 'CE9178' },
      { token: 'string.regexp', foreground: 'D16969' },
      
      // 数字
      { token: 'number', foreground: 'B5CEA8' },
      { token: 'number.hex', foreground: 'B5CEA8' },
      { token: 'number.octal', foreground: 'B5CEA8' },
      { token: 'number.binary', foreground: 'B5CEA8' },
      
      // 变量和标识符
      { token: 'variable', foreground: '9CDCFE' },
      { token: 'variable.name', foreground: '9CDCFE' },
      { token: 'variable.parameter', foreground: '9CDCFE' },
      { token: 'variable.other', foreground: '9CDCFE' },
      
      // 函数和方法
      { token: 'function', foreground: 'DCDCAA' },
      { token: 'function.name', foreground: 'DCDCAA' },
      { token: 'method', foreground: 'DCDCAA' },
      { token: 'method.name', foreground: 'DCDCAA' },
      
      // 类型和类
      { token: 'type', foreground: '4EC9B0' },
      { token: 'type.name', foreground: '4EC9B0' },
      { token: 'class', foreground: '4EC9B0' },
      { token: 'class.name', foreground: '4EC9B0' },
      { token: 'interface', foreground: 'B8D7A3' },
      { token: 'enum', foreground: 'B8D7A3' },
      { token: 'struct', foreground: '86C691' },
      
      // 操作符和标点
      { token: 'operator', foreground: 'D4D4D4' },
      { token: 'delimiter', foreground: 'D4D4D4' },
      { token: 'punctuation', foreground: 'D4D4D4' },
      
      // 特殊标记
      { token: 'tag', foreground: '569CD6' },
      { token: 'tag.name', foreground: '569CD6' },
      { token: 'attribute', foreground: '9CDCFE' },
      { token: 'attribute.name', foreground: '9CDCFE' },
      { token: 'attribute.value', foreground: 'CE9178' },
      
      // 装饰器和宏
      { token: 'decorator', foreground: 'C586C0' },
      { token: 'macro', foreground: 'C586C0' },
      
      // JavaScript/TypeScript 特定
      { token: 'support.type', foreground: '4EC9B0' },
      { token: 'support.class', foreground: '4EC9B0' },
      { token: 'support.function', foreground: 'DCDCAA' },
      { token: 'support.variable', foreground: '4FC1FF' },
      
      // CSS 特定
      { token: 'property', foreground: '9CDCFE' },
      { token: 'property.name', foreground: '9CDCFE' },
      { token: 'property.value', foreground: 'CE9178' },
      { token: 'selector', foreground: 'D7BA7D' },
      
      // JSON 特定
      { token: 'key', foreground: '9CDCFE' },
      { token: 'value', foreground: 'CE9178' }
    ],
    colors: {
      'editor.background': '#1E1E1E',
      'editor.foreground': '#D4D4D4',
      'editorLineNumber.foreground': '#858585',
      'editorLineNumber.activeForeground': '#C6C6C6',
      'editor.selectionBackground': '#264F78',
      'editor.inactiveSelectionBackground': '#3A3D41',
      'editorCursor.foreground': '#AEAFAD',
      'editor.findMatchBackground': '#515C6A',
      'editor.findMatchHighlightBackground': '#EA5C0055',
      'editor.linkedEditingBackground': '#FF00007A',
      'editorBracketMatch.background': '#0064001A',
      'editorBracketMatch.border': '#888888'
    }
  })
  
  // 定义自定义浅色主题 - 增强版
  monaco.editor.defineTheme('custom-light', {
    base: 'vs',
    inherit: true,
    rules: [
      // 注释
      { token: 'comment', foreground: '008000', fontStyle: 'italic' },
      { token: 'comment.line', foreground: '008000', fontStyle: 'italic' },
      { token: 'comment.block', foreground: '008000', fontStyle: 'italic' },
      
      // 关键字
      { token: 'keyword', foreground: '0000FF', fontStyle: 'bold' },
      { token: 'keyword.control', foreground: 'AF00DB', fontStyle: 'bold' },
      { token: 'keyword.operator', foreground: '0000FF' },
      { token: 'keyword.other', foreground: '0000FF' },
      
      // 字符串
      { token: 'string', foreground: 'A31515' },
      { token: 'string.quoted', foreground: 'A31515' },
      { token: 'string.template', foreground: 'A31515' },
      { token: 'string.regexp', foreground: 'D16969' },
      
      // 数字
      { token: 'number', foreground: '098658' },
      { token: 'number.hex', foreground: '098658' },
      { token: 'number.octal', foreground: '098658' },
      { token: 'number.binary', foreground: '098658' },
      
      // 变量和标识符
      { token: 'variable', foreground: '001080' },
      { token: 'variable.name', foreground: '001080' },
      { token: 'variable.parameter', foreground: '001080' },
      { token: 'variable.other', foreground: '001080' },
      
      // 函数和方法
      { token: 'function', foreground: '795E26' },
      { token: 'function.name', foreground: '795E26' },
      { token: 'method', foreground: '795E26' },
      { token: 'method.name', foreground: '795E26' },
      
      // 类型和类
      { token: 'type', foreground: '267F99' },
      { token: 'type.name', foreground: '267F99' },
      { token: 'class', foreground: '267F99' },
      { token: 'class.name', foreground: '267F99' },
      { token: 'interface', foreground: '007ACC' },
      { token: 'enum', foreground: '007ACC' },
      { token: 'struct', foreground: '267F99' },
      
      // 操作符和标点
      { token: 'operator', foreground: '000000' },
      { token: 'delimiter', foreground: '000000' },
      { token: 'punctuation', foreground: '000000' },
      
      // 特殊标记
      { token: 'tag', foreground: '800000' },
      { token: 'tag.name', foreground: '800000' },
      { token: 'attribute', foreground: 'FF0000' },
      { token: 'attribute.name', foreground: 'FF0000' },
      { token: 'attribute.value', foreground: '0000FF' },
      
      // 装饰器和宏
      { token: 'decorator', foreground: 'AF00DB' },
      { token: 'macro', foreground: 'AF00DB' },
      
      // JavaScript/TypeScript 特定
      { token: 'support.type', foreground: '267F99' },
      { token: 'support.class', foreground: '267F99' },
      { token: 'support.function', foreground: '795E26' },
      { token: 'support.variable', foreground: '0070C1' },
      
      // CSS 特定
      { token: 'property', foreground: 'FF0000' },
      { token: 'property.name', foreground: 'FF0000' },
      { token: 'property.value', foreground: '0451A5' },
      { token: 'selector', foreground: '800000' },
      
      // JSON 特定
      { token: 'key', foreground: '0451A5' },
      { token: 'value', foreground: 'A31515' }
    ],
    colors: {
      'editor.background': '#FFFFFF',
      'editor.foreground': '#000000',
      'editorLineNumber.foreground': '#237893',
      'editor.selectionBackground': '#ADD6FF',
      'editor.inactiveSelectionBackground': '#E5EBF1',
      'editorCursor.foreground': '#000000',
      'editor.findMatchBackground': '#A8AC94',
      'editor.findMatchHighlightBackground': '#EA5C0055'
    }
  })
}

// 更新编辑器值
const updateValue = (newValue) => {
  if (editor && editor.getValue() !== newValue) {
    editor.setValue(newValue || '')
  }
}

// 更新编辑器语言
const updateLanguage = (newLanguage) => {
  if (editor) {
    const model = editor.getModel()
    if (model) {
      monaco.editor.setModelLanguage(model, newLanguage)
    }
  }
}

// 更新编辑器主题
const updateTheme = (newTheme) => {
  if (editor) {
    monaco.editor.setTheme(newTheme)
  }
}

// 调整编辑器大小
const resizeEditor = () => {
  if (editor) {
    nextTick(() => {
      editor.layout()
    })
  }
}

// 获取编辑器实例
const getEditor = () => editor

// 聚焦编辑器
const focus = () => {
  if (editor) {
    editor.focus()
  }
}

// 设置编辑器内容
const setValue = (value) => {
  if (editor) {
    editor.setValue(value || '')
  }
}

// 获取编辑器内容
const getValue = () => {
  return editor ? editor.getValue() : ''
}

// 监听属性变化
watch(() => props.modelValue, updateValue)
watch(() => props.language, updateLanguage)
watch(() => props.theme, updateTheme)
watch(() => props.height, resizeEditor)

// 生命周期
onMounted(() => {
  nextTick(() => {
    initEditor()
  })
})

onBeforeUnmount(() => {
  if (editor) {
    editor.dispose()
    editor = null
  }
})

// 暴露方法给父组件
defineExpose({
  getEditor,
  focus,
  setValue,
  getValue,
  resizeEditor,
  getLanguageByExtension
})
</script>

<style scoped>
.monaco-editor-container {
  width: 100%;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  overflow: hidden;
}

.monaco-editor-container:focus-within {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}
</style>
