<template>
  <div class="p-base p-b-unset m-b-base radius-base fill-blank total-progress-box">
    <base-form size="small" :model="model" :items="items"></base-form>
    <div class="flex total-progress-info">
      <div class="flex direction-column full-h p-r-base table-info">
        <div class="p-t-base p-b-extra-small table-title">整体进度</div>
        <div class="flex-1 overflow-hidden">
          <base-table
            size="small"
            height="100%"
            highlight-current-row
            :columns="totalColumns"
            :data="totalProgressData"
            @current-change="onCurrentChange"
          >
            <template #empty>暂无数据</template>
          </base-table>
        </div>
      </div>
      <div class="flex-1 p-t-small p-b-extra-small overflow-hidden full-h chart-info">
        <vue-e-charts class="full" :option="totalChartsOption" autoresize></vue-e-charts>
      </div>
    </div>
  </div>
  <div class="p-base radius-base fill-blank flex group-progress-box">
    <div class="flex direction-column full-h p-r-base table-info">
      <div class="flex justify-between">
        <span class="table-title">小组进度</span>
        <span v-show="currentMainName" class="flex items-center current-main-name">
          <svg-icon class="m-r-medium-mini" name="question"></svg-icon>
          <span>{{ currentMainName }}</span>
        </span>
      </div>
      <div class="flex-1 overflow-hidden">
        <base-table size="small" height="100%" :columns="groupColumns" :data="groupProgressData">
          <template #empty>暂无数据</template>
        </base-table>
      </div>
    </div>
    <div class="flex-1 full-h chart-info">
      <vue-e-charts v-if="currentMainName" class="full" :option="groupChartsOption" autoresize></vue-e-charts>
    </div>
  </div>
</template>

<script setup lang="ts" name="TotalProgress">
/** 评卷进度 */
import { reactive, watch, computed, ref } from 'vue'
import VueECharts from 'vue-echarts'
import { minus } from '@/utils/common'
import BaseForm from '@/components/element/BaseForm.vue'
import BaseTable from '@/components/element/BaseTable.vue'
import SvgIcon from '@/components/common/SvgIcon.vue'
import useFetch from '@/hooks/useFetch'
import useOptions from '@/hooks/useOptions'
import useVueECharts from '@/hooks/useVueECharts'
import { usePX } from '@/hooks/useVW'

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

const { provideInitOption } = useVueECharts()

provideInitOption({ renderer: 'svg' })

const { subjectList, dataModel, changeModelValue } = useOptions(['subject'])

const model = reactive({
  subjectCode: dataModel.subject || '',
})

watch(
  dataModel,
  () => {
    model.subjectCode = dataModel.subject || ''
  },
  { deep: true, immediate: true }
)

const items = computed<EpFormItem[]>(() => [
  {
    label: '科目',
    slotType: 'select',
    prop: 'subjectCode',
    slot: { options: subjectList.value, onChange: changeModelValue('subject'), disabled: true },
    colProp: { span: 5 },
  },
])

/** 整体进度 */

type TotalProgress = ExtractArrayValue<ExtractApiResponse<'getMarkProgress'>>

const getMainName = (row?: TotalProgress) => {
  const { questionMainName: name, questionMainNumber: number } = row || {}
  return [number, name].filter(Boolean).join('-')
}

const totalColumns: EpTableColumn<TotalProgress>[] = [
  {
    label: '大题',
    formatter: getMainName,
  },
  { label: '试卷总量', prop: 'totalPaper', align: 'center', width: usePX(100) },
  { label: '已完成', prop: 'finishCount', align: 'center', width: usePX(100) },
  {
    label: '完成比',
    align: 'center',
    width: usePX(72),
    formatter(row) {
      return `${row.finishRate}%`
    },
  },
  {
    label: '待完成',
    align: 'center',
    width: usePX(100),
    formatter(row) {
      return `${minus(row.totalPaper, row.finishCount)}`
    },
  },
  {
    label: '待完成比',
    align: 'center',
    width: usePX(72),
    formatter(row) {
      return `${minus(100, row.finishRate)}%`
    },
  },
  {
    label: '预计耗时(分)',
    align: 'center',
    width: usePX(100),
    formatter(row) {
      return `${parseFloat((row.takeTime / 60).toFixed(2))}`
    },
  },
]

const { fetch: getMarkProgress, result: markProgressResult } = useFetch('getMarkProgress')

/** 将汇总行放到数组最后 */
const totalProgressData = computed(() => {
  if (!markProgressResult?.value) return []
  const arr = markProgressResult.value.slice(0)
  const totalIndex = arr.findIndex((v) => v.questionMainNumber === 0)
  const [total] = arr.splice(totalIndex, 1)
  arr.push(total)
  return arr
})

watch(
  () => model.subjectCode,
  (v) => {
    v && getMarkProgress(model)
  },
  { immediate: true }
)

const currentMainQuestion = ref<TotalProgress>()

const currentMainName = computed(() => {
  return getMainName(currentMainQuestion.value)
})

const onCurrentChange = (row: TotalProgress) => {
  if (row.questionMainNumber !== 0) {
    currentMainQuestion.value = row
  }
}

const getYAxisData = (field: keyof TotalProgress | 'name', data?: TotalProgress[]) => {
  if (!data) {
    return []
  }
  return data.map((v) => {
    if (field === 'name') {
      return getMainName(v)
    }
    return v[field]
  })
}

