<!-- eslint-disable vue/no-mutating-props -->
<template>
  <div>
    <rest-draggable-resizable
      v-if="topicInfo.question.show !== false"
      :key="`question_${topicInfo.questionId}`"
      v-model:x="topicInfo.question.x"
      v-model:y="topicInfo.question.y"
      v-model:w="topicInfo.question.w"
      v-model:h="topicInfo.question.h"
      class="question"
      :class="{ 'special': isSpecial }"
      :style="{ zIndex: questionZIndex }"
      :initW="topicInfo.question.w"
      :initH="topicInfo.question.h"
      :parent="bookContainerBoxRef"
      :draggable="true"
      :resizable="true"
      @activated="handleActivated('question')"
      @deactivated="handleDeactivated('question')"
      @contextmenu.stop.prevent="showContextMenu($event, 'question')"
    >
      <div class="top-tag" @mousedown.stop.prevent="">
        <span class="top-tag-text" @click.stop.prevent="handleOpenEdit">{{ questions?.no }}</span>

        <span class="top-tag-text" @click.stop.prevent="handleOpenEdit">{{ showType }}</span>
        <template v-if="!isSpecial && questions && 'analysis' in questions">
          <span
            v-if="[1, 2, 3].includes(questions?.type || -1)"
            class="top-tag-text"
            :class="questions?.options ? 'success' : 'danger'"
            @click.stop.prevent="handleOpenEdit"
          >
            配
          </span>

          <span class="top-tag-text" :class="questions?.answers ? 'success' : 'danger'" @click.stop.prevent="handleOpenEdit">答</span>
          <span class="top-tag-text" :class="questions?.analysis ? 'success' : 'danger'" @click.stop.prevent="handleOpenEdit">解</span>
        </template>
      </div>
      <div class="del-box" @mousedown.stop.prevent="">
        <n-button type="error" text size="tiny" @click="delQuestion()">
          <template #icon>
            <SolarTrashBinMinimalisticOutline />
          </template>
        </n-button>
      </div>
    </rest-draggable-resizable>

    <rest-draggable-resizable
      v-for="(answerInfo, answerIndex) in topicInfo.answerList"
      :key="`answer_${questions?.no}_${answerIndex}`"
      v-model:x="answerInfo.x"
      v-model:y="answerInfo.y"
      v-model:w="answerInfo.w"
      v-model:h="answerInfo.h"
      class="answer"
      :style="{ zIndex: answerZIndex }"
      :initW="answerInfo.w"
      :initH="answerInfo.h"
      :parent="bookContainerBoxRef"
      :draggable="true"
      :resizable="true"
      @activated="handleActivated('answer')"
      @deactivated="handleDeactivated('answer')"
      @contextmenu.stop.prevent="showContextMenu($event, 'answer', answerIndex)"
    >
      <div class="tag-danger top-tag" style="left: 4px; transform: scale(0.7)" @mousedown.stop.prevent="">
        <span class="top-tag-text">{{ questions?.no }}</span>
      </div>
      <div class="del-box" @mousedown.stop.prevent="">
        <n-button type="error" text size="tiny" @click="delAnswer(answerIndex)">
          <template #icon>
            <SolarTrashBinMinimalisticOutline />
          </template>
        </n-button>
      </div>
    </rest-draggable-resizable>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, defineProps, PropType } from 'vue';
import NButton from 'naive-ui';
import SolarTrashBinMinimalisticOutline from '~icons/solar/trash-bin-minimalistic-outline';
import RestDraggableResizable from '@/components/common/rest-draggable-resizable/rest-draggable-resizable.vue';
import type { TopicInfo } from '@/views/template/template-detail/types';
import type MenuBubble from './menu-bubble.vue';
import { topicTypeList } from '@/views/template/template-detail/def-data';
import type { BookPageAreas, BookPageQuestion } from '@/service/api/book';
import { $mitt, open_book_topic_edit } from '@/utils/event-bus';

const props = defineProps({
  /** 题目 */
  topicInfo: { type: Object as PropType<TopicInfo>, required: true },
  /** 限制移动区域的ref */
  bookContainerBoxRef: { type: [Object, null] as PropType<HTMLDivElement | null>, required: true },
  /** 菜单气泡的ref */
  getMenuBubbleRef: { type: [Function, null] as PropType<() => InstanceType<typeof MenuBubble> | null>, default: null },
  /** 题目信息 */
  getQuestions: { type: Function as PropType<() => BookPageAreas | BookPageQuestion | undefined>, default: () => undefined },
});

