<template>
  <t-dialog
    :header="title"
    :visible="visible"
    width="900px"
    :on-confirm="handleOk"
    :on-cancel="cancel"
    :on-close="cancel"
  >
    <div ref="monacoDom" class="monaco"></div>
  </t-dialog>
</template>

<script setup lang="ts">
import {
  defineComponent,
  nextTick,
  onMounted,
  onUnmounted,
  PropType,
  reactive,
  ref,
  watch,
} from "vue";
import { monaco } from "./customMonaco";

const props = defineProps({
  visible: {
    type: Boolean,
    require: true,
  },
  title: {
    type: String,
    default: () => {
      return "JavaScript";
    },
  },
  code: {
    type: String,
    default: () => {
      return "";
    },
  },
  language: {
    type: String,
    default: () => {
      return "javascript";
    },
    validator: (value: string) => {
      // 这个值必须匹配下列字符串中的一个
      return ["javascript", "json", "markdown"].includes(value);
    },
  },
});

const emit = defineEmits(["update:visible", "changeCode"]);

let editor: any = null;

function handleOk() {
  // 按下确认以后修改外界值
  const code = editor.getValue();
  emit("changeCode", code);
  emit("update:visible", false);
}

function cancel() {
  emit("update:visible", false);
}

const curTheme = "vs-dark"; // 暗主题
const monacoDom: any = ref(null);

watch(
  () => props.visible,
  (newV) => {
    // console.log("props.visible", props.visible);
    if (newV) {
      nextTick(async () => {
        if (!editor) {
          editor = monaco.editor.create(monacoDom.value, {
            theme: curTheme,
            automaticLayout: true,
            language: props.language,
          });
        }
        // 可见状态
        editor.setValue(props.code);
        monaco.editor.setModelLanguage(editor.getModel(), props.language);
        // 格式化
        setTimeout(() => {
          editor.getAction(["editor.action.formatDocument"])._run();
        }, 300);
      });
    }
  }
);

onUnmounted(() => {
  editor?.dispose();
});
</script>

<style lang="postcss">
.t-dialog__body {
  /* padding: 0; */
  overflow: hidden;
  .monaco {
    height: 400px;
  }
}
</style>
