<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible" width="900px">
    <div v-loading="loading" class="questionnaire-fill-dialog">
      <!-- 问卷信息头部 -->
      <div class="questionnaire-header">
        <h3 class="questionnaire-name">{{ questionnaireName }}</h3>
        <p class="questionnaire-tip">请根据实际情况填写以下问卷内容</p>
      </div>

      <!-- 分区列表 -->
      <div class="parts-container">
        <el-collapse v-model="activeParts" accordion>
          <el-collapse-item
            v-for="partition in partitions"
            :key="partition.name || 'default'"
            :name="partition.name || 'default'"
            :title="partition.name || '默认分区'"
          >
            <template #title>
              <div class="part-title">
                <span>{{ partition.name || '默认分区' }}</span>
                <el-tag size="small" type="info">{{ partition.questions.length }} 题</el-tag>
              </div>
            </template>

            <!-- 问题列表 -->
            <div class="questions-list">
              <div
                v-for="(question, qIndex) in partition.questions"
                :key="question.id"
                class="question-item"
                :class="{ 'is-required': question.isRequired }"
              >
                <div class="question-header">
                  <span class="question-index">{{ qIndex + 1 }}.</span>
                  <span class="question-title">
                    {{ question.title }}
                    <el-tag v-if="question.isRequired" type="danger" size="small">必填</el-tag>
                  </span>
                </div>

                <!-- 帮助说明 -->
                <div v-if="question.helpText" class="question-help">
                  <Icon icon="ep:info-filled" />
                  {{ question.helpText }}
                </div>

                <!-- 答题区域 -->
                <div class="question-answer">
                  <AutoFill
                    v-model="answers[question.id!]"
                    :question-type="question.type"
                    :fill-type="question.autoFillType || 'NONE'"
                    :fill-source="question.autoFillSource"
                    :prisoner-id="prisonerId"
                    :options="question.options"
                    :placeholder="question.placeholder"
                    :is-required="question.isRequired"
                    :min-value="question.minValue"
                    :max-value="question.maxValue"
                  />
                </div>
              </div>
            </div>
          </el-collapse-item>
        </el-collapse>
      </div>
    </div>

    <template #footer>
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" :loading="submitLoading" @click="handleSubmit">
        提交问卷
      </el-button>
    </template>
  </Dialog>
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue'
import { QuestionApi } from '@/api/prison/question'
import { QuestionnaireRecordApi } from '@/api/prison/questionnairerecord'
import AutoFill from '@/components/AutoFill/index.vue'
import type { Question, AutoFillType } from '@/api/prison/question'

defineOptions({ name: 'QuestionnaireFillDialog' })

const emit = defineEmits(['success'])

const dialogVisible = ref(false)
const dialogTitle = ref('问卷填写')
const loading = ref(false)
const submitLoading = ref(false)

// 入参
const recordId = ref<number>(0)
const prisonerId = ref<number>(0)
const questionnaireId = ref<number>(0)
const questionnaireName = ref('')
const recordStatus = ref<number>(0) // 记录状态：1-待测评 2-测评中

// 问题列表
const questions = ref<Question[]>([])
// 答案存储：支持 string（单选/填空）和 string[]（多选）
const answers = ref<Record<number, string | string[] | undefined>>({})

// 展开的分区
const activeParts = ref<string[]>([])

// 分区列表
const partitions = computed(() => {
  const partMap = new Map<string, Question[]>()
  const defaultPart: Question[] = []

  questions.value.forEach(q => {
    const partName = q.partName || ''
    if (partName) {
      if (!partMap.has(partName)) {
        partMap.set(partName, [])
      }
      partMap.get(partName)!.push(q)
    } else {
      defaultPart.push(q)
    }
  })

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

  // 添加默认分区
  if (defaultPart.length > 0) {
    result.push({ name: '', questions: defaultPart })
  }

  // 添加其他分区（按排序）
  Array.from(partMap.entries())
    .sort((a, b) => {
      const partA = questions.value.find(q => q.partName === a[0])
      const partB = questions.value.find(q => q.partName === b[0])
      const sortA = partA?.partSort ?? 0
      const sortB = partB?.partSort ?? 0
      return sortA - sortB
    })
    .forEach(([name, qs]) => {
      result.push({ name, questions: qs })
    })

  return result
})

