<template>
  <codemirror style="min-height: 200px;max-height: calc(100vh - 300px);background-color: #282A35;" v-model:value="code" :options="options" />
</template>
<script setup lang="ts">
import { reactive, ref, watch } from 'vue';
import Codemirror from 'codemirror-editor-vue3';
// 编辑器代码格式
import 'codemirror/mode/javascript/javascript.js';
import 'codemirror/mode/yaml/yaml.js';
// 自动刷新
import 'codemirror/addon/display/autorefresh';
// 主题
import 'codemirror/theme/dracula.css';

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

const props = defineProps({
  mode: {
    type: String,
    required: false,
    default: 'htmlmixed'
  },
  content: {
    type: String,
    required: true,
    default: ''
  },
  readOnly: {
    type: Boolean,
    required: false,
    default: false,
  },
  onchange: {
    type: Object as any,
    required: false,
    default: () => { },
  },
  cursorBlinkRate: {
    type: Number,
    required: false,
    default: -1,
  }
})

const code = ref('');

const defaultOptions = {
  autorefresh: true, // 是否自动刷新
  smartIndent: true, // 自动缩进
  tabSize: 4, // 缩进单元格为 4 个空格
  mode: 'application/json', //编辑器的编程语言，比如：'javascript'
  theme: 'dracula', // 主题，使用主体需要引入相应的 css 文件
  line: true, // 是否显示行数
  highlightDifferences: true,
  autofocus: false,
  indentUnit: 2,
  height: 200,
  readOnly: false, // 只读
  showCursorWhenSelecting: true,
  firstLineNumber: 1,
  matchBrackets: true,//括号匹配
}

const options = reactive({
  ...defaultOptions
})

watch(() => props.content, (newVal) => {
  code.value = newVal;
}, { immediate: true })

watch(() => props.mode, (mode) => {
  options.mode = mode;
}, { immediate: true })

watch(() => props.readOnly, (readOnly) => {
  options.readOnly = readOnly;
}, { immediate: true })

const getValue = () => code.value
const setValue = (val: string) => code.value = val
const setMode = (mode: string) => options.mode = mode
const setOption = (name: keyof typeof defaultOptions, value: never) => options[name] = value

defineExpose({ getValue, setValue, setMode, setOption })
</script>