<script lang="ts" setup>
import * as echarts from 'echarts'
import {
  ANIMATION,
  CHART_RENDERER,
  createLegend,
  createTooltip,
  FONT_FAMILY,
  THEME
} from '@/utils/kb'

type ActivePanel = 'distribution' | 'trend'

type InventoryItem = {
  project: string
  mayInventoryAmount: number
  yearBeginningBacklog: number
  mayBacklogAmount: number
}

const activePanel = ref<ActivePanel>('distribution')
const distributionChartRef = ref<HTMLDivElement>()
const trendChartRef = ref<HTMLDivElement>()

let distributionChart: echarts.ECharts | null = null
let trendChart: echarts.ECharts | null = null

const panelOptions: Array<{ label: string; value: ActivePanel }> = [
  { label: '分布', value: 'distribution' },
  { label: '趋势', value: 'trend' }
]

const yuanToWan = (value: number) => Number((value / 10000).toFixed(2))

const inventoryData: InventoryItem[] = [
  {
    project: '东营库',
    mayInventoryAmount: yuanToWan(2921827.56),
    yearBeginningBacklog: yuanToWan(1644059.52),
    mayBacklogAmount: yuanToWan(1436126.52)
  },
  {
    project: '川庆',
    mayInventoryAmount: yuanToWan(491050.94),
    yearBeginningBacklog: 0,
    mayBacklogAmount: yuanToWan(308801.56)
  },
  {
    project: '南美',
    mayInventoryAmount: yuanToWan(2491993.31),
    yearBeginningBacklog: 0,
    mayBacklogAmount: 0
  },
  {
    project: '非洲',
    mayInventoryAmount: yuanToWan(2276836.24),
    yearBeginningBacklog: yuanToWan(175144.46),
    mayBacklogAmount: yuanToWan(391697.89)
  },
  {
    project: '中东',
    mayInventoryAmount: yuanToWan(127300.64),
    yearBeginningBacklog: yuanToWan(14784.43),
    mayBacklogAmount: yuanToWan(103461.07)
  },
  {
    project: '中亚',
    mayInventoryAmount: yuanToWan(188389.42),
    yearBeginningBacklog: 0,
    mayBacklogAmount: 0
  },
  {
    project: '塔河库',
    mayInventoryAmount: yuanToWan(17175342.26),
    yearBeginningBacklog: yuanToWan(9890389.23),
    mayBacklogAmount: yuanToWan(9261631.2)
  },
  {
    project: '塔里木',
    mayInventoryAmount: yuanToWan(4599437.38),
    yearBeginningBacklog: 0,
    mayBacklogAmount: yuanToWan(890890.45)
  },
  {
    project: '吐哈库',
    mayInventoryAmount: yuanToWan(2342089.06),
    yearBeginningBacklog: yuanToWan(1097925.36),
    mayBacklogAmount: yuanToWan(1190879.22)
  }
]

const activeTitle = computed(() => (activePanel.value === 'distribution' ? '存货分布' : '积压趋势'))

function formatAmount(value: number) {
  return Number(value || 0).toFixed(2)
}

function getChartLayout(chartRef: Ref<HTMLDivElement | undefined>) {
  const { clientWidth = 0, clientHeight = 0 } = chartRef.value ?? {}
  const compact = clientHeight > 0 && (clientHeight < 210 || clientWidth < 520)

  return {
    compact,
    distributionTitleTop: compact ? 6 : 18,
    distributionTitleFontSize: compact ? 12 : 14,
    distributionTitleLineHeight: compact ? 14 : 16,
    distributionPieRadius: compact ? ['36%', '54%'] : ['48%', '68%'],
    distributionPieCenterY: compact ? '62%' : '57%',
    distributionLegendBottom: compact ? 0 : 10,
    distributionLegendItemSize: compact ? 9 : 13,
    distributionLegendGap: compact ? 8 : 14,
    distributionLegendFontSize: compact ? 10 : 14,
    trendGridTop: compact ? 10 : 32,
    trendGridRight: compact ? 12 : THEME.grid.right,
    trendGridBottom: compact ? 2 : THEME.grid.bottom,
    legendTop: compact ? 0 : 4,
    legendRight: compact ? 2 : 6,
    legendItemSize: compact ? 9 : 12,
    legendGap: compact ? 10 : 16,
    legendFontSize: compact ? 11 : 14,
    axisFontSize: compact ? 10 : 12,
    yAxisLabelWidth: compact ? 72 : 96,
    yAxisLabelMargin: compact ? 8 : 12,
    barWidth: compact ? 8 : 12,
    barGap: compact ? '12%' : '5%',
    barCategoryGap: compact ? '46%' : '36%',
    labelDistance: compact ? 4 : 7,
    labelFontSize: compact ? 10 : 12
  }
}

