<template>
  <div :class="['describe-preview']" :style="getAreaStyle()">
    <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />

    <div class="main">
      <div ref="leftDiv" :style="{ width: data.note_list.length > 0 ? '' : '100%' }">
        <PinyinText
          v-if="isEnable(data.property.view_pinyin)"
          :paragraph-list="data.paragraph_list"
          :pinyin-position="data.property.pinyin_position"
          :pinyin-overall-position="data.property.pinyin_overall_position"
          :pinyin-size="data?.unified_attrib?.pinyin_size"
          :font-size="data?.unified_attrib?.font_size"
          :font-family="data?.unified_attrib?.font"
          :is-preview="isPreview"
        />
        <span v-else class="rich-text" @click="handleRichFillClick" v-html="sanitizeHTML(data.content)"></span>
      </div>

      <div v-show="showLang" class="lang">
        {{ data.multilingual.find((item) => item.type === getLang())?.translation }}
      </div>
    </div>

    <el-dialog
      ref="optimizedDialog"
      title=""
      :visible.sync="noteDialogVisible"
      width="680px"
      :style="dialogStyle"
      :close-on-click-modal="false"
      destroy-on-close
      @close="noteDialogVisible = false"
    >
      <span v-html="sanitizeHTML(selectedNote)"></span>
    </el-dialog>
  </div>
</template>

<script>
import { getRichTextData } from '@/views/book/courseware/data/richText';
import PreviewMixin from '../common/PreviewMixin';
import { isEnable } from '@/views/book/courseware/data/common';
import PinyinText from '@/components/PinyinText.vue';

export default {
  name: 'RichTextPreview',
  components: { PinyinText },
  mixins: [PreviewMixin],
  data() {
    return {
      isEnable,
      data: getRichTextData(),
      isPreview: true,
      divHeight: 'auto',
      observer: null,
      noteDialogVisible: false,
      selectedNote: '',
      dialogStyle: {
        position: 'fixed',
        top: '0',
        left: '0',
        margin: '0',
      },
    };
  },
  mounted() {
    this.observer = new ResizeObserver(() => {
      this.updateHeight();
    });
    this.observer.observe(this.$refs.leftDiv.closest('.describe-preview'));
  },
  beforeDestroy() {
    this.observer.disconnect();
  },
  methods: {
    handleRichFillClick(event) {
      // 检查点击的元素是否是 rich-fill 或者其子元素
      const richFillElement = event.target.closest('.rich-fill');
      if (richFillElement) {
        // 处理点击事件
        let selectedNoteId = richFillElement.dataset.annotationId;
        if (this.data.note_list.some((p) => p.id === selectedNoteId)) {
          this.noteDialogVisible = true;
          this.selectedNote = this.data.note_list.find((p) => p.id === selectedNoteId).note;
        }
      } else {
        this.selectedNote = '';
        this.noteDialogVisible = false;
      }
      this.$nextTick(() => {
        const dialogElement = this.$refs.optimizedDialog;
        // 确保对话框DOM已渲染
        if (!dialogElement) {
          return;
        }
        // 获取对话框内容区域的DOM元素
        const dialogContent = dialogElement.$el.querySelector('.el-dialog');
        if (!dialogContent) {
          return;
        }
        const dialogRect = dialogContent.getBoundingClientRect();
        const dialogWidth = dialogRect.width;
        const dialogHeight = dialogRect.height;
        const padding = 10; // 安全边距

        const clickX = event.clientX;
        const clickY = event.clientY;

        const windowWidth = window.innerWidth;
        const windowHeight = window.innerHeight;

        // 水平定位 - 中心对齐
        let left = clickX - dialogWidth / 2;
        // 边界检查
        left = Math.max(padding, Math.min(left, windowWidth - dialogWidth - padding));

        // 垂直定位 - 点击位置作为下边界中心
        let top = clickY - dialogHeight;
        // 上方空间不足时，改为向下展开
        if (top < padding) {
          top = clickY + padding;
          // 如果向下展开会超出屏幕，则贴底部显示
          if (top + dialogHeight > windowHeight - padding) {
            top = windowHeight - dialogHeight - padding;
          }
        }

        this.dialogStyle = {
          position: 'fixed',
          top: `${top - 20}px`,
          left: `${left}px`,
          margin: '0',
          transform: 'none',
        };
      });
    },
    updateHeight() {
      this.$nextTick(() => {
        const target = this.$refs.leftDiv;
        const parent = target.closest('.describe-preview');
        if (!parent) return;
        setTimeout(() => {
          this.divHeight = parent.offsetHeight - 16;
        }, 800);
      });
    },
  },
};
</script>

<style lang="scss" scoped>
@use '@/styles/mixin.scss' as *;

.describe-preview {
  @include preview-base;

  &.middle {
    margin-top: calc($title-content-spacing - $component-spacing);
    margin-bottom: calc($title-content-spacing - $component-spacing);
  }

  &.top {
    margin-bottom: calc($title-content-spacing - $component-spacing);
  }

  &.bottom {
    margin-top: calc($title-content-spacing - $component-spacing);
  }

  :deep .el-dialog {
    position: fixed;
    margin: 0 !important;
    transition: all 0.2s; /* 添加平滑过渡效果 */

    .el-dialog__header {
      padding: 0 !important;

      .el-dialog__headerbtn {
        top: 6px !important;
        right: 6px !important;
      }
    }

    .el-dialog__body {
      padding: 10px !important;
    }
  }
}
</style>
