<script setup lang="ts">
import * as echarts from 'echarts/core'
import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components'
import { LineChart } from 'echarts/charts'
import { CanvasRenderer } from 'echarts/renderers'
import { UniversalTransition } from 'echarts/features'
import SelectTime from './SelectTime.vue'
import NumberCard from './NumberCard.vue'
import dayjs from '@/plugins/dayjs'
import { timeTool } from '../hooks'
import { $font_color } from '@/styles/variate'
import studyAnalysisApi from '@/api/studyAnalysis'

const props = withDefaults(
  defineProps<{
    subjectId: number
    userId: any
    isEnglish?: boolean
    windowWidth: number
  }>(),
  {
    isEnglish: false,
    subjectId: 0,
    userId: '',
    windowWidth: 1920,
  },
)

const emits = defineEmits(['change'])
echarts.use([
  LegendComponent,
  GridComponent,
  LineChart,
  CanvasRenderer,
  UniversalTransition,
  TooltipComponent,
])
let myChart: any

const chartDom = ref()
const showData = ref({
  allGraspGraph: {}, // 单词总掌握折线图
  allKnowGraph: {}, // 	单词总认识折线图
  allKnowWellGraph: {}, // 单词总熟悉折线图
  allStrangeGraph: {}, // 单词总陌生折线图

  allLearnTime: '', // 总学习时长
  allLearnWordCount: '', // 学习单词总数
  correctRate: '', // 总正确率
  graspCount: '', // 掌握单词总数
  knowCount: '', // 认识单词总数
  knowWellCount: '', // 熟悉单词总数
  strangeCount: '', // 陌生单词总数
})

const dateType = ref(0)

const timeList = ref([
  { label: '今日', value: 0 },
  { label: '近一周', value: 1 },
  { label: '总计', value: 3 },
])