const dialog = useDialog();
const questionZIndex = ref<number>(2);
const answerZIndex = ref<number>(3);

const questions = computed<BookPageAreas | BookPageQuestion | undefined>(() => props.getQuestions?.());
const showType = computed(() => topicTypeList.find((item) => item.value === questions.value?.type)?.label || '未知');
/** 是否特殊题目(区域) */
const isSpecial = computed(() => (questions.value?.type || 0) >= 100);

/** 删除答案 */
async function delAnswer(answerIndex: number) {
  try {
    await new Promise((resolve, reject) => {
      dialog.warning({
        title: '温馨提示',
        content: '删除后不可恢复，您确定删除吗？',
        positiveText: '确定',
        negativeText: '取消',
        onPositiveClick: () => resolve(true),
        onNegativeClick: () => reject()
      });
    });
    props.topicInfo!.answerList!.splice(answerIndex, 1);
  } catch (error) {}
}

function delQuestion() {
  props.topicInfo!.question.show = false;
}

function showContextMenu(e: MouseEvent, type: 'answer' | 'question', answerIndex?: number) {
  e.preventDefault();
  props.getMenuBubbleRef()?.show({
    eventElement: e,
    showRename: type === 'answer' && props.topicInfo!.question.show === false,
    editIndexBack() {
      props.topicInfo!.question.show = true;
      props.getMenuBubbleRef()!.hide();
    },
    // 置于底层
    renameCallBack() {
      if (type === 'answer') {
        answerZIndex.value = 2;
      } else {
        questionZIndex.value = 2;
      }
    },
    async deleteCallBack() {
      if (type === 'answer') {
        try {
          answerIndex ?? (await delAnswer(answerIndex!));
        } catch (error) {}
        props.getMenuBubbleRef()!.hide();
      } else {
        props.topicInfo!.question.show = false;
        props.getMenuBubbleRef()!.hide();
      }
    },
  });
}

/** 打开编辑 */
function handleOpenEdit(event: MouseEvent) {
  $mitt.emit(open_book_topic_edit, { questionId: props.topicInfo.questionId, event });
}

/** 组件从活跃状态到非活跃状态时触发 */
function handleDeactivated(type: 'answer' | 'question') {
  if (type === 'answer') {
    answerZIndex.value = 4;
  } else {
    questionZIndex.value = 3;
  }
}

/** 组件从非活跃状态到活跃状态时触发 */
function handleActivated(type: 'answer' | 'question') {
  if (type === 'answer') {
    answerZIndex.value = 5;
  } else {
    questionZIndex.value = 5;
  }
}
</script>

<style lang="scss">
.vdr-container.answer {
  box-sizing: border-box;
  background: rgba(215, 250, 222, 0.2);
  border-color: #67c23a;

  > .vdr-handle {
    border-color: #67c23a;
  }
}

.vdr-container.topic {
  box-sizing: border-box;
  background: rgba(209, 227, 252, 0.2);
  border-color: #409eff;

  > .vdr-handle {
    border-color: #409eff;
  }
}

.vdr-container.question {
  box-sizing: border-box;
  background: rgba(255, 245, 234, 0.2);
  border-color: #e6a23c;

  > .vdr-handle {
    border-color: #e6a23c;
  }
}
</style>

<style lang="scss" scoped>
.del-box {
  position: absolute;
  top: -10px;
  right: -10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #fef0f0;
  border-radius: 50%;
  width: 20px;
  height: 20px;
}

.vdr-container.active > .del-box {
  display: none;
}

.top-tag {
  position: absolute;
  top: -20px;
  left: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  background-color: rgba(255, 255, 255, 0.5);
  transform-origin: bottom left;

  .top-tag-text {
    height: 18px;
    padding: 0 10px;
    margin-left: 6px;
    font-size: 14px;
    color: #409eff;
    cursor: pointer;
    user-select: none;
    background-color: #ecf5ff;
    border: 1px solid #409eff;
    border-bottom: none;
    border-radius: 8px 8px 0 0;

    &.success {
      color: #67c23a;
      background-color: #f0f9eb;
      border: 1px solid #67c23a;
    }

    &.danger {
      color: #f56c6c;
      background-color: #fef0f0;
      border: 1px solid #f56c6c;
    }
  }
}

.topic .topic-content {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 16px;
  font-weight: bold;
  color: #409eff;
  user-select: none;
}

.question .question-content {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 16px;
  font-weight: bold;
  color: #e6a23c;
  user-select: none;
}

.answer .answer-content {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 14px;
  font-weight: bold;
  color: #67c23a;
  user-select: none;
}
</style>
