<script setup lang="ts">
import type { FormInst, FormItemRule } from 'naive-ui'
import Clipboard from 'clipboard'
import {
  NButton,
  NCard,
  NDrawer,
  NDrawerContent,
  NForm,
  NFormItem,
  NInput,
  NInputNumber,
  NRadio,
  NRadioGroup,
} from 'naive-ui'
import { pinyin } from 'pinyin-pro'
import { computed, onUnmounted, ref, watch } from 'vue'
import OssImageUpload from '@/components/common/oss-image-upload/index.vue'
import WangEditor from '@/components/common/wang-editor.vue'
import { QuestionCategoryEnum, QuestionType } from '@/enum/business'
import { fetchAddQuestionLibrary, fetchUpdateQuestionLibrary } from '@/service/api/question'

const props = defineProps<{
  show: boolean
  operation: 'add' | 'edit'
  questionData?: any
  currentCategory: any
}>()

const emit = defineEmits<{
  (e: 'update:show', value: boolean): void
  (e: 'success'): void
}>()

const showQuestionModal = computed({
  get: () => props.show,
  set: val => emit('update:show', val),
})

// 拼音转换工具
const pinyinTool = ref({
  input: '',
  output: '',
})

// 监听输入变化自动转换
watch(() => pinyinTool.value.input, (val) => {
  if (val) {
    pinyinTool.value.output = pinyin(val)
  }
  else {
    pinyinTool.value.output = ''
  }
})

// 复制拼音
const copyBtnRef = ref<any>(null)
let clipboard: Clipboard | null = null

watch(copyBtnRef, (inst) => {
  if (clipboard) {
    clipboard.destroy()
    clipboard = null
  }
  if (inst) {
    const domEl = inst.$el || inst
    clipboard = new Clipboard(domEl)
    clipboard.on('success', () => {
      window?.$message?.success('拼音已复制到剪贴板')
    })
    clipboard.on('error', () => {
      window?.$message?.error('复制失败，请手动复制')
    })
  }
})

onUnmounted(() => {
  clipboard?.destroy()
})

const questionForm = ref({
  name: '',
  answer: '',
  type: QuestionCategoryEnum.ChineseCharacterDictation1 as QuestionCategoryEnum | number,
  imageUrl: '',
  IsGood: 0,
  IsDisabled: false,
  KeyWord: '',
  KeyWordsIndex: 0,
})

const questionFormRef = ref<FormInst | null>(null)

const rules = computed(() => {
  const dynamicRules: any = {
    answer: [{ required: true, message: '请输入题目答案', trigger: ['blur'] }],
    type: [{ required: true, message: '请选择题目类型', trigger: ['change'] }],
  }

  // 题目正文内容和图片至少要有一个
  if (!questionForm.value.imageUrl) {
    dynamicRules.name = [{ required: true, message: '请输入题目正文内容或上传图片', trigger: ['blur'] }]
  }

  // 只有“联想对对碰”类型才需要关键词
  if (questionForm.value.type === QuestionCategoryEnum.AssociationMatching) {
    dynamicRules.KeyWord = [{ required: true, message: '请输入关键词', trigger: ['blur'] }]
    dynamicRules.KeyWordsIndex = [
      {
        required: true,
        validator: (_rule: FormItemRule, value: number) => {
          return typeof value === 'number'
        },
        message: '请输入关键词索引',
        trigger: ['blur', 'change'],
      },
    ]
  }

  return dynamicRules
})

watch(() => props.show, (val) => {
  if (val) {
    if (props.operation === 'add') {
      questionForm.value = {
        name: '',
        answer: '',
        type: props.currentCategory?.QuestionType || QuestionType.SingleChoice,
        imageUrl: '',
        IsGood: 0,
        IsDisabled: false,
        KeyWord: '',
        KeyWordsIndex: 0,
      }
      pinyinTool.value.input = ''
      pinyinTool.value.output = ''
    }
    else if (props.operation === 'edit' && props.questionData) {
      const question = props.questionData
      questionForm.value = {
        name: question.Name,
        answer: question.Answer,
        type: Number(question.Type),
        KeyWord: question.KeyWord || '',
        KeyWordsIndex: question.KeyWordsIndex || 0,
        imageUrl: question.ImageUrl || '',
        IsGood: question.IsPriority || 0,
        IsDisabled: !!question.IsDisabled,
      }
      pinyinTool.value.input = ''
      pinyinTool.value.output = ''
    }
  }
})