const renderConfig = ref([
  {
    name: '陌生',
    config: 'todayStrangeCountCmp',
    fill: '#FF8200',
    color: ' #C67016',
    value: 0,
  },
  {
    name: '认识',
    fill: '#FED769',
    color: '#A13C00',
    config: 'todayKnowCountCmp',
    value: 0,
  },
  {
    name: '熟悉',
    fill: '#8A94FD',
    color: '#2D39BC',
    config: 'todayKnownWellCountCmp',
    value: 0,
  },
  {
    name: '掌握',
    fill: '#8FCC00',
    color: '#2F8A5B ',
    config: 'todayGraspCountCmp',
    value: 0,
  },
  {
    name: '总计',
    fill: '#FF6350D9',
    color: '#BC2D37',
    config: 'todayAllCountCmp',
    value: 0,
  },
  {
    name: '新词数',
    fill: '#FED769',
    color: '#A13C00',
    config: 'newWordCount',
    value: 0,
  },
  {
    name: '复习数',
    fill: '#8A94FD',
    color: '#2D39BC',
    config: 'reviewCount',
    value: 0,
  },
])
const startTime = ref('')
const showLoading = ref(false)
function getSizeTransform(size: number): number {
  return Math.floor((props.windowWidth * size) / 1920)
}
function initChart() {
  myChart = echarts.init(chartDom.value)
  const seriesStyle = {
    type: 'line',
    symbol: 'circle',
    symbolSize: getSizeTransform(12),
    smooth: true,
    selectedMode: 'single',
    tooltip: {
      trigger: 'item',
      formatter: (params: anyObj, ticket: string) => {
        return `<div class="tooltip">
                            <div style="font-size: 1.562vw; line-height: 2.343vw; color: #999">
                                ${dayjs(
                                  Object.keys(showData.value.allGraspGraph)[params.dataIndex],
                                ).format('YYYY.M.D')}
                            </div>
                            <div style="font-size: 1.666vw; line-height: 2.5vw; color: #666">
                               ${params.seriesName}：${params.data}
                            </div>
                        </div>
                        `
      },
    },
    blur: {
      lineStyle: {
        opacity: 1,
      },
      itemStyle: {
        opacity: 1,
      },
    },
    emphasis: {
      scale: 2,
      focus: 'series',
      itemStyle: {
        borderWidth: getSizeTransform(4),
        borderColor: 'white',
        color: '#8FCC00',
        borderType: 'solid',
      },
    },
  }
  const option = {
    tooltip: {
      show: true,
      trigger: 'axis',
      axisPointer: {
        z: 0,
        type: 'line',
        lineStyle: {
          color: '#8FCC00',
          width: getSizeTransform(4),
          type: 'solid',
        },
      },
    },
    legend: {
      selectedMode: false,
      textStyle: {
        fontSize: getSizeTransform(30),
        color: '#666',
        fontFamily: 'Alibaba Health',
      },
      itemGap: getSizeTransform(32),
      itemHeight: getSizeTransform(16),
      itemWidth: getSizeTransform(38),
      itemStyle: {
        borderWidth: getSizeTransform(4),
      },
      lineStyle: {
        width: getSizeTransform(4),
      },
    },
    xAxis: {
      type: 'category',
      data: Object.keys(showData.value.allGraspGraph).map(item => dayjs(item).format('MM/DD')),
      boundaryGap: false,
      axisLine: {
        show: true,
        lineStyle: {
          color: '#8A94FD',
          width: getSizeTransform(4),
        },
      },
      axisTick: {
        show: false,
      },
      axisLabel: {
        margin: getSizeTransform(20),
        color: '#666666',
        fontWeight: '400',
        fontSize: getSizeTransform(30),
        fontFamily: 'Alibaba Health',
      },
      splitLine: {
        show: true,

        lineStyle: {
          color: '#8A94FD',
          opacity: 0.5,
          width: getSizeTransform(3),
        },
      },
    },
    yAxis: {
      nameGap: getSizeTransform(30),
      nameTextStyle: {
        color: '#666666',
        fontWeight: '400',
        fontSize: getSizeTransform(30),
        fontFamily: 'Alibaba Health',
      },
      type: 'value',
      scale: false,
      position: 'left',
      show: true,
      axisLine: {
        show: true,
        lineStyle: {
          color: '#8A94FD50',
          width: getSizeTransform(4),
        },
      },
      axisLabel: {
        margin: getSizeTransform(45),
        align: 'center',
        verticalAlign: 'middle',
        color: '#666666',
        fontWeight: '400',
        fontSize: getSizeTransform(30),
        fontFamily: 'Alibaba Health',
      },
      splitLine: {
        lineStyle: {
          color: '#8A94FD',
          opacity: 0.5,
          width: getSizeTransform(3),
        },
      },
    },
    series: [
      {
        ...seriesStyle,
        lineStyle: {
          color: '#FF7A6A',
          width: getSizeTransform(4),
        },
        itemStyle: {
          normal: {
            borderWidth: getSizeTransform(4),
            borderColor: '#FF7A6A',
            color: 'white',
            borderType: 'solid',
          },
        },

        name: '陌生',
        data: Object.values(showData.value.allStrangeGraph),
      },
      {
        ...seriesStyle,
        lineStyle: {
          color: '#FED769',
          width: getSizeTransform(4),
        },
        itemStyle: {
          normal: {
            borderWidth: getSizeTransform(4),
            borderColor: '#FED769',
            color: 'white',
            borderType: 'solid',
          },
        },

        name: '认识',
        data: Object.values(showData.value.allKnowGraph),
      },
      {
        ...seriesStyle,
        lineStyle: {
          color: '#8A94FD',
          width: getSizeTransform(4),
        },
        itemStyle: {
          normal: {
            borderWidth: getSizeTransform(4),
            borderColor: '#8A94FD',
            color: 'white',
            borderType: 'solid',
          },
        },

        name: '熟悉',
        data: Object.values(showData.value.allKnowWellGraph),
      },
      {
        ...seriesStyle,
        lineStyle: {
          color: '#8FCC00',
          width: getSizeTransform(4),
        },
        itemStyle: {
          normal: {
            borderWidth: getSizeTransform(4),
            borderColor: '#8FCC00',
            color: 'white',
            borderType: 'solid',
          },
        },

        name: '掌握',
        data: Object.values(showData.value.allGraspGraph),
      },
    ],
  }
  option && myChart.setOption(option)
}
function initChartPie() {
  myChart = echarts.init(chartDom.value)
  const option = {
    graphic: {
      type: 'text',
      left: 'center',
      top: 'center',
      style: {
        text: '总计\n' + showData.value.allLearnWordCount,
        textAlign: 'center',
        fill: '#333',
        color: $font_color,
        fontWeight: 700,
        fontSize: getSizeTransform(32),
        lineHeight: getSizeTransform(42),
        fontFamily: 'OPPOSans',
      },
    },
    tooltip: {
      trigger: 'item',
    },
    legend: {
      icon: 'circle',
      bottom: '0%',
      left: 'center',
      itemHeight: getSizeTransform(22),
      itemGap: getSizeTransform(40),
      itemStyle: {
        decal: {
          symbol: 'pin',
        },
      },
      textStyle: {
        fontSize: getSizeTransform(30),
        padding: [0, getSizeTransform(8)],
      },
    },
    series: [
      {
        name: '单词统计',
        type: 'pie',
        radius: ['30%', '70%'],
        data: [
          {
            value: showData.value.knowCount || 0,
            name: '认识',
            itemStyle: {
              color: '#F89100',
            },
          },
          {
            value: showData.value.knowWellCount || 0,
            name: '熟悉',
            itemStyle: {
              color: '#0CA8E5',
            },
          },
          {
            value: showData.value.strangeCount || 0,
            name: '陌生',
            itemStyle: {
              color: '#F45151',
            },
          },
          {
            value: showData.value.graspCount || 0,
            name: '掌握',
            itemStyle: {
              color: '#8AC500',
            },
          },
        ],
        label: {
          // formatter: '{name|{b}}\n{time|{c} 小时}',
          alignTo: 'labelLine',
          formatter: '{b}{c}/{d}%\n',
          fontSize: getSizeTransform(30),
          color: 'inherit',
        },
        labelLine: {
          length: getSizeTransform(20),
          length2: getSizeTransform(20),
          lineStyle: {
            width: getSizeTransform(2),
          },
        },

        labelLayout: function (params: anyObj) {
          const isLeft = params.labelRect.x < myChart.getWidth() / 2
          const points = params.labelLinePoints
          points[2][0] = isLeft ? params.labelRect.x : params.labelRect.x + params.labelRect.width
          return {
            labelLinePoints: points,
          }
        },
      },
    ],
  }

  option && myChart.setOption(option)
}
function getDuration() {
  showLoading.value = true

  studyAnalysisApi
    .getWordReportData({
      dateType: dateType.value,
      subjectId: props.subjectId,
      userId: props.userId,
    })
    .then(res => {
      if (res.data.data) {
        renderConfig.value.forEach(item => {
          item.value = res.data.data.todayStat[item.config]
        })
        startTime.value = dateType.value
          ? res.data.data.allLearnTime || 0
          : res.data.data.todayStat.todayLearnTime || 0

        for (const key in showData.value) {
          showData.value[key as keyof typeof showData.value] = res.data.data[key]
        }
        setTimeout(() => {
          if (dateType.value === 1) {
            initChart()
          } else if (dateType.value === 3) {
            initChartPie()
          }
        })
      }
    })
    .finally(() => {
      showLoading.value = false
    })
  return
}
watch(
  () => props.subjectId,
  nv => {
    getDuration()
  },
  {
    immediate: true,
  },
)
</script>
<template>
  <div class="data-content">
    <div class="data-title">单词统计</div>

    <div class="nav">
      <SelectTime v-model="dateType" :dataList="timeList" @change="getDuration"></SelectTime>
    </div>
    <div :class="{ 'data-content-bottom': true, totolData: dateType === 3 }">
      <div
        v-if="!dateType || dateType === 3"
        :class="{ 'data-content-card': true, isTotol: dateType === 3 }"
      >
        <NumberCard
          v-for="item in dateType === 3 ? [] : renderConfig"
          :key="item.name"
          :title="item.name"
          :fill="item.fill"
          :fontColor="item.color"
        >
          <div class="data-content-card-content">
            <span class="number">{{ item.value }}</span
            >词
          </div>
        </NumberCard>
        <NumberCard v-if="dateType === 3" title="正确率" fill="#B8FC90" fontColor="#2F8A5B">
          <div class="data-content-card-content">
            <span class="number">{{ Number(showData.correctRate) * 100 + '%' }}</span>
          </div>
        </NumberCard>
        <NumberCard title="有效学习时长" fill="#A1FCF8" fontColor="#2D39BC">
          <div class="data-content-card-content">
            <span class="number">{{ timeTool(startTime) }}</span
            >时<span class="number">{{ timeTool(startTime, true) }}</span
            >分
          </div>
        </NumberCard>
      </div>
      <div v-if="dateType" class="right">
        <div v-if="showLoading" class="chart loading">
          <Empty type="loading" />
        </div>
        <div v-else ref="chartDom" class="chart"></div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
//
.data-content-bottom {
  margin-top: 5.83vh;
  &.totolData {
    display: flex;
    padding-bottom: 1.67vh;

    .right {
      margin: 0 0 0 200px;
    }
  }
  .data-content-card {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    .count-card-item {
      margin-right: 24px;
      margin-bottom: 2vh;
      &:nth-child(4n) {
        margin-right: 0;
      }
    }
    &.isTotol {
      display: flex;
      flex-direction: column;

      width: max-content;
    }
  }
  .right {
    flex: 1;
    width: 76%;
    margin: 0 auto;
    .chart {
      width: 100%;
      height: 55vh;
      margin: 0 auto;
    }
  }
}
.nav {
  display: flex;
  justify-content: center;
  margin: 6vh 0 1.67vh;
}

.loading {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