// 打开弹窗
const open = async (opts: {
  recordId: number
  prisonerId: number
  questionnaireId: number
  questionnaireName: string
}) => {
  recordId.value = opts.recordId
  prisonerId.value = opts.prisonerId
  questionnaireId.value = opts.questionnaireId
  questionnaireName.value = opts.questionnaireName

  dialogVisible.value = true
  // 先获取记录详情，获取当前状态
  await loadRecordDetail()
  await loadQuestions()
}

// 获取记录详情
const loadRecordDetail = async () => {
  if (!recordId.value) return
  try {
    const res = await QuestionnaireRecordApi.getQuestionnaireRecord(recordId.value)
    recordStatus.value = res.status || 0
  } catch (e) {
    console.error('获取记录详情失败:', e)
  }
}

defineExpose({ open })

// 加载问题列表
const loadQuestions = async () => {
  if (!questionnaireId.value) return

  loading.value = true
  try {
    const allQuestions: Question[] = []
    let pageNo = 1
    const pageSize = 200 // 后端每页最大限制

    // 循环获取所有问题
    while (true) {
      const res = await QuestionApi.getQuestionPage({
        pageNo,
        pageSize,
        questionnaireId: questionnaireId.value
      })

      allQuestions.push(...res.list)

      // 如果已经是最后一页，退出循环
      if (res.list.length < pageSize || !res.pageInfo || res.pageInfo.total <= allQuestions.length) {
        break
      }
      pageNo++
    }

    questions.value = allQuestions
    // 重置答案
    answers.value = {}
    questions.value.forEach(q => {
      answers.value[q.id!] = undefined
    })

    // 默认展开第一个分区
    if (partitions.value.length > 0) {
      activeParts.value = [partitions.value[0].name || 'default']
    }
  } finally {
    loading.value = false
  }
}

// 验证必填项
const validateRequired = (): boolean => {
  for (const q of questions.value) {
    if (q.isRequired) {
      const answer = answers.value[q.id!]
      // 多选：至少选一个
      if (q.type === 2) {
        if (!answer || (Array.isArray(answer) && answer.length === 0)) {
          return false
        }
      } else {
        // 单选/填空等
        if (!answer) {
          return false
        }
      }
    }
  }
  return true
}

// 获取未填写的必填项
const getMissingRequired = (): Question | null => {
  for (const q of questions.value) {
    if (q.isRequired) {
      const answer = answers.value[q.id!]
      if (q.type === 2) {
        if (!answer || (Array.isArray(answer) && answer.length === 0)) {
          return q
        }
      } else {
        if (!answer) {
          return q
        }
      }
    }
  }
  return null
}