async function submitQuestion() {
  const valid = await questionFormRef.value?.validate()

  if (!valid) {
    window?.$message?.error('请填写完整信息')
    return
  }

  const params = {
    ...questionForm.value,
    questionId: props.currentCategory.Id,
    // type: String(questionForm.value.type) as Api.Question.QuestionScoreType,
  }

  if (questionForm.value.type !== QuestionCategoryEnum.AssociationMatching) {
    params.KeyWord = ''
    params.KeyWordsIndex = 0
  }

  if (props.operation === 'add') {
    const { error } = await fetchAddQuestionLibrary({ ...params, id: 0 })
    if (!error) {
      window?.$message?.success('题目添加成功')
      emit('success')
    }
    else {
      window?.$message?.error('添加失败')
    }
  }
  else if (props.operation === 'edit' && props.questionData) {
    const { error } = await fetchUpdateQuestionLibrary({ ...params, id: props.questionData.Id })
    if (!error) {
      window?.$message?.success('题目修改成功')
      emit('success')
    }
    else {
      window?.$message?.error('修改失败')
    }
  }
}
</script>

<template>
  <NDrawer v-model:show="showQuestionModal" :width="800">
    <NDrawerContent :title="props.operation === 'edit' ? '编辑题目详情' : '新增题目详情'">
      <div class="mb-4">
        <NCard size="small" title="🛠️ 拼音助手 (输入汉字获取带音标拼音)" class="bg-gray-50/50">
          <div class="flex gap-2">
            <NInput v-model:value="pinyinTool.input" placeholder="输入汉字..." class="flex-1" />
            <div class="flex flex-1 items-center justify-between border border-gray-200 rounded bg-white px-3 py-1">
              <span class="text-gray-600">{{ pinyinTool.output || '拼音结果将显示在这里' }}</span>
              <textarea id="pinyinCopyTarget" v-model="pinyinTool.output" class="absolute opacity-0 -z-1" />
              <div v-if="pinyinTool.output" ref="copyBtnRef" data-clipboard-target="#pinyinCopyTarget">
                <NButton size="tiny" type="primary" secondary>
                  复制
                </NButton>
              </div>
            </div>
          </div>
        </NCard>
      </div>

      <NForm ref="questionFormRef" label-placement="top" :rules="rules" :model="questionForm" size="small">
        <NFormItem label="题目正文内容" path="name">
          <div
            v-if="[QuestionCategoryEnum.PoetryComprehension, QuestionCategoryEnum.PoetryCommonKnowledge, QuestionCategoryEnum.ReversePoemMatching, QuestionCategoryEnum.ChineseCharacterDictation1].includes(props.currentCategory?.QuestionType)"
            class="w-full overflow-hidden border border-gray-200 rounded-lg"
          >
            <WangEditor
              v-model="questionForm.name" placeholder="请输入题目内容..." height="300px"
              :exclude-keys="['header1', 'fontSize', 'fontFamily', 'lineHeight', 'justifyLeft', 'justifyRight', 'justifyCenter', 'justifyJustify', 'group-image', 'group-video', 'insertTable', 'headerSelect']"
            />
          </div>
          <NInput v-else v-model:value="questionForm.name" type="textarea" placeholder="请输入题目内容" :rows="3" />
        </NFormItem>

        <NFormItem label="是否优先使用" path="IsGood">
          <NRadioGroup v-model:value="questionForm.IsGood">
            <NRadio :value="0">
              否
            </NRadio>
            <NRadio :value="1">
              是
            </NRadio>
          </NRadioGroup>
        </NFormItem>
        <NFormItem label="是否禁用" path="IsDisabled">
          <NRadioGroup v-model:value="questionForm.IsDisabled">
            <NRadio :value="false">
              否
            </NRadio>
            <NRadio :value="true">
              是
            </NRadio>
          </NRadioGroup>
        </NFormItem>
        <NFormItem label="上传图片">
          <OssImageUpload v-model="questionForm.imageUrl" />
        </NFormItem>
        <template v-if="currentCategory?.QuestionType === QuestionCategoryEnum.AssociationMatching">
          <NFormItem label="关键词" path="KeyWord">
            <NInput v-model:value="questionForm.KeyWord" placeholder="请输入关键词" />
          </NFormItem>

          <NFormItem label="关键词索引" path="KeyWordsIndex">
            <NInputNumber v-model:value="questionForm.KeyWordsIndex" placeholder="请输入关键词索引" />
          </NFormItem>
        </template>

        <NFormItem label="参考标准答案" path="answer">
          <NInput v-model:value="questionForm.answer" placeholder="正确答案" />
        </NFormItem>
      </NForm>
      <template #footer>
        <div class="flex justify-end gap-3">
          <NButton @click="showQuestionModal = false">
            取消并返回
          </NButton>
          <NButton type="primary" @click="submitQuestion">
            保存并入库
          </NButton>
        </div>
      </template>
    </NDrawerContent>
  </NDrawer>
</template>
