<template>
  <div class="p-small radius-base fill-blank statistics-personnel">
    <base-table
      ref="tableRef"
      border
      stripe
      size="small"
      :data="sortTableData"
      :columns="columns"
      :height="tableHeight"
      :row-class-name="rowClassName"
      highlight-current-row
      @current-change="onCurrentChange"
      @row-dblclick="myDbClick"
      @row-contextmenu="rowContextmenu"
      @sort-change="sortChange"
    >
      <template #column-marker="{ row }">
        <!-- <el-popover
          v-if="row.markerId"
          :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> -->
        <span v-if="row.markerId">{{ row.markerName }}</span>
        <span v-else-if="row.markingGroupNumber == 0">全体</span>
        <span v-else>全组</span>
      </template>
    </base-table>
  </div>
  <!-- <div
    v-if="!!current && !!current?.markerId"
    v-loading="loading1 || loading2"
    class="flex justify-between m-t-base charts-box"
  >
    <el-button type="primary" plain size="small" class="close-panel" @click="clearCheck">关闭</el-button>

    <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" />
  <right-key-menu
    v-show="visable"
    ref="rightKeyMenu"
    @right-click="rightClick"
    @on-set-workload="onSetWorkload"
    @on-send-message="onSendMessage"
    @force-assessment="forceAssessment"
  ></right-key-menu>
</template>

<script setup lang="tsx" name="StatisticsPersonnel">
/** 人员数据统计-按人员展开 */
import { ref, inject, computed, watch, nextTick, unref } from 'vue'
import { useRouter } from 'vue-router'
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 RightKeyMenu from './RightKeyMenu.vue'
import useMainStore from '@/store/main'
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 mainStore = useMainStore()
const isChief = computed(() => {
  const arr = ['CHIEF', 'SECTION_LEADER', 'EXPERT']
  return arr.indexOf(mainStore.myUserInfo?.role || '') > -1
})
const rightKeyMenu = ref(null)
const rightClick = () => {
  visable.value = false
}
const props = defineProps<{
  data: ExtractApiResponse<'getStatisticsByGroup'>
  params: ExtractApiParams<'getStatisticsByGroup'> & { expand: boolean }
  filterColumns?: any
  result?: any
}>()
const rowClassName = (obj: any) => {
  if (obj.row.markingGroupNumber === 0) {
    return 'fixed-row'
  } else if (obj.row.isGroupTotalRow) {
    return 'fixed-row2'
  }
}
const setMessageVisible = inject<(visible: boolean) => void>('setMessageVisible')
const setReplyUserId = inject<(id: number) => void>('setReplyUserId')

const { push } = useRouter()