// 提交问卷
const handleSubmit = async () => {
  // 验证必填项
  const missing = getMissingRequired()
  if (missing) {
    // 找到缺失的分区并展开
    const part = partitions.value.find(p => p.questions.some(q => q.id === missing.id))
    if (part) {
      activeParts.value = [part.name || 'default']
    }
    // 等待 DOM 更新后滚动到缺失位置
    setTimeout(() => {
      const el = document.querySelector('.question-item.is-required .el-form-item__error')
      el?.scrollIntoView({ behavior: 'smooth', block: 'center' })
    }, 100)
    return
  }

  // 构建答案列表
  const answerList = questions.value.map(q => {
    const answer = answers.value[q.id!]

    // 处理多选题（type === 2）
    if (q.type === 2 && Array.isArray(answer)) {
      // 解析选项获取文字
      let optionLabels: string[] = []
      try {
        const options = JSON.parse(q.options || '[]') as Array<{ label: string }>
        optionLabels = answer
          .map((idx: string) => options[parseInt(idx)]?.label)
          .filter((label): label is string => !!label)
      } catch (e) {
        console.error('解析选项失败:', e)
      }

      return {
        questionId: q.id!,
        answer: optionLabels.join('、') || '',
        optionIds: answer.map((idx: string) => parseInt(idx, 10))
      }
    }

    // 单选题（type === 1）：如果选择了"其他"选项，需要发送 optionIds
    if (q.type === 1 && answer) {
      const answerIndex = parseInt(answer as string, 10)
      let isOtherOption = false

      try {
        const options = JSON.parse(q.options || '[]') as Array<{ isOther?: boolean }>
        isOtherOption = options[answerIndex]?.isOther === true
      } catch (e) {
        console.error('解析选项失败:', e)
      }

      // 解析选项获取文字
      let answerText = answer as string
      try {
        const options = JSON.parse(q.options || '[]') as Array<{ label: string }>
        answerText = options[answerIndex]?.label || answer as string
      } catch (e) {
        console.error('解析选项失败:', e)
      }

      return {
        questionId: q.id!,
        answer: answerText,
        optionIds: isOtherOption ? [answerIndex] : undefined
      }
    }

    // 填空题、评分题、日期题、数字题（type 3/4/5/6）
    return {
      questionId: q.id!,
      answer: String(answer || ''),
      optionIds: undefined
    }
  })

  submitLoading.value = true
  try {
    // 如果状态是"待测评(1)"，需要先开始测评
    if (recordStatus.value === 1) {
      await QuestionnaireRecordApi.startAssessment(recordId.value, prisonerId.value)
    }
    // 提交答卷
    await QuestionnaireRecordApi.submitAnswer({
      recordId: recordId.value,
      prisonerId: prisonerId.value,
      answers: answerList
    })

    // 提交成功后结束测评
    await QuestionnaireRecordApi.finishAssessment(recordId.value)

    dialogVisible.value = false
    emit('success')
  } catch (e) {
    console.error('提交失败:', e)
  } finally {
    submitLoading.value = false
  }
}
</script>

<style lang="scss" scoped>
.questionnaire-fill-dialog {
  max-height: 70vh;
  overflow-y: auto;
  padding: 0 10px;
}

.questionnaire-header {
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid #ebeef5;

  .questionnaire-name {
    margin: 0 0 8px;
    font-size: 18px;
    font-weight: 600;
    color: #303133;
  }

  .questionnaire-tip {
    margin: 0;
    color: #909399;
    font-size: 14px;
  }
}

.parts-container {
  :deep(.el-collapse-item__header) {
    font-weight: 600;
    font-size: 15px;
    padding-left: 16px;
  }

  :deep(.el-collapse-item__content) {
    padding-bottom: 0;
  }
}

.part-title {
  display: flex;
  align-items: center;
  gap: 12px;
}

.questions-list {
  padding: 16px;
}

.question-item {
  padding: 16px;
  margin-bottom: 12px;
  background: #fafafa;
  border-radius: 8px;
  border: 1px solid #ebeef5;

  &:last-child {
    margin-bottom: 0;
  }

  &.is-required {
    background: #fff7f7;
    border-color: #fbc4c4;
  }
}

.question-header {
  display: flex;
  align-items: flex-start;
  margin-bottom: 12px;
}

.question-index {
  color: #409eff;
  font-weight: 600;
  margin-right: 8px;
  flex-shrink: 0;
}

.question-title {
  font-size: 15px;
  color: #303133;
  line-height: 1.5;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.question-help {
  margin-bottom: 12px;
  padding: 8px 12px;
  background: #ecf5ff;
  border-radius: 4px;
  font-size: 13px;
  color: #409eff;
  display: flex;
  align-items: center;
  gap: 6px;
}

.question-answer {
  margin-top: 8px;
}
</style>