const totalChartsOption = computed<EChartsOption>(() => {
  return {
    grid: {
      top: 20,
      bottom: -20,
      left: 20,
      right: 30,
      containLabel: true,
    },
    legend: {
      right: 0,
      itemWidth: 14,
      data: ['试卷总量', '已完成', '完成比'],
    },
    yAxis: {
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: { show: false },
      inverse: true,
      axisLabel: {
        align: 'right',
        verticalAlign: 'bottom',
      },
      data: getYAxisData('name', markProgressResult?.value),
    },
    xAxis: [
      {
        position: 'top',
        type: 'value',
        splitLine: { show: true },
      },
      {
        position: 'bottom',
        type: 'value',
        show: false,
        axisLabel: {
          formatter: `{value}%`,
        },
        splitLine: { show: false },
      },
    ],
    series: [
      {
        name: '试卷总量',
        type: 'bar',
        barWidth: 11,
        barGap: '-200%',
        itemStyle: {
          color: '#3AD500',
        },
        data: getYAxisData('totalPaper', markProgressResult?.value),
      },
      {
        name: '已完成',
        type: 'bar',
        barWidth: 11,
        barGap: '-200%',
        itemStyle: {
          color: '#0064FF',
        },
        data: getYAxisData('finishCount', markProgressResult?.value),
      },
      {
        name: '完成比',
        type: 'bar',
        barWidth: 44,
        barGap: '-200%',
        showBackground: true,
        xAxisIndex: 1,
        itemStyle: {
          color: 'rgba(0, 186, 151,0.3)',
        },
        label: {
          show: true,
          color: '#444',
          fontSize: 10,
          formatter({ value }) {
            return value > 0 ? `${value}%` : ''
          },
          position: 'insideTopRight',
        },
        data: getYAxisData('finishRate', markProgressResult?.value),
      },
    ],
  }
})
/** 小组进度 */

type GroupProgress = ExtractArrayValue<ExtractApiResponse<'getMarkProgressByGroup'>>

const groupColumns: EpTableColumn<GroupProgress>[] = [
  { label: '小组', formatter: (row) => (row.markingGroupNumber ? `第${row.markingGroupNumber}组` : '全体') },
  { label: '完成总量', prop: 'finishCount', align: 'center' },
  {
    label: '完成比',
    prop: 'finishRate',
    align: 'center',
    formatter(row) {
      return `${row.finishRate}%`
    },
  },
  { label: '当日已完成', prop: 'dayFinishCount', align: 'center' },
  {
    label: '当日完成比',
    prop: 'dayFinishRate',
    align: 'center',
    formatter(row) {
      return `${row.dayFinishRate}%`
    },
  },
]

const { fetch: getMarkProgressByGroup, result: groupProgressResult } = useFetch('getMarkProgressByGroup')

/** 将汇总行放到数组最后 */
const groupProgressData = computed(() => {
  if (!groupProgressResult?.value) return []
  const arr = groupProgressResult.value.slice(0)
  const totalIndex = arr.findIndex((v) => v.markingGroupNumber === 0)
  const [total] = arr.splice(totalIndex, 1)
  arr.push(total)
  return arr
})

watch(
  currentMainQuestion,
  (v) => {
    v?.questionMainNumber &&
      getMarkProgressByGroup({ subjectCode: model.subjectCode, questionMainNumber: v.questionMainNumber })
  },
  { immediate: true }
)

const getXAxisData = (field: keyof GroupProgress, data?: GroupProgress[]) => {
  if (!data) {
    return []
  }
  const getValue = (data: GroupProgress, v: keyof GroupProgress) => {
    if (v === 'markingGroupNumber') {
      return `第${data[v]}组`
    }
    return data[v]
  }
  return data.filter((v) => v.markingGroupNumber !== 0).map((v) => getValue(v, field))
}

const groupChartsOption = computed<EChartsOption>(() => {
  return {
    legend: {
      right: 0,
      itemWidth: 14,
      data: ['完成总量', '当日已完成', '完成比'],
    },
    xAxis: {
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: { show: false },
      axisLabel: {
        align: 'right',
      },
      data: getXAxisData('markingGroupNumber', groupProgressResult?.value),
    },
    yAxis: [
      {
        type: 'value',
      },
      {
        type: 'value',
        axisLabel: {
          formatter: `{value}%`,
        },
        splitLine: { show: false },
      },
    ],
    series: [
      {
        name: '完成总量',
        type: 'bar',
        barWidth: 20,
        itemStyle: {
          color: '#3AD500',
        },
        data: getXAxisData('finishCount', groupProgressResult?.value),
      },
      {
        name: '当日已完成',
        type: 'bar',
        barWidth: 20,
        itemStyle: {
          color: '#0064FF',
        },
        data: getXAxisData('dayFinishCount', groupProgressResult?.value),
      },
      {
        name: '完成比',
        type: 'bar',
        barWidth: 80,
        showBackground: true,
        barGap: '-200%',
        yAxisIndex: 1,
        itemStyle: {
          color: 'rgba(0, 186, 151,0.3)',
        },
        data: getXAxisData('finishRate', groupProgressResult?.value),
      },
    ],
  }
})
</script>

<style scoped lang="scss">
.total-progress-box {
  height: 323px;
  .total-progress-info {
    border-top: $OnePixelLine;
    height: 253px;
  }
}
.table-info {
  width: 720px;
  border-right: $OnePixelLine;
  .table-title {
    font-size: $MediumFont;
  }
}

.group-progress-box {
  height: 395px;
  .current-main-name {
    background-color: $BaseBgColor;
    font-size: $SmallFont;
    color: $PrimaryPlusFontColor;
    border-radius: 4px;
    &:not(:empty) {
      padding: 2px 4px;
    }
  }
}
</style>
