<template>
  <div class="czr-markdown-main">
    <div class="czr-markdown-main-menus">
      <template v-for="item in Menus">
        <template v-if="item.options?.length > 0">
          <el-dropdown>
            <div
              class="__hover button flex items-center gap-1"
              :title="item.title"
            >
              <SvgIcon :name="item.icon" color="#000000" />
              <SvgIcon
                name="czr_arrow"
                :rotate="90"
                size="12"
                color="#000000"
              />
            </div>
            <template #dropdown>
              <el-dropdown-menu>
                <template v-for="op in item.options">
                  <el-dropdown-item @click="insertText(op.start, op.end)">{{
                    op.title
                  }}</el-dropdown-item>
                </template>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </template>
        <template v-else>
          <div
            class="__hover button flex items-center gap-1"
            @click="insertText(item.start, item.end)"
            :title="item.title"
          >
            <SvgIcon :name="item.icon" color="#000000" />
          </div>
        </template>
        <template v-if="item.split">
          <div class="split" />
        </template>
      </template>
    </div>
    <div class="czr-markdown-main-content" :class="`layout-${layout}`">
      <div class="editor">
        <textarea
          ref="ref_textarea"
          v-model="markdownValue"
          @input="updateMarkdown"
        ></textarea>
      </div>
      <div class="preview" v-html="markdownHtmlCpt"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
defineOptions({
  name: 'CzrMarkdown',
})
import { ref, computed, onMounted } from 'vue'
import { marked } from 'marked'
import DOMPurify from 'dompurify'

const renderer: any = new marked.Renderer()
renderer.link = ({ href, text }) => {
  return `<a href="${href}">${text}</a>`
}
DOMPurify.addHook('afterSanitizeAttributes', (node) => {
  if (node.tagName === 'A') {
    node.setAttribute('target', '_blank')
    node.setAttribute('rel', 'noopener noreferrer')
  }
})
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
  modelValue: {
    type: String,
    default: '',
  },
  layout: {
    type: String,
    default: 'x',
  },
})
const Menus: any = [
  {
    icon: 'czr_md-title',
    title: '标题',
    options: [
      { title: '一级标题', start: '# ', end: '' },
      { title: '二级标题', start: '## ', end: '' },
      { title: '三级标题', start: '### ', end: '' },
      { title: '四级标题', start: '#### ', end: '' },
      { title: '五级标题', start: '##### ', end: '' },
      {
        label: 'H6',
        title: '六级标题',
        start: '###### ',
        end: '',
      },
    ],
  },
  { icon: 'czr_md-bold', title: '加粗', start: '**', end: '**' },
  { icon: 'czr_md-em', title: '斜体', start: '*', end: '*' },
  { icon: 'czr_md-bold-em', title: '加粗斜体', start: '***', end: '***' },
  {
    icon: 'czr_md-s',
    title: '删除线',
    start: '~~',
    end: '~~',
  },
  {
    icon: 'czr_md-u',
    title: '下划线',
    start: '<u>',
    end: '</u>',
    split: true,
  },
  { icon: 'czr_md-code', title: '代码块', start: '\n```\n', end: '\n```' },
  {
    icon: 'czr_md-link',
    title: '链接',
    start: '[链接](',
    end: ')',
  },
  { icon: 'czr_md-img', title: '图片', start: '![图片](', end: ')' },
]
const ref_textarea = ref(null)
const markdownValue = ref(props.modelValue)

const markdownHtmlCpt = computed(() => {
  return DOMPurify.sanitize(marked(markdownValue.value) as any)
})

const updateMarkdown = () => {
  emit('update:modelValue', markdownValue.value)
}

const insertText = (before, after) => {
  const dom: any = ref_textarea.value
  if (dom) {
    const start = dom.selectionStart
    const end = dom.selectionEnd
    const selectedText = markdownValue.value.substring(start, end)
    markdownValue.value =
      markdownValue.value.substring(0, start) +
      before +
      selectedText +
      after +
      markdownValue.value.substring(end)
    // 移动光标位置
    setTimeout(() => {
      dom.selectionStart = start + before.length
      dom.selectionEnd = end + before.length
      dom.focus()
    }, 0)
    emit('update:modelValue', markdownValue.value)
  }
}
onMounted(() => {
  marked.setOptions({
    renderer: renderer,
    breaks: true,
    gfm: true,
  })
})
</script>

<style scoped lang="scss">
.czr-markdown-main {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
  .czr-markdown-main-menus {
    display: flex;
    align-items: center;
    gap: 10px;
    box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
    padding: 10px;
    .split {
      width: 1px;
      height: 16px;
      background-color: rgba(0, 0, 0, 0.3);
    }
  }
  .czr-markdown-main-content {
    flex: 1;
    display: flex;
    overflow: hidden;
    &.layout-y {
      flex-direction: column;
      .editor {
        border-bottom: 1px solid rgba(0, 0, 0, 0.15);
      }
    }
    &.layout-x {
      .editor {
        border-right: 1px solid rgba(0, 0, 0, 0.15);
      }
    }
    .editor,
    .preview {
      flex: 1;
      padding: 14px;
    }
    .editor {
      textarea {
        width: 100%;
        height: 100%;
        resize: none;
      }
    }
    :deep(.preview) {
      overflow: auto;
      /* 通用标题样式 */
      h1,
      h2,
      h3,
      h4,
      h5,
      h6 {
        font-family:
          -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,
          Arial, sans-serif;
        font-weight: 600;
        line-height: 1.25;
        margin-top: 1.5em;
        margin-bottom: 0.5em;
        color: #222;
      }

      /* H1 样式 */
      h1 {
        font-size: 2em;
        border-bottom: 1px solid #eaecef;
        padding-bottom: 0.3em;
        margin-top: 0;
      }

      /* H2 样式 */
      h2 {
        font-size: 1.5em;
        border-bottom: 1px solid #eaecef;
        padding-bottom: 0.3em;
      }

      /* H3 样式 */
      h3 {
        font-size: 1.25em;
      }

      /* H4 样式 */
      h4 {
        font-size: 1em;
      }

      /* H5 样式 */
      h5 {
        font-size: 0.875em;
      }

      /* H6 样式 */
      h6 {
        font-size: 0.85em;
        color: #6a737d;
      }
      /* 默认链接样式 */
      a {
        color: #0366d6; /* 链接颜色 */
        text-decoration: none; /* 去掉下划线 */
        transition: color 0.2s; /* 颜色过渡效果 */
        /* 鼠标悬停样式 */
        &:hover {
          color: #0550a8; /* 悬停颜色 */
          text-decoration: underline; /* 显示下划线 */
        }
        /* 已访问链接 */
        &:visited {
          color: #5a32a3; /* 紫色表示已访问 */
        }

        /* 活动链接 (点击时) */
        &:active {
          color: #d63384;
        }
      }

      /*
 * 暗色系代码块样式
 * 适用于夜间/暗色模式的代码展示
 */

      // 基础代码块样式
      pre {
        background-color: #1e1e1e; // 深灰背景
        border-radius: 6px; // 圆角
        padding: 1.25rem; // 内边距
        margin: 1.5rem 0; // 外边距
        overflow: auto; // 溢出滚动
        border: 1px solid #333; // 边框
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); // 阴影效果

        // 代码内容样式
        code {
          display: block;
          color: #d4d4d4; // 主文本颜色
          font-family:
            'Fira Code', 'Consolas', 'Monaco', monospace; // 等宽字体栈
          font-size: 0.95em;
          line-height: 1.5;
          text-shadow: none;
          white-space: pre;
        }
      }
    }
  }
}
</style>
