<template>
  <Dialog
    style="display: none"
    title="问卷预览"
    v-model="dialogVisible"
    width="900px"
    :fullscreen="false"
  >
    <div ref="previewRef" class="questionnaire-preview" v-loading="loading">
      <!-- 问卷头部信息 -->
      <h1 class="preview-header">{{ recordInfo?.questionnaireName }}</h1>

      <!-- 问卷说明 -->
      <div v-if="recordInfo?.description" class="preview-description">
        <div class="section-title">问卷说明</div>
        <div class="description-content" v-html="recordInfo.description"></div>
      </div>

      <!-- 填写说明 -->
      <div v-if="recordInfo?.instruction" class="preview-instruction">
        <div class="section-title">填写说明</div>
        <div class="instruction-content">{{ recordInfo.instruction }}</div>
      </div>

      <!-- 问题列表（按分区显示） -->
      <div class="preview-questions">
        <template v-for="(partition, index) in partitions" :key="partition.name || 'default'">
          <!-- 分区标题 -->
          <div v-if="partition.name" class="partition-title">
            {{ ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'][index] }}、
            {{ partition.name }}
            <span class="question-count">({{ partition.questions.length }} 道题)</span>
          </div>

          <!-- 问题列表 -->
          <div class="question-items">
            <div
              v-for="(questionWithAnswer, index) in partition.questions"
              :key="questionWithAnswer.question.id"
              class="question-item"
            >
              <span class="question-index">{{ index + 1 }}.</span>
              <span class="question-title">{{ questionWithAnswer.question.title }}：</span>

              <!-- 帮助说明 -->
              <span v-if="questionWithAnswer.question.helpText" class="question-help-inline">
                {{ questionWithAnswer.question.helpText }}
              </span>

              <!-- 单选/多选题 -->
              <span
                v-if="
                  questionWithAnswer.question.type === 1 || questionWithAnswer.question.type === 2
                "
                class="question-options-inline"
              >
                <span
                  v-for="option in getQuestionOptions(questionWithAnswer.question)"
                  :key="option.label"
                  class="option-item"
                >
                  <span
                    v-if="
                      questionWithAnswer.question.type === 1 &&
                      questionWithAnswer.answer?.answerText?.trim() === option.label
                    "
                  >
                    ☑
                    {{ option.label }}
                  </span>
                  <span
                    v-if="
                      questionWithAnswer.question.type === 1 &&
                      questionWithAnswer.answer?.answerText?.trim() !== option.label
                    "
                  >
                    ☐
                    {{ option.label }}
                  </span>
                  <span
                    v-if="
                      questionWithAnswer.question.type === 2 &&
                      getSelectedLabels(questionWithAnswer.answer).includes(option.label)
                    "
                  >
                    ☑
                    {{ option.label }}
                  </span>
                  <span
                    v-if="
                      questionWithAnswer.question.type === 2 &&
                      !getSelectedLabels(questionWithAnswer.answer).includes(option.label)
                    "
                  >
                    ☐
                    {{ option.label }}
                  </span>
                </span>
              </span>

              <!-- 填空题 -->
              <span
                v-else-if="questionWithAnswer.question.type === 3"
                class="question-input-inline"
              >
                {{ getAnswerDisplayValue(questionWithAnswer.answer) }}
              </span>

              <!-- 评分题 -->
              <span
                v-else-if="questionWithAnswer.question.type === 4"
                class="question-rating-inline"
              >
                <span class="question-input-inline">{{
                  getAnswerDisplayValue(questionWithAnswer.answer)
                }}</span>
              </span>

              <!-- 日期题 -->
              <span v-else-if="questionWithAnswer.question.type === 5" class="question-date-inline">
                <span
                  class="date-info"
                  v-if="
                    getRangeValue(questionWithAnswer.question, 'min') ||
                    getRangeValue(questionWithAnswer.question, 'max')
                  "
                >
                  日期范围：{{ getRangeValue(questionWithAnswer.question, 'min') || '无限制' }} ~
                  {{ getRangeValue(questionWithAnswer.question, 'max') || '无限制' }}
                </span>
                <span class="question-input-inline">{{
                  getAnswerDisplayValue(questionWithAnswer.answer)
                }}</span>
              </span>

              <!-- 数字题 -->
              <span
                v-else-if="questionWithAnswer.question.type === 6"
                class="question-number-inline"
              >
                <span class="question-input-inline">{{
                  getAnswerDisplayValue(questionWithAnswer.answer)
                }}</span>
              </span>
            </div>
          </div>
        </template>
      </div>

      <!-- 空状态 -->
      <el-empty v-if="partitions.length === 0 && !loading" description="暂无问题" />
    </div>

    <template #footer>
      <el-button type="primary" @click="exportToWord" :loading="loading">导出Word</el-button>
      <el-button @click="dialogVisible = false">关 闭</el-button>
    </template>
  </Dialog>
</template>

<script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { QuestionnaireRecordApi, type QuestionnaireRecord } from '@/api/prison/questionnairerecord'
import { AnswerApi, type Answer } from '@/api/prison/answer'
import { QuestionApi, Question } from '@/api/prison/question'
import { asBlob } from 'html-docx-js-typescript'
import { saveAs } from 'file-saver'

defineOptions({ name: 'QuestionnaireOutput' })

const message = useMessage()
const dialogVisible = ref(false)
const loading = ref(false)
const previewRef = ref<HTMLElement | null>(null)

const recordInfo = ref<QuestionnaireRecord | null>(null)
const answers = ref<Answer[]>([])

const questions = ref<Question[]>([])
const questionnaireInfo = ref<any>(null) // 问卷详细信息(包含description和instruction)

// 分区列表（带答案）
interface QuestionWithAnswer {
  question: Question
  answer?: Answer
  index: number
}

const partitions = computed(() => {
  const partMap = new Map<string, QuestionWithAnswer[]>()

  questions.value.forEach((q, index) => {
    const partName = q.partName || ''
    const answer = answers.value.find((a) => a.questionId === q.id)

    if (!partMap.has(partName)) {
      partMap.set(partName, [])
    }
    partMap.get(partName)!.push({
      question: q,
      answer,
      index: index + 1
    })
  })

  // 按分区排序
  const sortedParts = Array.from(partMap.entries()).sort((a, b) => {
    const sortA = a[1][0]?.question.partSort ?? 0
    const sortB = b[1][0]?.question.partSort ?? 0
    return sortA - sortB
  })

  // 构建分区列表
  const result: Array<{ name: string; questions: QuestionWithAnswer[] }> = []

  // 添加默认分区
  const defaultQuestions = sortedParts.find(([name]) => !name)
  if (defaultQuestions) {
    result.push({
      name: '',
      questions: defaultQuestions[1]
    })
  }

  // 添加其他分区
  sortedParts
    .filter(([name]) => name)
    .forEach(([name, qs]) => {
      result.push({
        name,
        questions: qs
      })
    })

  return result
})

/** 根据问题ID获取答案 */
const getAnswerByQuestionId = (questionId: number): Answer | undefined => {
  return answers.value.find((a) => a.questionId === questionId)
}

/** 获取答案显示值（兼容不同字段名） */
const getAnswerDisplayValue = (answer?: Answer): string => {
  if (!answer) return ''
  // 优先使用 answerText，其次使用 optionIds，并去除前后空格和特殊字符
  const value = answer.answerText || answer.optionIds || ''
  return String(value).trim().replace(/^["']|["']$/g, '')
}

/** 问卷类型标签 */
const getTypeLabel = (type: number) => {
  const options = getIntDictOptions(DICT_TYPE.PRISON_QUESTIONNAIRE_TYPE)
  return options.find((o) => o.value === type)?.label || '未知'
}

/** 获取问题选项 */
const getQuestionOptions = (question: Question) => {
  if (!question.options) return []
  try {
    const parsed = JSON.parse(question.options)
    // 标准化选项格式，添加索引作为 value
    if (Array.isArray(parsed)) {
      return parsed.map((opt, index) => ({
        label: opt.label ?? opt.text ?? opt.name ?? String(opt),
        value: String(index), // 使用索引作为值
        score: opt.score ?? 0
      }))
    }
    return []
  } catch {
    return []
  }
}

/** 获取范围值（用于日期、数字、评分题） */
const getRangeValue = (question: Question, key: 'min' | 'max') => {
  if (!question.options) return undefined
  try {
    const obj = JSON.parse(question.options)
    return obj[key] || undefined
  } catch {
    return undefined
  }
}

/** 安全获取多选答案的标签数组 */
const getSelectedLabels = (answer?: Answer): string[] => {
  if (!answer?.answerText) return []
  return answer.answerText.split(',').map((s) => s.trim())
}

/** 判断选项是否被选中（支持单选和多选）- 已废弃，改用模板直接绑定 */
const isOptionSelected = (
  answer?: Answer,
  optionValue?: string,
  optionLabel?: string,
  questionType?: number
): boolean => {
  if (!answer || !optionValue || !optionLabel) {
    return false
  }

  // 多选（type === 2）：answerText 是逗号分隔的标签列表
  if (questionType === 2 && answer.answerText && answer.answerText.includes(',')) {
    const answerText = answer.answerText
    const selectedLabels = answerText.split(',').map((s) => s.trim())
    return selectedLabels.includes(optionLabel)
  }

  // 单选（type === 1）：answerText 等于选项标签（去除首尾空格后比较）
  if (questionType === 1 && answer.answerText) {
    return answer.answerText.trim() === optionLabel.trim()
  }

  // 兼容：没有 questionType 时，根据是否有逗号判断
  if (answer.answerText && answer.answerText.includes(',')) {
    const answerText = answer.answerText
    const selectedLabels = answerText.split(',').map((s) => s.trim())
    return selectedLabels.includes(optionLabel)
  }

  if (answer.answerText?.trim() === optionLabel?.trim()) return true

  return false
}

/** 打开弹窗 */
const open = async (recordId: number) => {
  dialogVisible.value = true
  loading.value = true

  try {
    // 并行加载数据
    const [recordData, answerList] = await Promise.all([
      QuestionnaireRecordApi.getQuestionnaireRecord(recordId),
      AnswerApi.getAnswersByAssessmentRecordId(recordId)
    ])

    recordInfo.value = recordData
    answers.value = answerList

    // 加载问题列表
    if (recordData.questionnaireId) {
      const questionsData = await QuestionApi.getQuestionPage({
        pageNo: 1,
        pageSize: 200,
        questionnaireId: recordData.questionnaireId
      })
      questions.value = questionsData.list
    }

    // 加载问卷详细信息(用于导出Word时获取description和instruction)
    if (recordData.questionnaireId) {
      try {
        const { QuestionnaireApi } = await import('@/api/prison/questionnaire')
        questionnaireInfo.value = await QuestionnaireApi.getQuestionnaire(
          recordData.questionnaireId
        )
      } catch (error) {
        console.warn('加载问卷详细信息失败:', error)
      }
    }
  } catch (error) {
    console.error('加载答题详情失败:', error)
  } finally {
    loading.value = false
    exportToWord()
    dialogVisible.value = false
  }
}

/** 跳转到填写页面 */
const openFillPage = () => {
  // TODO: 实现跳转到填写页面的逻辑
  message.info('填写页面功能待实现')
}

/** 导出为Word文档 - 直接使用预览容器的HTML */
const exportToWord = async () => {
  try {
    loading.value = true

    if (!previewRef.value) {
      message.error('预览内容未加载完成')
      return
    }

    // 获取预览容器的HTML内容
    let previewHTML = previewRef.value.innerHTML
    
    // 清理可能导致WPS显示引号的特殊字符
    previewHTML = previewHTML.replace(/[\u201C\u201D\u2018\u2019]/g, '') // 移除中文引号
    previewHTML = previewHTML.replace(/^["']|["']$/gm, '') // 移除行首尾的引号

    // 构建完整的HTML文档，使用与预览页面一致的样式
    const fullHTML = `
      <html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word'>
      <head>
        <meta charset="utf-8">
        <title>${recordInfo.value?.questionnaireName || '问卷'}</title>
        <style>
          /* 使用 pt 单位以避免 Word/WPS 在 px->pt 换算时产生差异 */
          body {
            font-family: 'Microsoft YaHei', '微软雅黑', SimSun, Arial, sans-serif;
            font-size: 11pt;
            margin: 15pt;
            padding: 15pt;
          }
          h1 {
            font-family: 'Microsoft YaHei', '微软雅黑', SimSun, Arial, sans-serif;
            font-size: 18pt;
            font-weight: 500;
            color: #000;
            text-align: center;
          }
          .section-title {
            font-family: 'Microsoft YaHei', '微软雅黑', SimSun, Arial, sans-serif;
            margin-bottom: 15pt;
            font-size: 18pt;
            font-weight: 700;
            color: #000;
          }
          .description-content {
            color: #000;
            font-size: 11pt;
            margin-bottom: 6pt;
            line-height: 1.5;
          }
          .instruction-content {
            color: #000;
            font-size: 11pt;
            font-weight: 500;
            margin-bottom: 6pt;
            line-height: 1.5;
          }
          .partition-title {
            margin-top: 15pt;
            color: #000;
            font-size: 15pt;
            font-weight: 500;
          }
          .partition-title:first-child {
            margin-top: 0;
          }
          .question-count {
            font-size: 11pt;
            color: #909399;
            font-weight: normal;
            margin-left: 2pt;
          }
          .question-item {
            font-size: 11pt;
            color: #000;
            margin-bottom: 8pt;
            line-height: 1.5;
            page-break-inside: avoid;
          }
          .question-index {
            margin-right: 2pt;
          }
          .question-title {
            margin-right: 4pt;
          }
          .question-help-inline {
            display: inline-flex;
            align-items: center;
            gap: 3pt;
            color: #909399;
            font-size: 11pt;
            background: #f4f4f5;
            border-radius: 2pt;
            margin-right: 6pt;
          }
          .question-options-inline {
            display: inline-flex;
            flex-wrap: wrap;
            gap: 8pt;
            align-items: center;
          }
          .option-item {
            display: inline-flex;
            align-items: center;
            gap: 3pt;
          }
          .question-rating-inline,
          .question-date-inline,
          .question-number-inline {
            display: inline-flex;
            align-items: center;
            gap: 8pt;
            flex-wrap: wrap;
            margin-left: 3pt;
          }
          .rating-info,
          .date-info,
          .number-info {
            display: inline-flex;
            gap: 11pt;
            color: #909399;
            font-size: 11pt;
          }
          .question-input-inline {
            color: #000;
            font-size: 11pt;
            line-height: 1.5;
            text-decoration: underline;
          }
        </style>
      </head>
      <body>
        ${previewHTML}
      </body>
      </html>
    `

    // 转换为Blob (asBlob返回Promise)
    const converted = await asBlob(fullHTML)

    // 下载文件
    const fileName = `${recordInfo.value?.questionnaireName || '问卷'}_${new Date().toLocaleDateString('zh-CN')}.docx`
    saveAs(converted as Blob, fileName)

    message.success('Word文档导出成功')
  } catch (error) {
    console.error('导出Word失败:', error)
    message.error('导出Word失败，请重试')
  } finally {
    loading.value = false
  }
}

defineExpose({ open, exportToWord })
</script>

<style scoped lang="scss">
.questionnaire-preview {
  padding: 20px;
  background: #f5f7fa;
  border-radius: 8px;
}

h1 {
  font-family: 'Microsoft YaHei', '微软雅黑', SimSun, Arial, sans-serif;
  font-size: 18pt;
  font-weight: 500;
  color: #000;
  text-align: center;
}
.section-title {
  font-family: 'Microsoft YaHei', '微软雅黑', SimSun, Arial, sans-serif;
  margin-bottom: 15pt;
  font-size: 18pt;
  font-weight: 700;
  color: #000;
}
.description-content {
  color: #000;
  line-height: 3;
  font-size: 11pt;
}
.instruction-content {
  color: #000;
  font-size: 11pt;
  font-weight: 500;
  line-height: 3;
}
.partition-title {
  margin-top: 15pt;
  color: #000;
  font-size: 15pt;
  font-weight: 500;
}
.partition-title:first-child {
  margin-top: 0;
}
.question-count {
  font-size: 11pt;
  color: #909399;
  font-weight: normal;
  margin-left: 2pt;
}
.question-item {
  font-size: 11pt;
  color: #000;
  line-height: 3;
  page-break-inside: avoid;
}
.question-index {
  margin-right: 2pt;
}
.question-title {
  margin-right: 4pt;
}
.question-help-inline {
  display: inline-flex;
  align-items: center;
  gap: 3pt;
  color: #909399;
  font-size: 11pt;
  background: #f4f4f5;
  border-radius: 2pt;
  margin-right: 6pt;
}
.question-options-inline {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8pt;
  align-items: center;
}
.option-item {
  display: inline-flex;
  align-items: center;
  gap: 3pt;
}
.question-rating-inline,
.question-date-inline,
.question-number-inline {
  display: inline-flex;
  align-items: center;
  gap: 8pt;
  flex-wrap: wrap;
  margin-left: 3pt;
}
.rating-info,
.date-info,
.number-info {
  display: inline-flex;
  gap: 11pt;
  color: #909399;
  font-size: 11pt;
}
.question-input-inline {
  color: #000;
  font-size: 11pt;
  line-height: 3;
  text-decoration: underline;
}
</style>
