<template>
  <div class="p-small radius-base fill-blank">
    <base-table
      ref="tableRef"
      size="small"
      :data="tableData"
      :columns="columns"
      :height="useVW(300)"
      highlight-current-row
      @current-change="onCurrentChange"
    >
      <template #column-marker="{ row }">
        <el-popover
          :ref="(popover: any) => setPopoverRefs(row.markerId,popover)"
          trigger="contextmenu"
          placement="right"
          :show-arrow="false"
          transition="none"
          @show="onPopoverShow(row.markerId)"
        >
          <template #reference>
            <el-button size="small" link type="primary">{{ row.markerName }}</el-button>
          </template>
          <el-menu @select="() => {}">
            <el-menu-item index="setting" @click="onSetWorkload(row)">
              <el-button link>设置工作量</el-button>
            </el-menu-item>
            <el-menu-item index="send" @click="onSendMessage(row)">
              <el-button link>发送消息</el-button>
            </el-menu-item>
          </el-menu>
        </el-popover>
      </template>
    </base-table>
  </div>
  <div class="flex justify-between m-t-base">
    <div class="flex-1 p-base radius-base fill-blank m-r-base chart-box">
      <vue-e-charts class="full" :option="markerSubjectiveChartsOption"></vue-e-charts>
    </div>
    <div class="flex-1 p-base radius-base fill-blank chart-box">
      <vue-e-charts class="full" :option="markerObjectiveChartsOption"></vue-e-charts>
    </div>
  </div>
  <set-workload v-model="setWorkloadVisible" :data="setWorkloadData" />
</template>

<script setup lang="tsx" name="StatisticsPersonnel">
/** 人员数据统计-按人员展开 */
import { reactive, ref, inject, computed, watch } from 'vue'
import { ElButton, ElPopover, ElMenu, ElMenuItem } from 'element-plus'
import VueECharts from 'vue-echarts'
import BaseTable from '@/components/element/BaseTable.vue'
import SetWorkload from './SetWorkload.vue'
import useVW, { usePX } from '@/hooks/useVW'
import useFetch from '@/hooks/useFetch'
import useTableCheck from '@/hooks/useTableCheck'

import type { EChartsOption } from 'echarts'
import type { ExtractApiResponse, ExtractApiParams } from '@/api/api'
import type { EpTableColumn } from 'global-type'
import type { PopoverInstance } from 'element-plus'

const props = defineProps<{
  data: ExtractApiResponse<'getStatisticsByGroup'>
  params: ExtractApiParams<'getStatisticsByGroup'> & { expand: boolean }
}>()

const setMessageVisible = inject<(visible: boolean) => void>('setMessageVisible')
const setReplyUserId = inject<(id: number) => void>('setReplyUserId')

const columns: EpTableColumn<ExtractArrayValue<ExtractApiResponse<'getStatisticsByGroup'>>>[] = [
  {
    label: '小组',
    prop: 'markingGroupNumber',
    width: usePX(52),
    formatter(row) {
      return `第${row.markingGroupNumber}组`
    },
  },
  { label: '评卷员', prop: 'markerName', minWidth: usePX(84), slotName: 'marker' },
  { align: 'center', label: '评卷份数', prop: 'markingPaperCount', width: usePX(72) },
  { align: 'center', label: '客观题0分量', prop: 'objectiveZero', width: usePX(84) },
  { align: 'center', label: '客观平均分', prop: 'objectiveAvg', width: usePX(76) },
  { align: 'center', label: '客观标准差', prop: 'objectiveStd', width: usePX(76) },
  { align: 'center', label: '重评/待确认', prop: 'reMarkUnConfirmCount', width: usePX(106) },
  { align: 'center', label: '抽查量', prop: 'checkCount', width: usePX(52) },
  { align: 'center', label: '抽查改正量', prop: 'checkCorrectCount', width: usePX(76) },
  { align: 'center', label: '相关系数', prop: 'xyRelate', width: usePX(64) },
  { align: 'center', label: '平均分', prop: 'avg', width: usePX(52) },
  { align: 'center', label: '标准差', prop: 'std', width: usePX(52) },
  { align: 'center', label: '近5分钟最高分', prop: 'scoreTop', width: usePX(96) },
  { align: 'center', label: '近5分钟最低分', prop: 'scoreLow', width: usePX(96) },
  { align: 'center', label: '近5分钟客主比', prop: 'objSubRate', width: usePX(96) },
  { align: 'center', label: '平均客主比', prop: 'objSubAvgRate', width: usePX(76) },
  {
    align: 'center',
    label: '在线',
    prop: 'online',
    width: usePX(40),
    formatter(row) {
      return row.online ? '在线' : '离线'
    },
  },
  { align: 'center', label: '状态', prop: 'markingStatus', width: usePX(40) },
  { align: 'center', label: '速度', prop: 'markingRate', width: usePX(40) },
  { align: 'center', label: '综合系数', prop: 'integration', width: usePX(64) },
]