function getDistributionOption(data: InventoryItem[]): echarts.EChartsOption {
  const layout = getChartLayout(distributionChartRef)
  const inventoryTotal = data.reduce((total, item) => total + item.mayInventoryAmount, 0)
  const backlogTotal = data.reduce((total, item) => total + item.mayBacklogAmount, 0)

  return {
    ...ANIMATION,
    color: [
      THEME.color.blue.line,
      THEME.color.orange.line,
      THEME.color.green.line,
      THEME.color.red.line,
      THEME.color.blue.mid,
      THEME.color.orange.mid,
      THEME.color.green.mid,
      THEME.color.red.mid,
      THEME.color.blue.light
    ],
    tooltip: createTooltip({
      trigger: 'item',
      formatter(params: any) {
        return `${params.seriesName}<br/>${params.marker}${params.name}：${formatAmount(
          params.value
        )}万元<br/>占比：${params.percent}%`
      }
    }),
    title: [
      {
        text: `5月底余额\n${formatAmount(inventoryTotal)} 万元`,
        left: '26.5%',
        top: layout.distributionTitleTop,
        textAlign: 'center',
        textStyle: {
          color: THEME.text.strong,
          fontSize: layout.distributionTitleFontSize,
          fontWeight: 700,
          lineHeight: layout.distributionTitleLineHeight,
          fontFamily: FONT_FAMILY
        }
      },
      {
        text: `5月底积压\n${formatAmount(backlogTotal)} 万元`,
        left: '72.5%',
        top: layout.distributionTitleTop,
        textAlign: 'center',
        textStyle: {
          color: THEME.text.strong,
          fontSize: layout.distributionTitleFontSize,
          fontWeight: 700,
          lineHeight: layout.distributionTitleLineHeight,
          fontFamily: FONT_FAMILY
        }
      }
    ],
    legend: createLegend({
      type: 'scroll',
      bottom: layout.distributionLegendBottom,
      left: 10,
      right: 10,
      itemWidth: layout.distributionLegendItemSize,
      itemHeight: layout.distributionLegendItemSize,
      itemGap: layout.distributionLegendGap,
      textStyle: {
        color: THEME.text.regular,
        fontSize: layout.distributionLegendFontSize,
        fontWeight: 600,
        fontFamily: FONT_FAMILY
      }
    }),
    series: [
      {
        name: '5月底余额',
        type: 'pie',
        radius: layout.distributionPieRadius,
        center: ['27%', layout.distributionPieCenterY],
        minAngle: 5,
        label: {
          show: false
        },
        data: data.map((item) => ({
          name: item.project,
          value: item.mayInventoryAmount
        }))
      },
      {
        name: '5月底积压',
        type: 'pie',
        radius: layout.distributionPieRadius,
        center: ['73%', layout.distributionPieCenterY],
        minAngle: 5,
        label: {
          show: false
        },
        data: data
          .filter((item) => item.mayBacklogAmount > 0)
          .map((item) => ({
            name: item.project,
            value: item.mayBacklogAmount
          }))
      }
    ]
  }
}

function getTrendOption(data: InventoryItem[]): echarts.EChartsOption {
  const layout = getChartLayout(trendChartRef)
  const maxBacklog = Math.max(
    ...data.map((item) => Math.max(item.yearBeginningBacklog, item.mayBacklogAmount)),
    1
  )
  const backlogAxisMax = Math.ceil((maxBacklog * 1.15) / 100) * 100
  const barLabel = {
    show: true,
    position: 'right' as any,
    distance: layout.labelDistance,
    color: THEME.text.strong,
    fontSize: layout.labelFontSize,
    fontWeight: 700,
    fontFamily: FONT_FAMILY,
    formatter(params: any) {
      return formatAmount(Number(params.value))
    }
  }

  return {
    ...ANIMATION,
    grid: {
      ...THEME.grid,
      top: layout.trendGridTop,
      right: layout.trendGridRight,
      bottom: layout.trendGridBottom
    },
    color: [THEME.color.blue.line, THEME.color.orange.line],
    legend: createLegend(
      {
        top: layout.legendTop,
        right: layout.legendRight,
        itemWidth: layout.legendItemSize,
        itemHeight: layout.legendItemSize,
        itemGap: layout.legendGap,
        textStyle: {
          color: THEME.text.regular,
          fontSize: layout.legendFontSize,
          fontWeight: 600,
          fontFamily: FONT_FAMILY
        }
      },
      ['年初积压', '5月底积压']
    ),
    tooltip: createTooltip({
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
        shadowStyle: {
          color: THEME.split
        }
      },
      valueFormatter(value: number) {
        return `${formatAmount(value)}万元`
      }
    }),
    xAxis: {
      type: 'value',
      max: backlogAxisMax,
      splitNumber: 4,
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: THEME.text.regular,
        fontSize: layout.axisFontSize,
        fontFamily: FONT_FAMILY
      },
      splitLine: {
        lineStyle: {
          color: THEME.split,
          type: 'dashed'
        }
      }
    },
    yAxis: {
      type: 'category',
      data: data.map((item) => item.project),
      inverse: true,
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: THEME.text.regular,
        fontSize: layout.axisFontSize,
        fontWeight: 600,
        fontFamily: FONT_FAMILY,
        margin: layout.yAxisLabelMargin,
        width: layout.yAxisLabelWidth,
        overflow: 'break',
        align: 'right'
      }
    },
    series: [
      {
        name: '年初积压',
        type: 'bar',
        data: data.map((item) => item.yearBeginningBacklog),
        barWidth: layout.barWidth,
        barGap: layout.barGap,
        barCategoryGap: layout.barCategoryGap,
        label: barLabel,
        labelLayout: {
          hideOverlap: false
        },
        itemStyle: {
          shadowBlur: 10,
          shadowColor: THEME.color.blue.bg,
          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
            { offset: 0, color: THEME.color.blue.light },
            { offset: 0.55, color: THEME.color.blue.mid },
            { offset: 1, color: THEME.color.blue.line }
          ])
        }
      },
      {
        name: '5月底积压',
        type: 'bar',
        data: data.map((item) => item.mayBacklogAmount),
        barWidth: layout.barWidth,
        barGap: layout.barGap,
        barCategoryGap: layout.barCategoryGap,
        label: barLabel,
        labelLayout: {
          hideOverlap: false
        },
        itemStyle: {
          shadowBlur: 10,
          shadowColor: THEME.color.orange.bg,
          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
            { offset: 0, color: THEME.color.orange.light },
            { offset: 0.55, color: THEME.color.orange.mid },
            { offset: 1, color: THEME.color.orange.line }
          ])
        }
      }
    ]
  }
}

