<template>
  <div class="assessment-analysis">
    <el-tabs v-model="activeTab" type="border-card">
      <el-tab-pane label="全局概览" name="overview">
        <div class="tab-pane-body" v-loading="loading">
          <el-card class="filter-card" shadow="never">
            <el-form :inline="true" size="small">
              <el-form-item label="测评量表">
                <el-select v-model="queryParams.scaleId" clearable filterable placeholder="全部量表" style="width: 220px">
                  <el-option
                    v-for="item in scaleOptions"
                    :key="item.scaleId"
                    :label="item.scaleName"
                    :value="item.scaleId"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="测评时间">
                <el-date-picker
                  v-model="queryParams.dateRange"
                  type="daterange"
                  unlink-panels
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  value-format="yyyy-MM-dd"
                  range-separator="至"
                  style="width: 320px"
                />
              </el-form-item>
              <el-form-item>
                <el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
                <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
              </el-form-item>
            </el-form>
          </el-card>

          <el-row :gutter="16" class="overview-row">
            <el-col v-for="card in overviewCards" :key="card.key" :xs="12" :sm="6" :md="4">
              <el-card class="stat-card" shadow="hover">
                <div class="stat-title">{{ card.label }}</div>
                <div class="stat-value">{{ formatNumber(card.value) }}</div>
                <div class="stat-desc">{{ card.desc }}</div>
              </el-card>
            </el-col>
          </el-row>

          <el-row :gutter="16" class="chart-row">
            <el-col :md="24" :sm="24">
              <el-card shadow="always" class="chart-card">
                <div slot="header" class="chart-card__title">测评状态分布</div>
                <div ref="statusPie" class="chart-container"></div>
              </el-card>
            </el-col>
          </el-row>

          <el-row :gutter="16" class="chart-row">
            <el-col :md="24" :sm="24">
              <el-card shadow="always" class="chart-card">
                <div slot="header" class="chart-card__title">近期待完成趋势</div>
                <div ref="trendChart" class="chart-container trend-chart"></div>
              </el-card>
            </el-col>
          </el-row>

          <el-row :gutter="16" class="detail-row">
            <el-col :md="12" :sm="24">
              <el-card shadow="never">
                <div slot="header" class="detail-title">量表参与 TOP10</div>
                <el-table
                  :data="analytics.scaleDistribution"
                  size="small"
                  height="300"
                  :empty-text="emptyText"
                  border
                >
                  <el-table-column type="index" label="#" width="60" />
                  <el-table-column prop="name" label="量表" show-overflow-tooltip />
                  <el-table-column prop="value" label="参与次数" width="120" align="right" />
                </el-table>
              </el-card>
            </el-col>
            <el-col :md="12" :sm="24">
              <el-card shadow="never">
                <div slot="header" class="detail-title">得分区间分布</div>
                <el-table
                  :data="analytics.scoreRangeDistribution"
                  size="small"
                  height="300"
                  :empty-text="emptyText"
                  border
                >
                  <el-table-column prop="name" label="区间" />
                  <el-table-column prop="value" label="人数" width="120" align="right" />
                </el-table>
              </el-card>
            </el-col>
          </el-row>
        </div>
      </el-tab-pane>

      <el-tab-pane label="学员视角" name="student">
        <div class="tab-pane-body" v-loading="studentLoading">
          <el-card class="filter-card" shadow="never">
            <el-form :inline="true" size="small">
              <el-form-item label="选择学员">
                <el-select
                  v-model="selectedStudentId"
                  style="width: 280px"
                  clearable
                  filterable
                  remote
                  reserve-keyword
                  :remote-method="loadStudentOptions"
                  :loading="studentOptionsLoading"
                  placeholder="输入姓名或账号搜索"
                  @change="handleStudentChange"
                >
                  <el-option
                    v-for="item in studentOptions"
                    :key="item.userId"
                    :label="buildStudentLabel(item)"
                    :value="item.userId"
                  >
                    <div class="student-option">
                      <span class="name">{{ item.nickName || item.userName }}</span>
                      <span class="dept">{{ item.deptName || '未分配单位' }}</span>
                    </div>
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" icon="el-icon-search" :disabled="!selectedStudentId" @click="fetchUserSummary">
                  载入
                </el-button>
                <el-button icon="el-icon-refresh" @click="resetStudentSelection">重置</el-button>
              </el-form-item>
            </el-form>
          </el-card>

          <template v-if="studentSummary">
            <el-card shadow="never" class="student-info-card">
              <el-descriptions size="small" :column="3" border>
                <el-descriptions-item label="罪犯姓名">{{ studentSummary.nickName || studentSummary.userName || '-' }}</el-descriptions-item>
                <el-descriptions-item label="信息编号">{{ studentSummary.infoNumber || '-' }}</el-descriptions-item>
                <el-descriptions-item label="监狱">{{ studentSummary.prisonName || '-' }}</el-descriptions-item>
                <el-descriptions-item label="监区">{{ studentSummary.prisonAreaName || '-' }}</el-descriptions-item>
                <el-descriptions-item label="民族">{{ studentSummary.nation || '-' }}</el-descriptions-item>
                <el-descriptions-item label="文化程度">{{ studentSummary.educationLevel || '-' }}</el-descriptions-item>
                <el-descriptions-item label="罪名">{{ studentSummary.crimeName || '-' }}</el-descriptions-item>
                <el-descriptions-item label="刑期">{{ studentSummary.sentenceTerm || '-' }}</el-descriptions-item>
                <el-descriptions-item label="状态">{{ studentSummary.custodyStatus || '-' }}</el-descriptions-item>
                <el-descriptions-item label="刑期起日">{{ studentSummary.sentenceStartDate || '-' }}</el-descriptions-item>
                <el-descriptions-item label="刑期止日">{{ studentSummary.sentenceEndDate || '-' }}</el-descriptions-item>
                <el-descriptions-item label="入监时间">{{ studentSummary.entryDate || '-' }}</el-descriptions-item>
                <el-descriptions-item label="量表数量">{{ (studentSummary.scales || []).length }}</el-descriptions-item>
                <el-descriptions-item label="测评次数">{{ studentSummary.totalAssessments || 0 }}</el-descriptions-item>
                <el-descriptions-item label="原账号">{{ studentSummary.loginAccount || '-' }}</el-descriptions-item>
              </el-descriptions>
            </el-card>

            <el-collapse v-model="openedScalePanels" accordion class="scale-collapse">
              <el-collapse-item
                v-for="scale in studentScales"
                :key="scale.scaleId"
                :name="scale.scaleId"
                :title="scale.scaleName + '（' + scale.attempts.length + '次）'"
              >
                <div class="scale-attempts">
                  <el-radio-group v-model="scale.selectedAssessmentId" size="mini" class="attempt-radio-group">
                    <el-radio-button
                      v-for="attempt in scale.attempts"
                      :key="attempt.assessmentId"
                      :label="attempt.assessmentId"
                    >
                      {{ attempt.submitTime ? formatDateTime(attempt.submitTime) : '未提交' }}
                    </el-radio-button>
                  </el-radio-group>

                  <div class="attempt-detail" v-if="getSelectedAttempt(scale)">
                    <div class="attempt-detail__row">
                      <div class="attempt-field">
                        <span>提交时间</span>
                        <strong>{{ formatDateTime(getSelectedAttempt(scale).submitTime) }}</strong>
                      </div>
                      <div class="attempt-field">
                        <span>总分</span>
                        <strong>{{ getSelectedAttempt(scale).totalScore != null ? getSelectedAttempt(scale).totalScore : '-' }}</strong>
                      </div>
                      <div class="attempt-field">
                        <span>状态</span>
                        <el-tag size="small" :type="statusTagType(getSelectedAttempt(scale).status)">
                          {{ statusLabel(getSelectedAttempt(scale).status) }}
                        </el-tag>
                      </div>
                    </div>
                    <div class="attempt-summary">
                      <div class="summary-title">报告摘要</div>
                      <div class="summary-content">{{ getSelectedAttempt(scale).reportSummary || '暂无报告摘要' }}</div>
                    </div>
                    <el-button
                      type="primary"
                      size="mini"
                      :disabled="!getSelectedAttempt(scale).reportId"
                      @click="navigateReport(getSelectedAttempt(scale))"
                    >
                      查看报告
                    </el-button>
                  </div>
                </div>
              </el-collapse-item>
            </el-collapse>
          </template>
          <el-empty v-else description="请选择学员查看测评详情"></el-empty>
        </div>
      </el-tab-pane>

      <el-tab-pane label="量表 / 单位" name="scaleDept">
        <div class="tab-pane-body" v-loading="scaleStatsLoading">
          <el-card class="filter-card" shadow="never">
            <el-form :inline="true" size="small">
              <el-form-item label="量表">
                <el-select v-model="scaleDeptForm.scaleId" filterable placeholder="请选择量表" style="width: 220px">
                  <el-option
                    v-for="item in scaleOptions"
                    :key="item.scaleId"
                    :label="item.scaleName"
                    :value="item.scaleId"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="监区">
                <Treeselect
                  v-model="scaleDeptForm.deptIds"
                  :options="deptOptions"
                  :multiple="true"
                  :clearable="true"
                  placeholder="可多选监区单位"
                  style="width: 260px"
                  value-consists-of="LEAF_PRIORITY"
                ></Treeselect>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" icon="el-icon-data-analysis" @click="handleScaleDeptQuery">统计</el-button>
                <el-button icon="el-icon-refresh" @click="resetScaleDeptForm">重置</el-button>
              </el-form-item>
            </el-form>
          </el-card>

          <template v-if="scaleStats && (scaleStats.totalTargets || scaleStats.measuredCount)">
            <el-row :gutter="16" class="overview-row">
              <el-col :md="6" :sm="12">
                <el-card class="stat-card">
                  <div class="stat-title">目标人数</div>
                  <div class="stat-value">{{ formatNumber(scaleStats.totalTargets || 0) }}</div>
                  <div class="stat-desc">选择单位内的全部受测人</div>
                </el-card>
              </el-col>
              <el-col :md="6" :sm="12">
                <el-card class="stat-card">
                  <div class="stat-title">已测评</div>
                  <div class="stat-value">{{ formatNumber(scaleStats.measuredCount || 0) }}</div>
                  <div class="stat-desc">至少完成一次该量表</div>
                </el-card>
              </el-col>
              <el-col :md="6" :sm="12">
                <el-card class="stat-card">
                  <div class="stat-title">未测评</div>
                  <div class="stat-value">{{ formatNumber(scaleStats.unmeasuredCount || 0) }}</div>
                  <div class="stat-desc">尚未参与或未提交</div>
                </el-card>
              </el-col>
              <el-col :md="6" :sm="12">
                <el-card class="stat-card">
                  <div class="stat-title">完成率</div>
                  <div class="stat-value">{{ formatPercent(scaleStats.completionRate) }}</div>
                  <div class="stat-desc">已测评 / 目标人数</div>
                </el-card>
              </el-col>
            </el-row>

            <el-row :gutter="16" class="chart-row">
              <el-col :md="12" :sm="24">
                <el-card shadow="always" class="chart-card">
                  <div slot="header" class="chart-card__title">完成情况</div>
                  <div ref="scaleCompletionPie" class="chart-container"></div>
                </el-card>
              </el-col>
              <el-col :md="12" :sm="24">
                <el-card shadow="always" class="chart-card">
                  <div slot="header" class="chart-card__title">报告结果分布</div>
                  <div ref="scaleResultPie" class="chart-container"></div>
                </el-card>
              </el-col>
            </el-row>
          </template>
          <el-empty v-else description="请选择量表与单位后统计"></el-empty>
        </div>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