const popovers = ref<Record<string, PopoverInstance>>({})

const setWorkloadVisible = ref<boolean>(false)

const setWorkloadData = ref<ExtractArrayValue<ExtractApiResponse<'getStatisticsByGroup'>>>()

function setPopoverRefs(id: number, popover: PopoverInstance) {
  popovers.value[`popovers-${id}`] = popover
}

/** on popover show */
function onPopoverShow(id: number) {
  Object.keys(popovers.value).forEach((k) => {
    if (k !== `popovers-${id}`) {
      popovers.value[k]?.hide()
    }
  })
}

/** 设置工作量 */
function onSetWorkload(data: ExtractArrayValue<ExtractApiResponse<'getStatisticsByGroup'>>) {
  popovers.value[`popovers-${data.markerId}`]?.hide()
  setWorkloadData.value = data
  setWorkloadVisible.value = true
}
/** 发送消息 */
function onSendMessage(data: ExtractArrayValue<ExtractApiResponse<'getStatisticsByGroup'>>) {
  popovers.value[`popovers-${data.markerId}`]?.hide()
  setReplyUserId?.(data.markerId)
  setMessageVisible?.(true)
}

const data = computed(() => {
  return props.data || []
})

const { tableRef, tableData, current, onCurrentChange } = useTableCheck(data)

watch(tableData, () => {
  popovers.value = {}
})

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

watch(
  [() => props.params, current],
  () => {
    const { startTime = '', endTime = '' } = props.params || {}
    if (current.value?.markerId) {
      getStatisticObjectiveByMarker({
        markerId: current.value.markerId,
        startTime,
        endTime,
      })
      getStatisticSubjectiveByMarker({
        markerId: current.value.markerId,
        startTime,
        endTime,
      })
    }
  },
  { immediate: true, deep: true }
)

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: {
      right: 0,
      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: '#3AD500',
        },
        data: getXAxisData('rate', subjectiveByMarker?.value?.segmentsByUser),
      },
      {
        name: '小组主观分布',
        type: 'line',
        itemStyle: {
          color: '#0064FF',
        },
        data: getXAxisData('rate', subjectiveByMarker?.value?.segmentsByGroup),
      },
      {
        name: '题组主观分布',
        type: 'line',
        itemStyle: {
          color: '#008000',
        },
        data: getXAxisData('rate', subjectiveByMarker?.value?.segmentsByAll),
      },
    ],
  }
})

const markerObjectiveChartsOption = computed<EChartsOption>(() => {
  return {
    legend: {
      right: 0,
      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: '#3AD500',
        },
        data: getXAxisData('rate', objectiveByMarker?.value?.segmentsByUser),
      },
      {
        name: '小组客观分布',
        type: 'line',
        itemStyle: {
          color: '#0064FF',
        },
        data: getXAxisData('rate', objectiveByMarker?.value?.segmentsByGroup),
      },
      {
        name: '题组客观分布',
        type: 'line',
        itemStyle: {
          color: '#008000',
        },
        data: getXAxisData('rate', objectiveByMarker?.value?.segmentsByAll),
      },
    ],
  }
})
</script>

<style scoped lang="scss">
.chart-box {
  height: 293px;
}
</style>
