<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 activeTitle = computed(() => (activePanel.value === 'distribution' ? '存货分布' : '积压趋势'))

const inventoryData: InventoryItem[] = [
  {
    project: '东营中心仓',
    mayInventoryAmount: 7.35,
    yearBeginningBacklog: 10.13,
    mayBacklogAmount: 7.02
  },
  {
    project: '吉尔吉斯',
    mayInventoryAmount: 23.82,
    yearBeginningBacklog: 23.82,
    mayBacklogAmount: 25.18
  },
  {
    project: '新疆-连油',
    mayInventoryAmount: 21.9,
    yearBeginningBacklog: 177.02,
    mayBacklogAmount: 19.55
  },
  {
    project: '青海',
    mayInventoryAmount: 52.03,
    yearBeginningBacklog: 177.97,
    mayBacklogAmount: 53.46
  },
  {
    project: '东部-陕蒙',
    mayInventoryAmount: 5.63,
    yearBeginningBacklog: 84.75,
    mayBacklogAmount: 7.65
  },
  {
    project: '东部-胜利',
    mayInventoryAmount: 8.82,
    yearBeginningBacklog: 59.9,
    mayBacklogAmount: 10.67
  },
  {
    project: '西南压裂',
    mayInventoryAmount: 41.78,
    yearBeginningBacklog: 174.18,
    mayBacklogAmount: 27.72
  },
  {
    project: '西南连油',
    mayInventoryAmount: 24.13,
    yearBeginningBacklog: 90.01,
    mayBacklogAmount: 23.37
  },
  {
    project: '伊拉克(国内)',
    mayInventoryAmount: 0.1,
    yearBeginningBacklog: 190.71,
    mayBacklogAmount: 0.1
  },
  {
    project: '大庆工具',
    mayInventoryAmount: 0.12,
    yearBeginningBacklog: 1.79,
    mayBacklogAmount: 0.05
  },
  {
    project: '利比亚(国内)',
    mayInventoryAmount: 0,
    yearBeginningBacklog: 31.33,
    mayBacklogAmount: 0
  }
]

function formatProjectName(value: string) {
  return value.replace(/项目$/, '')
}

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

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

  return {
    compact,
    trendGridTop: compact ? 34 : 40,
    trendGridLeft: compact ? 36 : 44,
    trendGridRight: compact ? 8 : 16,
    trendGridBottom: compact ? 12 : 12,
    legendTop: compact ? 0 : 4,
    legendRight: compact ? 2 : 6,
    legendItemSize: compact ? 8 : 10,
    legendGap: compact ? 8 : 12,
    legendFontSize: compact ? 10 : 12,
    axisFontSize: compact ? 10 : 10,
    yAxisLabelMargin: compact ? 6 : 8,
    xAxisLabelRotate: compact ? 45 : 36,
    distributionTitleTop: compact ? 6 : 4,
    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,
    pieLabelNameFontSize: compact ? 11 : 13,
    pieLabelNameLineHeight: compact ? 18 : 22,
    pieLabelValueFontSize: compact ? 16 : 20,
    pieLabelValueLineHeight: compact ? 22 : 30,
    barWidth: compact ? 10 : 12,
    barGap: compact ? '10%' : '8%',
    barCategoryGap: compact ? '44%' : '38%',
    labelDistance: compact ? 4 : 7,
    labelFontSize: compact ? 10 : 12
  }
}

function getDistributionOption(data: InventoryItem[]): echarts.EChartsOption {
  const layout = getInventoryChartLayout(distributionChartRef)
  const inventoryTotal = data.reduce((total, item) => total + item.mayInventoryAmount, 0)
  const backlogTotal = data.reduce((total, item) => total + item.yearBeginningBacklog, 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
    ],
    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: `总库存金额\n${formatAmount(backlogTotal)} 万元`,
        left: '71.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: '总库存金额',
        type: 'pie',
        radius: layout.distributionPieRadius,
        center: ['73%', layout.distributionPieCenterY],
        minAngle: 5,
        label: { show: false },
        data: data
          .filter((item) => item.yearBeginningBacklog > 0)
          .map((item) => ({
            name: item.project,
            value: item.yearBeginningBacklog
          }))
      }
    ]
  }
}

function getTrendOption(data: InventoryItem[]): echarts.EChartsOption {
  const projects = data.map((item) => formatProjectName(item.project))
  const maxBacklog = Math.max(
    ...data.map((item) => Math.max(item.mayInventoryAmount, item.mayBacklogAmount)),
    1
  )
  const backlogAxisMax = Math.ceil((maxBacklog * 1.15) / 50) * 50
  const layout = getInventoryChartLayout(trendChartRef)
  const barLabel = {
    show: false,
    position: 'top' as any,
    distance: layout.labelDistance,
    color: THEME.text.strong,
    fontSize: layout.labelFontSize,
    fontWeight: 700,
    fontFamily: FONT_FAMILY,
    formatter(params: any) {
      const value = Number(params.value)

      return formatAmount(value)
    }
  }

  return {
    ...ANIMATION,
    grid: {
      ...THEME.grid,
      top: layout.trendGridTop,
      left: layout.trendGridLeft,
      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
        }
      },
      ['2026期初', '5月总积压']
    ),
    tooltip: createTooltip({
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
        shadowStyle: {
          color: THEME.split
        }
      },
      valueFormatter(value: number) {
        return `${formatAmount(value)}万元`
      }
    }),
    xAxis: {
      type: 'category',
      data: projects,
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: THEME.text.regular,
        fontSize: layout.axisFontSize,
        fontWeight: 600,
        fontFamily: FONT_FAMILY,
        interval: 0,
        margin: layout.yAxisLabelMargin,
        rotate: layout.xAxisLabelRotate
      }
    },
    yAxis: {
      type: 'value',
      max: backlogAxisMax,
      splitNumber: 4,
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: THEME.text.regular,
        fontSize: layout.axisFontSize,
        fontFamily: FONT_FAMILY,
        formatter(value: number) {
          return `${value}`
        }
      },
      splitLine: {
        lineStyle: {
          color: THEME.split,
          type: 'dashed'
        }
      }
    },
    series: [
      {
        name: '2026期初',
        type: 'bar',
        data: data.map((item) => item.mayBacklogAmount),
        barWidth: layout.barWidth,
        barGap: layout.barGap,
        barCategoryGap: layout.barCategoryGap,
        barMinHeight: 0,
        showBackground: false,
        backgroundStyle: {
          color: THEME.split,
          borderRadius: 999
        },
        label: barLabel,
        labelLayout: {
          hideOverlap: true
        },
        itemStyle: {
          shadowBlur: 10,
          shadowColor: THEME.color.blue.bg,
          color: new echarts.graphic.LinearGradient(0, 1, 0, 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.mayInventoryAmount),
        barWidth: layout.barWidth,
        barMinHeight: 0,
        barGap: layout.barGap,
        barCategoryGap: layout.barCategoryGap,
        showBackground: false,
        backgroundStyle: {
          color: THEME.split,
          borderRadius: 999
        },
        label: barLabel,
        labelLayout: {
          hideOverlap: true
        },
        itemStyle: {
          shadowBlur: 10,
          shadowColor: THEME.color.orange.bg,
          color: new echarts.graphic.LinearGradient(0, 1, 0, 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('rdkb:resize', resizeCharts)
})

onUnmounted(() => {
  window.removeEventListener('resize', resizeCharts)
  window.removeEventListener('rdkb: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>
