<template>
  <div class="full flex direction-column">
    <div class="flex items-center p-extra-small fill-blank header-view">
      <el-button class="m-r-auto" size="small" plain @click="back()">返回</el-button>

      <div class="data-item">
        <user-info></user-info>
      </div>
      <div class="data-item">
        <div class="icon-item">
          <lock-entry />
        </div>
        <div class="icon-item">
          <message></message>
        </div>
      </div>
    </div>
    <div class="flex-1 overflow-hidden flex direction-column">
      <div class="fill-blank p-t-medium-base filter-header">
        <base-form size="small" :items="formItems" :model="model">
          <template #form-item-search>
            <el-button type="primary" :loading="loading1 || loading2" @click="onSearch">刷新</el-button>
          </template>
        </base-form>
      </div>
      <div class="flex-1 flex overflow-hidden p-base">
        <div class="flex-1 flex direction-column overflow-hidden">
          <div class="fill-blank text-center p-t-base table-title">{{ query.markerName }}主观题给分分布</div>
          <div class="flex-1 overflow-hidden fill-blank m-b-base table-box">
            <base-table
              size="small"
              border
              stripe
              height="100%"
              :columns="columns"
              :data="subjectTableData"
              @row-dblclick="onDbClick"
            ></base-table>
          </div>
          <div class="flex-1 overflow-hidden radius-base fill-blank p-base chart-box">
            <vue-echarts class="full" :option="markerSubjectiveChartsOption"></vue-echarts>
          </div>
        </div>
        <div class="flex-1 flex direction-column overflow-hidden m-l-base">
          <div class="fill-blank text-center p-t-base table-title">{{ query.markerName }}客观题给分分布</div>
          <div class="flex-1 overflow-hidden fill-blank m-b-base table-box">
            <base-table
              size="small"
              border
              stripe
              height="100%"
              :columns="columns"
              :data="objectiveTableData"
            ></base-table>
          </div>
          <div class="flex-1 overflow-hidden radius-base fill-blank p-base chart-box">
            <vue-echarts class="full" :option="markerObjectiveChartsOption"></vue-echarts>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="tsx" name="AnalysisPersonnelStatisticsMarker">
/** 评卷员明细统计 */
import { computed, reactive } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { ElButton } from 'element-plus'
import dayjs from 'dayjs'
import VueEcharts from 'vue-echarts'
import Message from '@/components/shared/message/Message.vue'
import UserInfo from '@/components/shared/UserInfo.vue'
import BaseTable from '@/components/element/BaseTable.vue'
import BaseForm from '@/components/element/BaseForm.vue'
import useFetch from '@/hooks/useFetch'
import LockEntry from '@/components/common/LockEntry.vue'

import type { EChartsOption } from 'echarts'
import type { ExtractApiResponse } from '@/api/api'
import type { EpTableColumn, EpFormItem } from 'global-type'

const { back, push } = useRouter()
const { query } = useRoute()

const model = reactive({
  type: 'total',
})

const formItems: EpFormItem[] = [
  {
    label: '统计方式',
    prop: 'type',
    slotType: 'radio',
    rowKey: 'row-1',
    slot: {
      options: [
        { label: 'total', slotLabel: '积累' },
        { label: 'today', slotLabel: '当天' },
      ],
    },
    colProp: {
      span: 4,
      offset: 18,
    },
  },
  {
    slotName: 'search',
    rowKey: 'row-1',
    colProp: {
      span: 2,
    },
  },
]

const {
  fetch: getStatisticObjectiveByMarker,
  result: objectiveByMarker,
  loading: loading1,
} = useFetch('getStatisticObjectiveByMarker')
const {
  fetch: getStatisticSubjectiveByMarker,
  result: subjectiveByMarker,
  loading: loading2,
} = useFetch('getStatisticSubjectiveByMarker')

type TableDataType = ExtractArrayValue<ExtractApiResponse<'getStatisticObjectiveByMarker'>['segmentsByAll']> & {
  groupCount: number
  groupRate: number
  allCount: number
  allRate: number
}

type GroupData = Record<number, { groupCount: number; groupRate: number }>
type AllData = Record<number, { allCount: number; allRate: number }>

const objectiveGroupData = computed<GroupData>(() => {
  return objectiveByMarker.value?.segmentsByGroup?.reduce((result, data) => {
    result[data.scoreStart] = { groupCount: data.count, groupRate: data.rate }
    return result
  }, {} as GroupData)
})

const objectiveAllData = computed<AllData>(() => {
  return objectiveByMarker.value?.segmentsByAll?.reduce((result, data) => {
    result[data.scoreStart] = { allCount: data.count, allRate: data.rate }
    return result
  }, {} as AllData)
})

const subjectiveGroupData = computed<GroupData>(() => {
  return subjectiveByMarker.value?.segmentsByGroup?.reduce((result, data) => {
    result[data.scoreStart] = { groupCount: data.count, groupRate: data.rate }
    return result
  }, {} as GroupData)
})

const subjectiveAllData = computed<AllData>(() => {
  return subjectiveByMarker.value?.segmentsByAll?.reduce((result, data) => {
    result[data.scoreStart] = { allCount: data.count, allRate: data.rate }
    return result
  }, {} as AllData)
})

const objectiveTableData = computed<TableDataType[]>(() => {
  return objectiveByMarker?.value?.segmentsByUser.map((d) => ({
    ...d,
    ...objectiveGroupData.value?.[d.scoreStart],
    ...objectiveAllData.value?.[d.scoreStart],
  }))
})

const subjectTableData = computed<TableDataType[]>(() => {
  return subjectiveByMarker?.value?.segmentsByUser.map((d) => ({
    ...d,
    ...subjectiveGroupData.value?.[d.scoreStart],
    ...subjectiveAllData.value?.[d.scoreStart],
  }))
})