function initChart(
  chartRef: Ref<HTMLDivElement | undefined>,
  chart: echarts.ECharts | null,
  option: echarts.EChartsOption
) {
  if (!chartRef.value) return chart

  chart?.dispose()
  const nextChart = echarts.init(chartRef.value, undefined, {
    renderer: CHART_RENDERER
  })
  nextChart.setOption(option, true)

  return nextChart
}

function renderDistributionChart() {
  distributionChart?.setOption(getDistributionOption(inventoryData), true)
}

function renderTrendChart() {
  trendChart?.setOption(getTrendOption(inventoryData), true)
}

function initDistributionChart() {
  distributionChart = initChart(
    distributionChartRef,
    distributionChart,
    getDistributionOption(inventoryData)
  )
}

function initTrendChart() {
  trendChart = initChart(trendChartRef, trendChart, getTrendOption(inventoryData))
}

function resizeCharts() {
  distributionChart?.resize()
  trendChart?.resize()
  renderDistributionChart()
  renderTrendChart()
}

function destroyCharts() {
  distributionChart?.dispose()
  trendChart?.dispose()
  distributionChart = null
  trendChart = null
}

watch(activePanel, (value) => {
  nextTick(() => {
    if (value === 'distribution') {
      if (!distributionChart) initDistributionChart()
      renderDistributionChart()
    } else {
      if (!trendChart) initTrendChart()
      renderTrendChart()
    }
    resizeCharts()
  })
})

onMounted(() => {
  initDistributionChart()
  window.addEventListener('resize', resizeCharts)
  window.addEventListener('rhkb:resize', resizeCharts)
})

onUnmounted(() => {
  window.removeEventListener('resize', resizeCharts)
  window.removeEventListener('rhkb:resize', resizeCharts)
  destroyCharts()
})
</script>

<template>
  <div class="panel flex flex-col">
    <div class="panel-title flex items-center justify-between">
      <div class="kb-panel-title-text flex items-center">
        <div class="icon-decorator">
          <span></span>
          <span></span>
        </div>
        {{ activeTitle }}
      </div>
      <el-segmented
        v-model="activePanel"
        :options="panelOptions"
        size="small"
        class="inventory-switch" />
    </div>
    <div class="flex-1 min-h-0">
      <div
        v-show="activePanel === 'distribution'"
        ref="distributionChartRef"
        class="inventory-chart"></div>
      <div v-show="activePanel === 'trend'" ref="trendChartRef" class="inventory-chart"></div>
    </div>
  </div>
</template>

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

.inventory-switch {
  --el-segmented-item-selected-color: #03409b;
  --el-segmented-item-selected-bg-color: rgb(255 255 255 / 86%);
  --el-segmented-bg-color: rgb(31 91 184 / 10%);
  --el-segmented-item-hover-bg-color: rgb(255 255 255 / 56%);

  min-height: calc(26px * var(--kb-scale, 1));
  padding: calc(2px * var(--kb-scale, 1));
  border: 1px solid rgb(31 91 184 / 12%);
  transform: translateY(calc(-2px * var(--kb-scale, 1)));

  :deep(.el-segmented__item) {
    min-height: calc(22px * var(--kb-scale, 1));
    padding: 0 calc(8px * var(--kb-scale, 1));
    font-size: calc(13px * var(--kb-scale, 1));
    font-weight: 600;
    color: #29527f;
  }
}

.inventory-chart {
  width: 100%;
  height: 100%;
  min-height: 0;
}
</style>