import * as echarts from 'echarts'
require('echarts/theme/macarons')
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { parseTime } from '@/utils/common'
import {
  getAssessmentAnalytics,
  getStudentOptions,
  getUserAssessmentSummary,
  getScaleDeptStats
} from '@/api/psychology/assessment'
import { listScale } from '@/api/psychology/scale'
import { getCustodyTreeOptions, findCustodyLabel } from '@/utils/custodyArea'

export default {
  name: 'AssessmentAnalysis',
  components: { Treeselect },
  data() {
    return {
      activeTab: 'overview',
      loading: false,
      studentLoading: false,
      scaleStatsLoading: false,
      queryParams: {
        scaleId: undefined,
        dateRange: []
      },
      scaleOptions: [],
      deptOptions: JSON.parse(JSON.stringify(getCustodyTreeOptions())),
      analytics: this.createEmptyAnalytics(),
      charts: {},
      resizeHandler: null,
      emptyText: '暂无数据',
      studentOptions: [],
      studentOptionsLoading: false,
      selectedStudentId: undefined,
      studentSummary: null,
      studentScales: [],
      openedScalePanels: [],
      scaleDeptForm: {
        scaleId: undefined,
        deptIds: []
      },
      scaleStats: this.createEmptyScaleStats()
    }
  },
  computed: {
    overviewCards() {
      const overview = this.analytics.overview || {}
      return [
        { key: 'total', label: '测评总数', value: overview.totalAssessments || 0, desc: '所有已发起测评' },
        { key: 'completed', label: '已完成', value: overview.completedAssessments || 0, desc: '提交并生成结果' },
        { key: 'inProgress', label: '进行中', value: overview.inProgressAssessments || 0, desc: '仍在答题' },
        { key: 'paused', label: '已暂停', value: overview.pausedAssessments || 0, desc: '等待恢复' },
        { key: 'invalid', label: '已作废', value: overview.invalidAssessments || 0, desc: '无效测评' },
        { key: 'reports', label: '报告数量', value: overview.generatedReports || 0, desc: '已生成报告' },
        { key: 'participants', label: '覆盖人数', value: overview.uniqueParticipants || 0, desc: '参测人员数' }
      ]
    }
  },
  watch: {
    activeTab(val) {
      if (val === 'overview') {
        this.$nextTick(() => this.renderCharts())
      }
      if (val === 'scaleDept') {
        this.$nextTick(() => this.renderScaleDeptCharts())
      }
    }
  },
  created() {
    this.fetchScaleOptions()
    this.loadStudentOptions('')
  },
  mounted() {
    this.resizeHandler = () => {
      Object.values(this.charts).forEach((chart) => {
        if (chart) {
          chart.resize()
        }
      })
    }
    window.addEventListener('resize', this.resizeHandler)
    this.loadAnalytics()
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resizeHandler)
    this.disposeCharts()
  },
  methods: {
    createEmptyAnalytics() {
      return {
        overview: {},
        statusDistribution: [],
        scaleDistribution: [],
        scoreRangeDistribution: [],
        monthlyTrend: []
      }
    },
    createEmptyScaleStats() {
      return {
        totalTargets: 0,
        measuredCount: 0,
        unmeasuredCount: 0,
        completionRate: 0,
        resultDistribution: []
      }
    },
    formatNumber(value) {
      if (!value) {
        return '0'
      }
      return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
    },
    formatPercent(value) {
      if (!value) {
        return '0%'
      }
      return `${parseFloat(value).toFixed(2)}%`
    },
    formatDateTime(value) {
      return value ? parseTime(value) : '-'
    },
    buildQueryParams() {
      const params = {}
      if (this.queryParams.scaleId) {
        params.scaleId = this.queryParams.scaleId
      }
      if (this.queryParams.dateRange && this.queryParams.dateRange.length === 2) {
        params.startDate = this.queryParams.dateRange[0]
        params.endDate = this.queryParams.dateRange[1]
      }
      return params
    },
    handleQuery() {
      this.loadAnalytics()
    },
    resetQuery() {
      this.queryParams.scaleId = undefined
      this.queryParams.dateRange = []
      this.handleQuery()
    },
    fetchScaleOptions() {
      listScale({ pageNum: 1, pageSize: 999 }).then((res) => {
        this.scaleOptions = res.rows || []
      })
    },
    loadAnalytics() {
      this.loading = true
      const params = this.buildQueryParams()
      getAssessmentAnalytics(params)
        .then((res) => {
          const data = res.data || this.createEmptyAnalytics()
          this.analytics = Object.assign(this.createEmptyAnalytics(), data)
          this.$nextTick(() => {
            this.renderCharts()
          })
        })
        .finally(() => {
          this.loading = false
        })
    },
    loadStudentOptions(query) {
      this.studentOptionsLoading = true
      getStudentOptions({ keyword: query, limit: 20 })
        .then((res) => {
          this.studentOptions = res.data || []
        })
        .finally(() => {
          this.studentOptionsLoading = false
        })
    },
    handleStudentChange() {
      if (!this.selectedStudentId) {
        this.studentSummary = null
        this.studentScales = []
        this.openedScalePanels = []
      }
    },
    resetStudentSelection() {
      this.selectedStudentId = undefined
      this.studentSummary = null
      this.studentScales = []
      this.openedScalePanels = []
    },
    fetchUserSummary() {
      if (!this.selectedStudentId) {
        return
      }
      this.studentLoading = true
      getUserAssessmentSummary(this.selectedStudentId)
        .then((res) => {
          this.studentSummary = res.data || null
          const scales = (this.studentSummary && this.studentSummary.scales) ? this.studentSummary.scales : []
          this.studentScales = scales.map((scale) => ({
            ...scale,
            selectedAssessmentId:
              scale.latestAssessmentId || (scale.attempts && scale.attempts.length ? scale.attempts[0].assessmentId : undefined)
          }))
          this.openedScalePanels = this.studentScales.map((item) => item.scaleId)
        })
        .finally(() => {
          this.studentLoading = false
        })
    },
    statusLabel(status) {
      const map = {
        0: '进行中',
        1: '已完成',
        2: '已作废',
        3: '已暂停'
      }
      return map[status] || '未知'
    },
    statusTagType(status) {
      const map = {
        1: 'success',
        0: 'warning',
        3: 'info',
        2: 'danger'
      }
      return map[status] || 'info'
    },
    getSelectedAttempt(scale) {
      if (!scale || !scale.attempts) {
        return null
      }
      return scale.attempts.find((item) => item.assessmentId === scale.selectedAssessmentId) || scale.attempts[0]
    },
    navigateReport(attempt) {
      if (!attempt || !attempt.reportId) {
        this.$modal.msgWarning('当前测评尚未生成报告')
        return
      }
      this.$router.push({ path: '/psychology/assessment/report', query: { assessmentId: attempt.assessmentId } })
    },
    buildStudentLabel(option) {
      if (!option) {
        return ''
      }
      const name = option.nickName || option.userName || ''
      const dept = option.deptName ? ` - ${option.deptName}` : ''
      return name + dept
    },
    handleScaleDeptQuery() {
      if (!this.scaleDeptForm.scaleId) {
        this.$message.warning('请选择量表')
        return
      }
      if (!this.scaleDeptForm.deptIds || this.scaleDeptForm.deptIds.length === 0) {
        this.$message.warning('请至少选择一个监区')
        return
      }
      this.scaleStatsLoading = true
      getScaleDeptStats(this.scaleDeptForm)
        .then((res) => {
          this.scaleStats = Object.assign(this.createEmptyScaleStats(), res.data || {})
          this.$nextTick(() => {
            this.renderScaleDeptCharts()
          })
        })
        .finally(() => {
          this.scaleStatsLoading = false
        })
    },
    resetScaleDeptForm() {
      this.scaleDeptForm.scaleId = undefined
      this.scaleDeptForm.deptIds = []
      this.scaleStats = this.createEmptyScaleStats()
      this.$nextTick(() => this.renderScaleDeptCharts())
    },
    renderCharts() {
      this.renderPie('statusPie', this.analytics.statusDistribution, '测评状态')
      this.renderTrendChart(this.analytics.monthlyTrend, 'trendChart')
    },
    renderScaleDeptCharts() {
      const completionData = [
        { name: '已测评', value: this.scaleStats.measuredCount || 0 },
        { name: '未测评', value: this.scaleStats.unmeasuredCount || 0 }
      ]
      this.renderPie('scaleCompletionPie', completionData, '完成情况')
      this.renderPie(
        'scaleResultPie',
        this.scaleStats.resultDistribution && this.scaleStats.resultDistribution.length
          ? this.scaleStats.resultDistribution
          : [{ name: '暂无数据', value: 0 }],
        '报告结果'
      )
    },
    ensureChartInstance(refName) {
      const dom = this.$refs[refName]
      if (!dom) {
        return null
      }
      if (this.charts[refName]) {
        return this.charts[refName]
      }
      this.charts[refName] = echarts.init(dom, 'macarons')
      return this.charts[refName]
    },
    renderPie(refName, sourceData, title) {
      const chart = this.ensureChartInstance(refName)
      if (!chart) {
        return
      }
      const data = sourceData && sourceData.length > 0 ? sourceData : [{ name: '暂无数据', value: 0 }]
      chart.setOption({
        tooltip: {
          trigger: 'item',
          formatter: '{b} : {c} ({d}%)'
        },
        legend: {
          bottom: 0,
          left: 'center',
          data: data.map((item) => item.name)
        },
        series: [
          {
            name: title,
            type: 'pie',
            radius: ['35%', '70%'],
            center: ['50%', '45%'],
            roseType: 'radius',
            data: data,
            label: {
              formatter: '{b}\n{d}%'
            }
          }
        ]
      })
    },
    renderTrendChart(sourceData, refName) {
      const chart = this.ensureChartInstance(refName)
      if (!chart) {
        return
      }
      const list = sourceData && sourceData.length > 0 ? sourceData : [{ label: '暂无数据', value: 0 }]
      chart.setOption({
        tooltip: {
          trigger: 'axis'
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '5%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: list.map((item) => item.label)
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            name: '测评次数',
            type: 'line',
            smooth: true,
            data: list.map((item) => item.value),
            areaStyle: {
              opacity: 0.15
            },
            lineStyle: {
              width: 3
            },
            itemStyle: {
              color: '#5B8FF9'
            }
          }
        ]
      })
    },
    disposeCharts() {
      Object.keys(this.charts).forEach((key) => {
        if (this.charts[key]) {
          this.charts[key].dispose()
          this.charts[key] = null
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.assessment-analysis {
  .tab-pane-body {
    padding: 12px;
  }
  .filter-card {
    margin-bottom: 16px;
  }
  .overview-row {
    margin-bottom: 16px;
  }
  .chart-row {
    margin-bottom: 16px;
  }
  .stat-card {
    text-align: left;
    margin-bottom: 16px;
    .stat-title {
      font-size: 14px;
      color: #909399;
    }
    .stat-value {
      font-size: 26px;
      font-weight: 600;
      margin: 8px 0;
      color: #303133;
    }
    .stat-desc {
      font-size: 12px;
      color: #c0c4cc;
    }
  }
  .chart-card {
    height: 380px;
    .chart-container {
      width: 100%;
      height: 320px;
    }
    .trend-chart {
      height: 320px;
    }
  }
  .detail-title {
    font-weight: 600;
  }
  .student-info-card {
    margin-bottom: 16px;
  }
  .scale-collapse {
    background: #fff;
  }
  .scale-attempts {
    .attempt-radio-group {
      margin-bottom: 12px;
    }
  }
  .attempt-detail {
    border: 1px dashed #ebeef5;
    padding: 12px;
    border-radius: 4px;
    background: #fafafa;
    .attempt-detail__row {
      display: flex;
      flex-wrap: wrap;
      margin-bottom: 12px;
      .attempt-field {
        width: 220px;
        margin-right: 24px;
        span {
          color: #909399;
          display: block;
        }
        strong {
          font-size: 16px;
        }
      }
    }
    .attempt-summary {
      margin-bottom: 12px;
      .summary-title {
        font-weight: 600;
        margin-bottom: 6px;
      }
      .summary-content {
        color: #606266;
      }
    }
  }
  .student-option {
    display: flex;
    justify-content: space-between;
    .name {
      font-weight: 500;
    }
    .dept {
      color: #909399;
      font-size: 12px;
    }
  }
}
</style>