const columns: EpTableColumn<TableDataType>[] = [
  { label: '分数', prop: 'scoreStart' },
  { label: '人数', prop: 'count' },
  { label: '百分比', prop: 'rate', formatter: (row) => `${row.rate}%` },
  { label: '本组人数', prop: 'groupCount' },
  { label: '百分比', prop: 'groupRate', formatter: (row) => `${row.groupRate}%` },
  { label: '全体人数', prop: 'allCount' },
  { label: '百分比', prop: 'allRate', formatter: (row) => `${row.allRate}%` },
]

const onSearch = () => {
  if (query.markerId) {
    const startTime = model.type === 'today' ? dayjs().startOf('day').format('YYYYMMDDHHmmss') : ''
    getStatisticObjectiveByMarker({
      markerId: query.markerId as string,
      startTime,
      endTime: '',
    })
    getStatisticSubjectiveByMarker({
      markerId: query.markerId as string,
      startTime,
      endTime: '',
    })
  }
}

const onDbClick = (row: TableDataType) => {
  if (query.markerId) {
    push({
      name: 'AnalysisViewMarked',
      params: {
        markerId: query.markerId as string,
      },
      query: {
        markerName: query.markerName,
        score: row.scoreStart,
        source: (query.source as string) || '',
        subjectCode: query.subjectCode,
        questionMainNumber: query.questionMainNumber,
      },
    })
  }
}

type StatisticObjectiveByMarker = ExtractApiResponse<'getStatisticObjectiveByMarker'>

type StatisticObjectiveByMarkerValues = StatisticObjectiveByMarker['segmentsByAll']

const getXAxisData = <K extends keyof ExtractArrayValue<StatisticObjectiveByMarkerValues>>(
  field: K,
  data?: StatisticObjectiveByMarkerValues
) => {
  if (!data) {
    return []
  }
  const getValue = (key: K, item: ExtractArrayValue<StatisticObjectiveByMarkerValues>) => {
    return item[key]
  }
  return data?.map((v) => getValue(field, v))
}

const markerSubjectiveChartsOption = computed<EChartsOption>(() => {
  return {
    legend: {
      itemWidth: 14,
      data: ['评卷员主观分布', '小组主观分布', '题组主观分布'],
    },
    xAxis: {
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: { show: false },
      axisLabel: {
        align: 'right',
      },
      data: getXAxisData('scoreStart', subjectiveByMarker?.value?.segmentsByAll),
    },
    yAxis: [
      {
        type: 'value',
      },
      {
        type: 'value',
        axisLabel: {
          formatter: `{value}%`,
        },
        splitLine: { show: false },
      },
    ],
    series: [
      {
        name: '评卷员主观分布',
        type: 'line',
        itemStyle: {
          color: '#8ED14B',
        },
        data: getXAxisData('rate', subjectiveByMarker?.value?.segmentsByUser),
      },
      {
        name: '小组主观分布',
        type: 'line',
        itemStyle: {
          color: '#3B99D4',
        },
        data: getXAxisData('rate', subjectiveByMarker?.value?.segmentsByGroup),
      },
      {
        name: '题组主观分布',
        type: 'line',
        itemStyle: {
          color: '#ff0000',
        },
        data: getXAxisData('rate', subjectiveByMarker?.value?.segmentsByAll),
      },
    ],
  }
})

const markerObjectiveChartsOption = computed<EChartsOption>(() => {
  return {
    legend: {
      itemWidth: 14,
      data: ['评卷员客观分布', '小组客观分布', '题组客观分布'],
    },
    xAxis: {
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: { show: false },
      axisLabel: {
        align: 'right',
      },
      data: getXAxisData('scoreStart', objectiveByMarker?.value?.segmentsByAll),
    },
    yAxis: [
      {
        type: 'value',
      },
      {
        type: 'value',
        axisLabel: {
          formatter: `{value}%`,
        },
        splitLine: { show: false },
      },
    ],
    series: [
      {
        name: '评卷员客观分布',
        type: 'line',
        itemStyle: {
          color: '#8ED14B',
        },
        data: getXAxisData('rate', objectiveByMarker?.value?.segmentsByUser),
      },
      {
        name: '小组客观分布',
        type: 'line',
        itemStyle: {
          color: '#3B99D4',
        },
        data: getXAxisData('rate', objectiveByMarker?.value?.segmentsByGroup),
      },
      {
        name: '题组客观分布',
        type: 'line',
        itemStyle: {
          color: '#ff0000',
        },
        data: getXAxisData('rate', objectiveByMarker?.value?.segmentsByAll),
      },
    ],
  }
})

onSearch()
</script>

<style scoped lang="scss">
.header-view {
  background-color: #333;
  height: 60px;
  ::v-deep(.data-item) {
    // padding-left: 20px;
    padding-left: 15px;
    padding-right: 15px;
    position: relative;
    height: 100%;
    display: flex;
    align-items: center;
    color: #8a8a8a;
    .icon-item {
      // width: 45px;
      padding: 0 10px;
      height: 100%;
      display: flex;
      flex-direction: column;
      justify-content: flex-end;
    }
    &:first-child {
      margin-left: auto;
    }
    &:not(:last-child) {
      &:after {
        content: '';
        position: absolute;
        right: 0;
        top: 0;
        width: 1px;
        height: 100%;
        background-color: #464646;
      }
    }
    &.is-last:after {
      width: 0;
    }
    .main-ques-info {
      text-align: center;
      font-weight: bold;
      color: $color--primary;
      margin-bottom: 5px;
      max-width: 130px;
    }
  }
}
.filter-header {
  border-top: 1px solid #eee;
  border-bottom: 1px solid #eee;
}
.chart-box {
  height: 350px;
}
</style>