const columns = computed(() => {
  return [
    {
      label: '#',
      type: 'index',
      width: 50,
      align: 'center',
      fixed: 'left',
      index(index: number) {
        return index + 1
      },
    },
    {
      label: '小组',
      prop: 'markingGroupNumber',
      width: 60,
      fixed: 'left',
      formatter(row: any) {
        return row.markingGroupNumber === 0 ? '全部' : `第${row.markingGroupNumber}组`
      },
    },
    { label: '评卷员', prop: 'markerName', minWidth: 84, slotName: 'marker', fixed: 'left' },

    { align: 'center', label: '评卷份数', prop: 'markingPaperCount', minWidth: 96 },
    { align: 'center', label: '平均分', prop: 'avg', minWidth: 80 },
    {
      align: 'center',
      label: '相关系数',
      prop: 'xyRelate',
      minWidth: 96,
      formatter(row: any) {
        let r = unref(props.result) || []
        const { markingGroupNumber } = row
        let compareTarget = r.find((item: any) => item.markingGroupNumber == markingGroupNumber)
        let allTarget = r.find((item: any) => item.markingGroupNumber == 0)
        if (compareTarget && markingGroupNumber) {
          return (
            props.params.markingGroupNumber ? row.xyRelate < compareTarget.xyRelate : row.xyRelate < allTarget.xyRelate
          ) ? (
            <span style="color:red">{row.xyRelate}</span>
          ) : (
            row.xyRelate
          )
        } else {
          return row.xyRelate
        }
      },
    },
    { align: 'center', label: '标准差', prop: 'std', minWidth: 80 },
    { align: 'center', label: '综合系数', prop: 'integration', minWidth: 96 },

    // { align: 'center', label: '评卷份数', prop: 'markingPaperCount', width: 92 },
    { align: 'center', label: '当日可阅', prop: 'markDayCount', minWidth: 96 },
    { align: 'center', label: '剩余可阅', prop: 'todoMarkDayCount', minWidth: 96 },
    { align: 'center', label: '客观题0分量', prop: 'objectiveZero', minWidth: 120 },
    { align: 'center', label: '客观平均分', prop: 'objectiveAvg', minWidth: 110 },
    { align: 'center', label: '客观标准差', prop: 'objectiveStd', minWidth: 110 },
    {
      align: 'center',
      label: '重评/待确认',
      prop: 'reMarkUnConfirmCount',
      minWidth: 120,
      formatter(row: any) {
        return `${row.reMarkCount}/${row.reMarkUnConfirmCount}`
      },
    },
    { align: 'center', label: '抽查量', prop: 'checkCount', minWidth: 90 },
    { align: 'center', label: '抽查改正量', prop: 'checkCorrectCount', minWidth: 110 },
    // { align: 'center', label: '相关系数', prop: 'xyRelate', width: 90 },
    // { align: 'center', label: '平均分', prop: 'avg', width: 80 },
    // { align: 'center', label: '标准差', prop: 'std', width: 80 },
    { align: 'center', label: '近5分钟最高分', prop: 'scoreTop', minWidth: 130 },
    { align: 'center', label: '近5分钟最低分', prop: 'scoreLow', minWidth: 130 },
    { align: 'center', label: '近5分钟客主比', prop: 'objSubRate', minWidth: 130 },
    { align: 'center', label: '平均客主比', prop: 'objSubAvgRate', minWidth: 110 },
    {
      align: 'center',
      label: '在线',
      prop: 'online',
      minWidth: 72,
      formatter(row: any) {
        if (row.markingGroupNumber === 0) {
          let total = (unref(props.result) || [])
            .filter((item: any) => item.markingGroupNumber !== 0)
            .reduce((ar: any, item: any) => {
              return [...ar, ...(item.markerDetails || [])]
            }, [])
            .reduce((num: number, item: any) => {
              return num + (item.online ? 1 : 0)
            }, 0)
          return total + '人'
        } else if (row.isGroupTotalRow) {
          let total = (unref(props.result) || [])
            .filter((item: any) => item.markingGroupNumber == row.markingGroupNumber)
            .reduce((ar: any, item: any) => {
              return [...ar, ...(item.markerDetails || [])]
            }, [])
            .reduce((num: number, item: any) => {
              return num + (item.online ? 1 : 0)
            }, 0)
          return total + '人'
        } else {
          return row.online ? '在线' : '离线'
        }
      },
    },
    { align: 'center', label: '状态', prop: 'markingStatus', minWidth: 100 },
    { align: 'center', label: '速度', prop: 'markingRate', minWidth: 72 },
    // { align: 'center', label: '综合系数', prop: 'integration', width: 90 },
  ]
    .map((col: any) => {
      if (!['小组', '重评/待确认'].includes(col.label)) col.sortable = 'custom'
      return col
    })
    .filter((col: any) => {
      return props.filterColumns ? props.filterColumns.indexOf(col.prop) > -1 || col.type === 'index' : col
    })
})
const visable = ref(false)
const rowContextmenu = (row: any, column: any, event: any) => {
  console.log(row, column, event)
  visable.value = false
  setTimeout(() => {
    visable.value = true
  }, 50)
  event.preventDefault()
  nextTick(() => {
    // alert(1)
    ;(rightKeyMenu.value as any).onload(row, column, event)
  })
}
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)
}
function forceAssessment(data: ExtractArrayValue<ExtractApiResponse<'getStatisticsByGroup'>>) {
  push({
    name: 'MarkingAssess',
    query: { markerId: data.markerId },
  })
}
const data = computed(() => {
  return JSON.parse(JSON.stringify(props.data || [])) || []
})

