<script lang="ts" setup>
import * as echarts from 'echarts'
import { IotStatApi } from '@/api/pms/stat'
import { rangeShortcuts } from '@/utils/formatTime'
import { ANIMATION, CHART_RENDERER, ChartItem, createTooltip, FONT_FAMILY, THEME } from '@/utils/kb'
import dayjs from 'dayjs'

interface CompleteRateRow {
  department?: string
  rate?: number | string | null
  [key: string]: unknown
}

const DEFAULT_TIME_RANGE = rangeShortcuts[2]
  .value()
  .map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))

const createTime = ref<string[]>(DEFAULT_TIME_RANGE)
const chartData = ref<ChartItem[]>([])
const loading = ref(false)

const chartRef = ref<HTMLDivElement>()
let chart: echarts.ECharts | null = null

function toNumber(value: unknown) {
  const num = Number(value)
  return Number.isFinite(num) ? num : 0
}

function toPercentValue(value: unknown) {
  const num = toNumber(value)
  const percent = num <= 1 ? num * 100 : num
  return Number(percent.toFixed(2))
}

function formatPercent(value: unknown) {
  return `${toPercentValue(value).toFixed(2)}%`
}

function getRateValue(item: CompleteRateRow) {
  const departmentRate = item.department ? item[item.department] : undefined
  return toPercentValue(item.rate ?? departmentRate)
}

function getChartOption(data: ChartItem[]): echarts.EChartsOption {
  const names = data.map((item) => item.name)
  const values = data.map((item) => item.value)

  return {
    ...ANIMATION,
    grid: { ...THEME.grid, top: 30 },
    tooltip: createTooltip({
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
        shadowStyle: {
          color: THEME.split
        }
      }
    }),
    xAxis: {
      type: 'category',
      data: names,
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: THEME.text.regular,
        fontSize: 14,
        fontFamily: FONT_FAMILY
      }
    },
    yAxis: {
      type: 'value',
      min: 0,
      max: 100,
      interval: 20,
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: THEME.text.regular,
        fontSize: 12,
        fontFamily: FONT_FAMILY,
        formatter(value: number) {
          return `${value}%`
        }
      },
      splitLine: {
        lineStyle: {
          color: THEME.split,
          type: 'dashed'
        }
      }
    },
    series: [
      {
        name: '日报完成率',
        type: 'bar',
        data: values,
        barWidth: 44,
        showBackground: true,
        backgroundStyle: {
          color: THEME.split,
          borderRadius: 999
        },
        itemStyle: {
          borderRadius: [12, 12, 0, 0],
          shadowBlur: 12,
          shadowColor: THEME.color.blue.bg,
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: THEME.color.blue.light },
            { offset: 0.5, color: THEME.color.blue.mid },
            { offset: 1, color: THEME.color.blue.line }
          ])
        },
        label: {
          show: true,
          position: 'top',
          distance: 10,
          color: THEME.color.blue.strong,
          fontSize: 16,
          fontWeight: 700,
          fontFamily: FONT_FAMILY,
          formatter(params: any) {
            return formatPercent(params.value)
          }
        },
        emphasis: {
          itemStyle: {
            shadowBlur: 18,
            shadowColor: THEME.color.blue.shadow
          }
        }
      }
    ]
  }
}

function initChart() {
  if (!chartRef.value) return
  if (chart) {
    chart.dispose()
  }
  chart = echarts.init(chartRef.value, undefined, {
    renderer: CHART_RENDERER
  })
  renderChart()
}

function renderChart() {
  if (!chart) return

  chart.setOption(getChartOption(chartData.value || []), true)
}

function resizeChart() {
  chart?.resize()
}

function destroyChart() {
  if (chart) {
    chart.dispose()
    chart = null
  }
}

function handleDateChange() {
  loadChart()
}

async function loadChart() {
  loading.value = true

  try {
    const res = await IotStatApi.getCompleteRate({ createTime: createTime.value })
    const list = Array.isArray(res) ? (res as CompleteRateRow[]) : []

    chartData.value = list
      .map((item) => ({
        name: String(item.department ?? '').trim(),
        value: getRateValue(item)
      }))
      .filter((item) => item.name)

    renderChart()
  } catch (error) {
    console.error('获取日报完成率失败:', error)
    chartData.value = []
    renderChart()
  } finally {
    loading.value = false
  }
}

onMounted(() => {
  initChart()
  loadChart()
  window.addEventListener('resize', resizeChart)
  window.addEventListener('homekb:resize', resizeChart)
})

onUnmounted(() => {
  window.removeEventListener('resize', resizeChart)
  window.removeEventListener('homekb:resize', resizeChart)
  destroyChart()
})
</script>

<template>
  <div class="panel flex flex-col">
    <div class="panel-title panel-title--lg flex items-center justify-between">
      <div class="kb-panel-title-text flex items-center">
        <div class="icon-decorator">
          <span></span>
          <span></span>
        </div>
        日报完成率
      </div>
      <div class="kb-inline-picker kb-inline-picker--260">
        <el-date-picker
          v-model="createTime"
          value-format="YYYY-MM-DD HH:mm:ss"
          type="daterange"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
          :shortcuts="rangeShortcuts"
          :clearable="false"
          class="kb-inline-picker__input"
          @change="handleDateChange" />
      </div>
    </div>
    <div ref="chartRef" class="flex-1 min-h-0"></div>
  </div>
</template>

<style lang="scss" scoped>
@import url('@/styles/kb.scss');
</style>