const { tableRef, tableData, current, onCurrentChange, onDbClick, currentView, elTableRef } = useTableCheck(data, false)
const myDbClick = (row: any) => {
  onDbClick(row)
  if (currentView.value && !!currentView.value.markingGroupNumber && !!currentView.value.markerId) {
    push({
      name: 'AnalysisPersonnelStatisticsMarker',
      query: {
        markerId: currentView.value.markerId,
        markerName: currentView.value.markerName,
        source: '人员数据统计',
        subjectCode: props.params?.subjectCode,
        questionMainNumber: props.params?.questionMainNumber,
      },
    })
  }
}
const sortTableData = ref<any[]>([])
const originalTableData = ref<any[]>([])
const sortChange = (params: any) => {
  const { column, prop, order } = params
  if (order === 'ascending') {
    sortTableData.value.sort((a: any, b: any) => {
      if (a.markingGroupNumber == 0) {
        return -1
      } else if (b.markingGroupNumber == 0) {
        return 1
      } else {
        if (typeof a[prop] === 'string') {
          let aa = a[prop] || '',
            bb = b[prop] || ''
          return aa.localeCompare(bb)
        } else {
          return a[prop] - b[prop]
        }
      }
    })
  } else if (order === 'descending') {
    sortTableData.value.sort((a: any, b: any) => {
      if (a.markingGroupNumber == 0) {
        return -1
      } else if (b.markingGroupNumber == 0) {
        return 1
      } else {
        if (typeof a[prop] === 'string') {
          let aa = a[prop] || '',
            bb = b[prop] || ''
          return bb.localeCompare(aa)
        } else {
          return b[prop] - a[prop]
        }
      }
    })
  } else if (order == null) {
    sortTableData.value = JSON.parse(JSON.stringify(originalTableData.value))
  }
}
function initSortTableData() {
  if (tableData.value) {
    let data: any[] = JSON.parse(JSON.stringify(tableData.value)) || []
    if (data.length && data[data.length - 1].markingGroupNumber === 0) {
      let last = data.splice(data.length - 1, 1)[0]
      data.unshift(last)
    }
    sortTableData.value = JSON.parse(JSON.stringify(data))
    originalTableData.value = JSON.parse(JSON.stringify(data))
  }
}
initSortTableData()
watch(tableData, () => {
  popovers.value = {}
  initSortTableData()
})

// watch(currentView, () => {
//   if (currentView.value && !!currentView.value.markingGroupNumber) {
//     push({
//       name: 'AnalysisPersonnelStatisticsMarker',
//       query: { markerId: currentView.value.markerId, markerName: currentView.value.markerName },
//     })
//   }
// })

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

watch(
  [() => props.params, current],
  () => {
    const { startTime = '', endTime = '' } = props.params || {}
    // if (current.value?.markerId) {
    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),
      },
    ],
  }
})
const tableHeight = computed(() => {
  // return !!current.value && !!current.value?.markerId ? 'calc(100vh - 520px)' : 'calc(100vh - 219px)'
  return 'calc(100vh - 250px)'
})
const clearCheck = () => {
  ;(elTableRef as any).value!.setCurrentRow(undefined)
}
</script>

<style scoped lang="scss">
.statistics-personnel {
  :deep(.el-table) {
    .fixed-row {
      display: table-row;
      position: sticky;
      position: '-webkit-sticky';
      top: 0;
      width: 100%;
      z-index: 3;
      font-weight: bold;
      color: #333;
    }
    .fixed-row2 {
      display: table-row;
      position: sticky;
      position: '-webkit-sticky';
      top: 44px;
      width: 100%;
      z-index: 3;
      font-weight: bold;
      color: #333;
    }
  }
}
.chart-box {
  height: 293px;
}
.charts-box {
  position: relative;
  .close-panel {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateX(-50%) translateY(-50%);
    z-index: 1;
  }
}
</style>
