/** 大屏首页 ECharts 配置（深色主题，与 screen-theme 一致） */

const AXIS_LABEL = { color: '#9fb0c3', fontSize: 10 }
/** 12 个月横轴：不旋转，略缩小字号以适配窄图 */
const MONTH_AXIS_LABEL = { color: '#9fb0c3', fontSize: 9, margin: 6 }
const AXIS_LINE = { lineStyle: { color: 'rgba(61, 217, 176, 0.35)' } }
const SPLIT_LINE = { lineStyle: { color: 'rgba(61, 217, 176, 0.12)' } }
const GRID = { left: 22, right: 8, top: 24, bottom: 6, containLabel: true }

function emptyOption(text = '暂无数据') {
  return {
    title: {
      text,
      left: 'center',
      top: 'middle',
      textStyle: { color: '#6a9f90', fontSize: 13, fontWeight: 'normal' }
    }
  }
}

function pickNumber(row, fields) {
  for (const key of fields) {
    const raw = row?.[key]
    if (raw != null && raw !== '') {
      const n = Number(raw)
      if (!Number.isNaN(n)) {
        return n
      }
    }
  }
  return 0
}

/** 滚动最近 12 月：按 statYear、month 升序 */
function sortRollingMonths(list) {
  return [...(list || [])].sort((a, b) => {
    const ak = (Number(a.statYear) || 0) * 100 + (Number(a.month) || 0)
    const bk = (Number(b.statYear) || 0) * 100 + (Number(b.month) || 0)
    return ak - bk
  })
}

function rollingMonthLabel(row) {
  return `${Number(row.month)}月`
}

function rollingTooltipTitle(row) {
  if (!row) {
    return ''
  }
  return `${row.statYear}年${Number(row.month)}月`
}

function buildRollingAxis(list) {
  const rows = sortRollingMonths(list)
  return {
    rows,
    categories: rows.map(rollingMonthLabel),
    titleAt: (dataIndex) => rollingTooltipTitle(rows[dataIndex])
  }
}

function rollingSeries(list, field, altFields = []) {
  const fields = [field, ...altFields]
  return sortRollingMonths(list).map((row) => pickNumber(row, fields))
}

/** 牦牛存栏变动：公牛 / 母牛折线（滚动 12 月） */
export function buildInventoryTrendOption(monthlyTrend) {
  if (!monthlyTrend?.length) {
    return emptyOption()
  }
  const axis = buildRollingAxis(monthlyTrend)
  return {
    color: ['#5ef0c8', '#ecd27b'],
    tooltip: {
      trigger: 'axis',
      formatter: (params) => {
        if (!Array.isArray(params) || !params.length) {
          return ''
        }
        const title = axis.titleAt(params[0].dataIndex)
        const lines = params.map((p) => `${p.marker}${p.seriesName} ${p.value} 头`)
        return `${title}<br/>${lines.join('<br/>')}`
      }
    },
    legend: {
      top: 0,
      right: 8,
      textStyle: { color: '#a8d4c8', fontSize: 10 },
      itemWidth: 12,
      itemHeight: 8
    },
    grid: GRID,
    xAxis: {
      type: 'category',
      data: axis.categories,
      axisLabel: { ...MONTH_AXIS_LABEL, interval: 0 },
      axisLine: AXIS_LINE,
      axisTick: { show: false }
    },
    yAxis: {
      type: 'value',
      axisLabel: AXIS_LABEL,
      axisLine: AXIS_LINE,
      splitLine: SPLIT_LINE
    },
    series: [
      {
        name: '公牛',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 4,
        data: rollingSeries(monthlyTrend, 'bullCount')
      },
      {
        name: '母牛',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 4,
        data: rollingSeries(monthlyTrend, 'cowCount')
      }
    ]
  }
}

/** 年龄四档配色（母牛分龄：1岁以下 / 1～3岁 / 3～12岁 / 12岁以上） */
const AGE_BAND_COLOR = {
  COW_U1: '#45c997',
  COW_1_3: '#6eb5ff',
  COW_3_12: '#547233',
  COW_O12: '#ecd27b'
}

const AGE_BAND_ORDER = ['COW_U1', 'COW_1_3', 'COW_3_12', 'COW_O12']

function sortAgeBands(ageStructure) {
  const map = new Map((ageStructure || []).map((item) => [item.bandCode, item]))
  const ordered = AGE_BAND_ORDER.map((code) => map.get(code)).filter(Boolean)
  return ordered.length ? ordered : [...(ageStructure || [])]
}

function formatAgeRatio(ratio, percent) {
  if (ratio != null && ratio !== '') {
    return `${Number(ratio).toFixed(0)}%`
  }
  return `${Math.round(percent)}%`
}

/** 牦牛年龄结构（环形图 + 右侧图例，固定四档） */
export function buildAgeStructureOption(ageStructure) {
  if (!ageStructure?.length) {
    return emptyOption()
  }
  const bands = sortAgeBands(ageStructure)
  const data = bands.map((item) => ({
    name: item.bandLabel || item.bandCode,
    value: pickNumber(item, ['count']),
    ratio: item.ratio,
    itemStyle: {
      color: AGE_BAND_COLOR[item.bandCode] || '#45f0b8',
      shadowBlur: 8,
      shadowColor: 'rgba(0, 0, 0, 0.45)',
      shadowOffsetY: 2
    }
  }))
  const hasSlice = data.some((d) => d.value > 0)
  const centerGraphic = hasSlice
    ? []
    : [
        {
          type: 'text',
          left: '26%',
          top: '46%',
          style: {
            text: '暂无存栏',
            fill: '#6a9f90',
            fontSize: 11,
            textAlign: 'center'
          }
        }
      ]
  return {
    color: Object.values(AGE_BAND_COLOR),
    tooltip: {
      trigger: 'item',
      formatter: (p) => {
        const row = bands[p.dataIndex]
        const ratio =
          row?.ratio != null ? `${Number(row.ratio).toFixed(1)}%` : `${p.percent?.toFixed(1)}%`
        return `${p.name}<br/>${p.value} 头 (${ratio})`
      }
    },
    legend: {
      orient: 'vertical',
      right: '2%',
      top: 'middle',
      icon: 'circle',
      itemWidth: 8,
      itemHeight: 8,
      itemGap: 10,
      textStyle: { color: '#e8eef5', fontSize: 10 }
    },
    graphic: [
      {
        type: 'circle',
        left: '22%',
        top: '38%',
        shape: { r: 52 },
        style: {
          fill: 'transparent',
          stroke: 'rgba(61, 217, 176, 0.22)',
          lineWidth: 1
        },
        z: 0
      },
      {
        type: 'circle',
        left: '20%',
        top: '36%',
        shape: { r: 58 },
        style: {
          fill: 'transparent',
          stroke: 'rgba(61, 217, 176, 0.12)',
          lineWidth: 1
        },
        z: 0
      },
      ...centerGraphic
    ],
    series: [
      {
        type: 'pie',
        radius: ['42%', '68%'],
        center: ['34%', '54%'],
        avoidLabelOverlap: true,
        stillShowZeroSum: false,
        itemStyle: {
          borderColor: 'rgba(2, 22, 18, 0.9)',
          borderWidth: 2
        },
        label: {
          show: hasSlice,
          position: 'inside',
          color: '#fff',
          fontSize: 10,
          fontWeight: 'bold',
          formatter: (p) => formatAgeRatio(p.data.ratio, p.percent)
        },
        labelLine: { show: false },
        emphasis: {
          scale: true,
          scaleSize: 5
        },
        data: hasSlice ? data : []
      }
    ]
  }
}

/** 牦牛存栏结构 — 内环大类配色 */
const YAK_CATEGORY_COLOR = {
  BULL: '#5ef0c8',
  COW: '#6eb5ff',
  INSURED: '#ecd27b'
}

/** 牦牛存栏结构 — 外环细分配色（对齐科技特派员双层饼风格） */
const YAK_DETAIL_COLOR = {
  BREEDING_BULL: '#5ef0c8',
  BULL_CASTRATED: '#3b9e84',
  COW_YOUNG: '#6eb5ff',
  COW_ADULT: '#98e9aa',
  INSURED: '#ecd27b'
}

/**
 * 牦牛存栏结构（内外双层饼，样式对齐畜牧资源「科技特派员」）：
 * 内环大类 BULL/COW/INSURED，外环 details 细分。
 * @param {Array} structure yakInventoryStructure[]
 */
export function buildYakInventoryStructureOption(structure) {
  if (!structure?.length) {
    return emptyOption()
  }
  const categoryTotal = structure.reduce((sum, item) => sum + pickNumber(item, ['count']), 0)
  const detailRows = []
  for (const cat of structure) {
    const categoryLabel = cat?.categoryLabel || cat?.categoryCode || ''
    const details = cat?.details
    if (details?.length) {
      for (const d of details) {
        detailRows.push({
          ...d,
          categoryLabel
        })
      }
    } else if (cat) {
      detailRows.push({
        detailCode: cat.categoryCode,
        detailLabel: cat.categoryLabel,
        count: cat.count,
        ratio: cat.ratio,
        categoryLabel
      })
    }
  }
  const detailTotal = detailRows.reduce((sum, item) => sum + pickNumber(item, ['count']), 0)
  if (categoryTotal <= 0 && detailTotal <= 0) {
    return emptyOption()
  }

  const fallbackColors = ['#5ef0c8', '#6eb5ff', '#ecd27b', '#98e9aa', '#3b9e84']
  const innerData = structure.map((item, i) => {
    const code = item.categoryCode || ''
    const color = YAK_CATEGORY_COLOR[code] || fallbackColors[i % fallbackColors.length]
    return {
      name: item.categoryLabel || code || '未知',
      value: pickNumber(item, ['count']),
      ratio: item.ratio,
      itemStyle: { color }
    }
  })
  const outerData = detailRows.map((item, i) => {
    const code = item.detailCode || ''
    const color = YAK_DETAIL_COLOR[code] || fallbackColors[i % fallbackColors.length]
    return {
      name: item.detailLabel || code || '未知',
      value: pickNumber(item, ['count']),
      ratio: item.ratio,
      categoryLabel: item.categoryLabel || '',
      itemStyle: { color },
      label: { color },
      labelLine: { lineStyle: { color } }
    }
  })

  const pieBorder = {
    borderColor: 'rgba(8, 48, 42, 0.88)',
    borderWidth: 2
  }

  return {
    title: { show: false },
    tooltip: {
      trigger: 'item',
      formatter: (p) => {
        const ratio =
          p.data?.ratio != null ? `${Number(p.data.ratio).toFixed(1)}%` : `${p.percent?.toFixed(1)}%`
        const seriesName =
          p.seriesName === '存栏细分' && p.data?.categoryLabel
            ? `${p.seriesName}（${p.data.categoryLabel}）`
            : p.seriesName
        return `${seriesName}<br/>${p.marker}${p.name}: ${p.value ?? 0} 头 (${ratio})`
      }
    },
    legend: {
      show: false
    },
    series: [
      // 外环：细分（种公牛 / 阉畜 / 幼畜 / 成畜 / 保险）
      {
        name: '存栏细分',
        type: 'pie',
        radius: ['58%', '74%'],
        center: ['50%', '52%'],
        avoidLabelOverlap: true,
        itemStyle: pieBorder,
        label: {
          show: true,
          fontSize: 11,
          formatter: (p) => p.name
        },
        labelLine: {
          show: true,
          length: 10,
          length2: 12
        },
        data: outerData
      },
      // 内饼：公牛 / 母牛 / 保险牛
      {
        name: '存栏大类',
        type: 'pie',
        radius: [0, '46%'],
        center: ['50%', '52%'],
        avoidLabelOverlap: true,
        itemStyle: pieBorder,
        label: {
          show: true,
          position: 'inside',
          color: '#fff',
          fontSize: 12,
          fontWeight: 600,
          formatter: (p) => p.name
        },
        labelLine: { show: false },
        data: innerData
      }
    ]
  }
}

/** 出栏柱图金色渐变 */
const OUTBOUND_BAR_GRADIENT = {
  type: 'linear',
  x: 0,
  y: 1,
  x2: 0,
  y2: 0,
  colorStops: [
    { offset: 0, color: '#6b4f18' },
    { offset: 0.45, color: '#b8923a' },
    { offset: 1, color: '#f7d547' }
  ]
}

const OUTBOUND_GRID = { left: 36, right: 8, top: 28, bottom: 6, containLabel: true }
const OUTBOUND_SPLIT_LINE = {
  lineStyle: { color: 'rgba(120, 140, 160, 0.28)', type: 'dashed' }
}

/** 牦牛出栏按月（纯柱状图，滚动 12 月） */
export function buildOutboundOption(outboundMonthly) {
  if (!outboundMonthly?.length) {
    return emptyOption()
  }
  const axis = buildRollingAxis(outboundMonthly)
  const values = rollingSeries(outboundMonthly, 'outboundCount', ['outbound_count', 'count'])
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params) => {
        const p = Array.isArray(params) ? params[0] : params
        if (!p) {
          return ''
        }
        const title = axis.titleAt(p.dataIndex)
        return `${title}<br/>出栏 ${p.value} 头`
      }
    },
    grid: OUTBOUND_GRID,
    xAxis: {
      type: 'category',
      data: axis.categories,
      axisLabel: { ...MONTH_AXIS_LABEL, interval: 0 },
      axisLine: { lineStyle: { color: 'rgba(150, 170, 190, 0.45)' } },
      axisTick: { show: false }
    },
    yAxis: {
      type: 'value',
      minInterval: 1,
      axisLabel: AXIS_LABEL,
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: OUTBOUND_SPLIT_LINE
    },
    series: [
      {
        name: '出栏',
        type: 'bar',
        barWidth: '46%',
        itemStyle: {
          color: OUTBOUND_BAR_GRADIENT,
          borderRadius: [10, 10, 10, 10]
        },
        data: values
      }
    ]
  }
}

/** 牲畜出栏六畜配色（偏暗，保证白色文字可读） */
const LIVESTOCK_OUTBOUND_COLOR = {
  YAK: '#2a9d7a',
  CATTLE: '#b8923a',
  SHEEP: '#3d7ab8',
  GOAT: '#2f4f9e',
  HORSE_MULE: '#c47a1a',
  DONKEY: '#2f8a6a'
}

/** 树图过小扇区的布局下限：至少占总量约 4%，保证 1 头也能看见 */
const LIVESTOCK_TREEMAP_MIN_SHARE = 0.04

/**
 * 牲畜出栏统计（矩形树图）：livestockOutboundStructure[]
 * 项含 speciesCode / speciesLabel / count / ratio / unit
 */
export function buildLivestockOutboundStructureOption(structure) {
  if (!structure?.length) {
    return emptyOption()
  }
  const rows = structure
    .map((item, i) => {
      const code = item.speciesCode || ''
      const count = pickNumber(item, ['count'])
      return {
        name: item.speciesLabel || code || '未知',
        realCount: count,
        ratio: item.ratio,
        unit: item.unit || '头',
        itemStyle: {
          color: LIVESTOCK_OUTBOUND_COLOR[code] || Object.values(LIVESTOCK_OUTBOUND_COLOR)[i % 6],
          borderColor: 'rgba(2, 22, 18, 0.85)',
          borderWidth: 2,
          borderRadius: 4
        }
      }
    })
    .filter((d) => d.realCount > 0)
  if (!rows.length) {
    return emptyOption()
  }
  const total = rows.reduce((sum, d) => sum + d.realCount, 0)
  const minVisual = Math.max(total * LIVESTOCK_TREEMAP_MIN_SHARE, 1)
  const data = rows.map((d) => ({
    ...d,
    value: Math.max(d.realCount, minVisual)
  }))
  return {
    tooltip: {
      trigger: 'item',
      formatter: (p) => {
        const unit = p.data?.unit || '头'
        const count = p.data?.realCount ?? p.value
        const ratio =
          p.data?.ratio != null
            ? `${Number(p.data.ratio).toFixed(1)}%`
            : total > 0
              ? `${((Number(count) / total) * 100).toFixed(1)}%`
              : '-'
        return `${p.name}<br/>${count}${unit} (${ratio})`
      }
    },
    series: [
      {
        type: 'treemap',
        width: '96%',
        height: '92%',
        left: '2%',
        top: '4%',
        roam: false,
        nodeClick: false,
        breadcrumb: { show: false },
        squareRatio: 0.75 * (1 + Math.sqrt(5)),
        label: {
          show: true,
          formatter: (p) => {
            const unit = p.data?.unit || '头'
            const count = p.data?.realCount ?? p.value
            const ratioText =
              p.data?.ratio != null
                ? `${Number(p.data.ratio).toFixed(0)}%`
                : ''
            return ratioText
              ? `{name|${p.name}}\n{val|${count}${unit}}\n{pct|${ratioText}}`
              : `{name|${p.name}}\n{val|${count}${unit}}`
          },
          rich: {
            name: { color: '#ffffff', fontSize: 11, fontWeight: 600, lineHeight: 16 },
            val: { color: 'rgba(255,255,255,0.92)', fontSize: 10, lineHeight: 14 },
            pct: { color: 'rgba(232,238,245,0.85)', fontSize: 10, lineHeight: 14 }
          }
        },
        upperLabel: { show: false },
        itemStyle: {
          gapWidth: 3,
          borderColor: 'rgba(2, 22, 18, 0.9)'
        },
        emphasis: {
          itemStyle: {
            shadowBlur: 12,
            shadowColor: 'rgba(0, 0, 0, 0.45)'
          }
        },
        levels: [
          {
            itemStyle: {
              borderWidth: 0,
              gapWidth: 3
            }
          }
        ],
        data
      }
    ]
  }
}

/** 自食情况柱图：上绿下蓝渐变，顶部圆角 */
const SELF_CONSUMPTION_BAR_GRADIENT = {
  type: 'linear',
  x: 0,
  y: 0,
  x2: 0,
  y2: 1,
  colorStops: [
    { offset: 0, color: '#3ecf9a' },
    { offset: 0.45, color: '#2a9d9a' },
    { offset: 1, color: '#2f5fad' }
  ]
}

/**
 * 自食情况统计（柱状图）：selfConsumption.items[]
 * 项含 itemCode / itemLabel / count，单位：头
 */
export function buildSelfConsumptionOption(selfConsumption) {
  const items = selfConsumption?.items
  if (!items?.length) {
    return emptyOption()
  }
  const categories = items.map((item) => item.itemLabel || item.itemCode || '')
  const values = items.map((item) => pickNumber(item, ['count']))
  if (!values.some((v) => v > 0)) {
    return emptyOption()
  }
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params) => {
        const p = Array.isArray(params) ? params[0] : params
        if (!p) {
          return ''
        }
        return `${p.name}<br/>自食 ${p.value} 头`
      }
    },
    grid: { left: 36, right: 10, top: 28, bottom: 8, containLabel: true },
    xAxis: {
      type: 'category',
      data: categories,
      axisLabel: { color: '#9fb0c3', fontSize: 11 },
      axisLine: { lineStyle: { color: 'rgba(150, 170, 190, 0.45)' } },
      axisTick: { show: false }
    },
    yAxis: {
      type: 'value',
      minInterval: 1,
      name: '头',
      nameTextStyle: { color: '#9fb0c3', fontSize: 10, padding: [0, 28, 0, 0] },
      axisLabel: AXIS_LABEL,
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: {
        lineStyle: { color: 'rgba(120, 140, 160, 0.28)', type: 'dashed' }
      }
    },
    series: [
      {
        name: '自食',
        type: 'bar',
        barWidth: '28%',
        itemStyle: {
          color: SELF_CONSUMPTION_BAR_GRADIENT,
          borderRadius: [10, 10, 0, 0]
        },
        label: {
          show: true,
          position: 'top',
          color: '#c8e6d8',
          fontSize: 10,
          formatter: '{c}'
        },
        data: values
      }
    ]
  }
}

/** 农牧户分类柱图：上金下青渐变，顶部圆角（区别于自食绿蓝） */
const FARMER_CLASS_BAR_GRADIENT = {
  type: 'linear',
  x: 0,
  y: 0,
  x2: 0,
  y2: 1,
  colorStops: [
    { offset: 0, color: '#e0b84a' },
    { offset: 0.45, color: '#3aa8a0' },
    { offset: 1, color: '#1e6a9e' }
  ]
}

/**
 * 农牧户分类（柱状图）：farmerHouseholdClassification[]
 * 项含 itemCode / itemLabel / count，单位：个
 */
export function buildFarmerHouseholdClassificationOption(structure) {
  if (!structure?.length) {
    return emptyOption()
  }
  const categories = structure.map((item) => item.itemLabel || item.itemCode || '')
  const values = structure.map((item) => pickNumber(item, ['count']))
  if (!values.some((v) => v > 0)) {
    return emptyOption()
  }
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params) => {
        const p = Array.isArray(params) ? params[0] : params
        if (!p) {
          return ''
        }
        return `${p.name}<br/>${p.value} 个`
      }
    },
    grid: { left: 28, right: 8, top: 28, bottom: 8, containLabel: true },
    xAxis: {
      type: 'category',
      data: categories,
      axisLabel: {
        color: '#9fb0c3',
        fontSize: 9,
        interval: 0,
        hideOverlap: false
      },
      axisLine: { lineStyle: { color: 'rgba(150, 170, 190, 0.45)' } },
      axisTick: { show: false }
    },
    yAxis: {
      type: 'value',
      minInterval: 1,
      name: '个',
      nameTextStyle: { color: '#9fb0c3', fontSize: 10, padding: [0, 28, 0, 0] },
      axisLabel: AXIS_LABEL,
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: {
        lineStyle: { color: 'rgba(120, 140, 160, 0.28)', type: 'dashed' }
      }
    },
    series: [
      {
        name: '补助奖励资金',
        type: 'bar',
        barWidth: '36%',
        itemStyle: {
          color: FARMER_CLASS_BAR_GRADIENT,
          borderRadius: [10, 10, 0, 0]
        },
        label: {
          show: true,
          position: 'top',
          color: '#d8e8f0',
          fontSize: 9,
          formatter: '{c}'
        },
        data: values
      }
    ]
  }
}

/** 企业财务柱图配色（偏暗，白字可读） */
const ENTERPRISE_FINANCE_BAR_COLOR = {
  INCOME: '#2a9d7a',
  EXPENSE: '#3d7ab8',
  PROFIT: '#b8923a',
  SUBSIDY: '#2f5fad'
}

/**
 * 企业年度收入与补助（柱状图）：familyRanchFinance / largeLivestockFarmerFinance
 * items[] 含 itemCode / itemLabel / amountWan，单位：万元
 * @param {object|null} finance
 * @param {string} axisName 横轴下方名称（家庭牧场 / 养殖大户）
 */
export function buildEnterpriseFinanceOption(finance, axisName) {
  const items = finance?.items
  if (!items?.length) {
    return emptyOption()
  }
  const categories = items.map((item) => item.itemLabel || item.itemCode || '')
  const data = items.map((item, i) => {
    const code = item.itemCode || ''
    return {
      value: pickNumber(item, ['amountWan', 'amount_wan', 'amount']),
      itemStyle: {
        color:
          ENTERPRISE_FINANCE_BAR_COLOR[code] ||
          Object.values(ENTERPRISE_FINANCE_BAR_COLOR)[i % 4],
        borderRadius: [6, 6, 0, 0]
      }
    }
  })
  return {
    title: {
      text: axisName || '',
      left: 'center',
      top: 0,
      textStyle: { color: '#89D9AD', fontSize: 11, fontWeight: 600 }
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params) => {
        const p = Array.isArray(params) ? params[0] : params
        if (!p) {
          return ''
        }
        const prefix = axisName ? `${axisName}<br/>` : ''
        return `${prefix}${p.name}：${p.value} 万元`
      }
    },
    grid: { left: 8, right: 8, top: 28, bottom: 8, containLabel: true },
    xAxis: {
      type: 'category',
      data: categories,
      axisLabel: {
        color: '#9fb0c3',
        fontSize: 9,
        interval: 0,
        hideOverlap: false
      },
      axisLine: { lineStyle: { color: 'rgba(150, 170, 190, 0.45)' } },
      axisTick: { show: false }
    },
    yAxis: {
      type: 'value',
      name: '万元',
      nameTextStyle: { color: '#9fb0c3', fontSize: 9, padding: [0, 0, 0, 0] },
      axisLabel: { color: '#9fb0c3', fontSize: 9 },
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: {
        lineStyle: { color: 'rgba(120, 140, 160, 0.28)', type: 'dashed' }
      }
    },
    series: [
      {
        name: axisName || '金额',
        type: 'bar',
        barWidth: '36%',
        data
      }
    ]
  }
}

/** 合作社经营模式配色（偏暗） */
const COOP_MODEL_COLOR = {
  WHOLE_VILLAGE: '#2a9d7a',
  SHARE: '#3d7ab8',
  JOINT: '#b8923a',
  MULTI_BUSINESS: '#2f5fad',
  COMPANY_TYPE: '#5a8a4a',
  OTHER: '#6a7a8a'
}

/**
 * 合作社经营模式分类（饼图）：cooperativeBusinessModel[]
 * 项含 itemCode / itemLabel / count / ratio，单位：个
 */
export function buildCooperativeBusinessModelOption(structure) {
  if (!structure?.length) {
    return emptyOption()
  }
  const hasData = structure.some((item) => pickNumber(item, ['count']) > 0)
  if (!hasData) {
    return emptyOption()
  }
  const data = structure.map((item, i) => {
    const code = item.itemCode || ''
    return {
      name: item.itemLabel || code || '未知',
      value: pickNumber(item, ['count']),
      ratio: item.ratio,
      itemStyle: {
        color: COOP_MODEL_COLOR[code] || Object.values(COOP_MODEL_COLOR)[i % 6],
        shadowBlur: 8,
        shadowColor: 'rgba(0, 0, 0, 0.4)',
        shadowOffsetY: 2
      }
    }
  })
  return {
    color: Object.values(COOP_MODEL_COLOR),
    tooltip: {
      trigger: 'item',
      formatter: (p) => {
        const row = structure[p.dataIndex]
        const ratio =
          row?.ratio != null ? `${Number(row.ratio).toFixed(1)}%` : `${p.percent?.toFixed(1)}%`
        return `${p.name}<br/>${p.value} 个 (${ratio})`
      }
    },
    legend: {
      orient: 'vertical',
      right: '1%',
      top: 'middle',
      icon: 'circle',
      itemWidth: 8,
      itemHeight: 8,
      itemGap: 6,
      textStyle: { color: '#e8eef5', fontSize: 9 }
    },
    series: [
      {
        type: 'pie',
        radius: '64%',
        center: ['32%', '52%'],
        avoidLabelOverlap: true,
        itemStyle: {
          borderColor: 'rgba(2, 22, 18, 0.9)',
          borderWidth: 2
        },
        label: {
          show: true,
          position: 'inside',
          color: '#fff',
          fontSize: 9,
          fontWeight: 'bold',
          formatter: (p) => {
            if (p.data.ratio != null && p.data.ratio !== '') {
              return `${Number(p.data.ratio).toFixed(0)}%`
            }
            return `${Math.round(p.percent)}%`
          }
        },
        labelLine: { show: false },
        emphasis: {
          scale: true,
          scaleSize: 4,
          itemStyle: { shadowBlur: 12, shadowColor: 'rgba(0, 0, 0, 0.5)' }
        },
        data
      }
    ]
  }
}

/** 草场退化五档配色 */
const GRASSLAND_DEGRADATION_COLOR = {
  1: '#3b66d1',
  2: '#5dc3a1',
  3: '#547233',
  4: '#f7b538',
  5: '#3e5388'
}

/** 畜群存栏结构物种配色 */
const HERD_SPECIES_COLOR = {
  YAK: '#5ef0c8',
  DAIRY: '#ecd27b',
  SHEEP: '#3b66d1'
}

function formatGrasslandRatio(ratio, percent) {
  if (ratio != null && ratio !== '') {
    return `${Number(ratio).toFixed(0)}%`
  }
  return `${Math.round(percent)}%`
}

/**
 * 畜群存栏结构（环形饼图）：herdInventoryStructure[]
 * 项含 speciesCode / speciesLabel / count / ratio
 */
export function buildHerdInventoryStructureOption(structure) {
  if (!structure?.length) {
    return emptyOption()
  }
  const hasData = structure.some(
    (item) => pickNumber(item, ['count']) > 0 || pickNumber(item, ['ratio']) > 0
  )
  if (!hasData) {
    return emptyOption()
  }
  const data = structure.map((item) => {
    const code = item.speciesCode || ''
    return {
      name: item.speciesLabel || code || '未知',
      value: pickNumber(item, ['count']),
      ratio: item.ratio,
      itemStyle: {
        color: HERD_SPECIES_COLOR[code] || '#45f0b8',
        shadowBlur: 10,
        shadowColor: 'rgba(0, 0, 0, 0.5)',
        shadowOffsetY: 3
      }
    }
  })
  return {
    color: Object.values(HERD_SPECIES_COLOR),
    tooltip: {
      trigger: 'item',
      formatter: (p) => {
        const row = structure[p.dataIndex]
        const ratio =
          row?.ratio != null ? `${Number(row.ratio).toFixed(1)}%` : `${p.percent?.toFixed(1)}%`
        return `${p.name}<br/>${p.value}头 (${ratio})`
      }
    },
    legend: {
      orient: 'vertical',
      right: '2%',
      top: 'middle',
      icon: 'circle',
      itemWidth: 8,
      itemHeight: 8,
      itemGap: 10,
      textStyle: { color: '#e8eef5', fontSize: 10 }
    },
    series: [
      {
        type: 'pie',
        radius: ['42%', '68%'],
        center: ['34%', '54%'],
        avoidLabelOverlap: true,
        itemStyle: {
          borderColor: 'rgba(2, 22, 18, 0.9)',
          borderWidth: 2
        },
        label: {
          show: true,
          position: 'inside',
          color: '#fff',
          fontSize: 10,
          fontWeight: 'bold',
          formatter: (p) => formatGrasslandRatio(p.data.ratio, p.percent)
        },
        labelLine: { show: false },
        emphasis: {
          scale: true,
          scaleSize: 5,
          itemStyle: { shadowBlur: 14, shadowColor: 'rgba(0, 0, 0, 0.55)' }
        },
        data
      }
    ]
  }
}

/** 草场退化占比（环形图 + 右侧图例 + 扇区内占比） */
export function buildGrasslandOption(grassland) {
  const degradationStats = grassland?.degradationStats
  if (!degradationStats?.length) {
    return emptyOption()
  }
  const hasData = degradationStats.some(
    (item) => pickNumber(item, ['count']) > 0 || pickNumber(item, ['ratio']) > 0
  )
  if (!hasData) {
    return emptyOption()
  }
  const data = degradationStats.map((item) => ({
    name: item.degradationLabel || `等级${item.degradationLevel}`,
    value: pickNumber(item, ['count']),
    ratio: item.ratio,
    itemStyle: {
      color: GRASSLAND_DEGRADATION_COLOR[item.degradationLevel] || '#45f0b8',
      shadowBlur: 10,
      shadowColor: 'rgba(0, 0, 0, 0.5)',
      shadowOffsetY: 3
    }
  }))
  return {
    color: Object.values(GRASSLAND_DEGRADATION_COLOR),
    tooltip: {
      trigger: 'item',
      formatter: (p) => {
        const row = degradationStats[p.dataIndex]
        const ratio =
          row?.ratio != null ? `${Number(row.ratio).toFixed(1)}%` : `${p.percent?.toFixed(1)}%`
        return `${p.name}<br/>${p.value}个 (${ratio})`
      }
    },
    legend: {
      orient: 'vertical',
      right: '2%',
      top: 'middle',
      icon: 'circle',
      itemWidth: 8,
      itemHeight: 8,
      itemGap: 10,
      textStyle: { color: '#e8eef5', fontSize: 10 }
    },
    series: [
      {
        type: 'pie',
        radius: ['42%', '68%'],
        center: ['34%', '54%'],
        avoidLabelOverlap: true,
        itemStyle: {
          borderColor: 'rgba(2, 22, 18, 0.9)',
          borderWidth: 2
        },
        label: {
          show: true,
          position: 'inside',
          color: '#fff',
          fontSize: 10,
          fontWeight: 'bold',
          formatter: (p) => formatGrasslandRatio(p.data.ratio, p.percent)
        },
        labelLine: { show: false },
        emphasis: {
          scale: true,
          scaleSize: 5,
          itemStyle: { shadowBlur: 14, shadowColor: 'rgba(0, 0, 0, 0.55)' }
        },
        data
      }
    ]
  }
}

const APPOINTMENT_ORG_GRADIENT = {
  type: 'linear',
  x: 0,
  y: 1,
  x2: 0,
  y2: 0,
  colorStops: [
    { offset: 0, color: '#1e479b' },
    { offset: 1, color: '#3a6bc4' }
  ]
}

const APPOINTMENT_EXPERT_GRADIENT = {
  type: 'linear',
  x: 0,
  y: 1,
  x2: 0,
  y2: 0,
  colorStops: [
    { offset: 0, color: '#8e763d' },
    { offset: 1, color: '#d4a84a' }
  ]
}

const APPOINTMENT_GRID = { left: 44, right: 8, top: 26, bottom: 6, containLabel: true }
const APPOINTMENT_SPLIT_LINE = {
  lineStyle: { color: 'rgba(120, 140, 160, 0.28)', type: 'dashed' }
}

/** 线下服务预约堆叠柱（滚动 12 月） */
export function buildAppointmentStackedOption(monthlyStacked) {
  if (!monthlyStacked?.length) {
    return emptyOption()
  }
  const axis = buildRollingAxis(monthlyStacked)
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params) => {
        if (!Array.isArray(params) || !params.length) {
          return ''
        }
        const title = axis.titleAt(params[0].dataIndex)
        const lines = params.map((p) => `${p.marker}${p.seriesName} ${p.value} 人次`)
        return `${title}<br/>${lines.join('<br/>')}`
      }
    },
    legend: {
      top: 4,
      right: 8,
      itemWidth: 10,
      itemHeight: 8,
      textStyle: { color: '#e8eef5', fontSize: 10 },
      data: ['诊疗机构', '兽医', '专家']
    },
    grid: APPOINTMENT_GRID,
    xAxis: {
      type: 'category',
      data: axis.categories,
      axisLabel: { ...MONTH_AXIS_LABEL, interval: 0 },
      axisLine: { lineStyle: { color: 'rgba(150, 170, 190, 0.45)' } },
      axisTick: { show: false }
    },
    yAxis: {
      type: 'value',
      minInterval: 1,
      axisLabel: AXIS_LABEL,
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: APPOINTMENT_SPLIT_LINE
    },
    series: [
      {
        name: '诊疗机构',
        type: 'bar',
        stack: 'apt',
        barMaxWidth: 10,
        itemStyle: { color: APPOINTMENT_ORG_GRADIENT },
        data: rollingSeries(monthlyStacked, 'orgCount', ['org_count'])
      },
      {
        name: '兽医',
        type: 'bar',
        stack: 'apt',
        barMaxWidth: 10,
        itemStyle: { color: '#52b89f' },
        data: rollingSeries(monthlyStacked, 'vetCount', ['vet_count'])
      },
      {
        name: '专家',
        type: 'bar',
        stack: 'apt',
        barMaxWidth: 10,
        itemStyle: { color: APPOINTMENT_EXPERT_GRADIENT },
        data: rollingSeries(monthlyStacked, 'expertCount', ['expert_count'])
      }
    ]
  }
}

/** 三类柱图配色 */
const STACK_BAR_COLORS = [APPOINTMENT_ORG_GRADIENT, '#52b89f', APPOINTMENT_EXPERT_GRADIENT]

/** 惠农补贴（万元） */
export function buildSubsidyOption(typeStats, hasSubsidyData) {
  if (!hasSubsidyData || !typeStats?.length) {
    return emptyOption('暂无补贴数据')
  }
  const categories = typeStats.map(
    (item) => item.subsidyTypeName || `类型${item.subsidyType}`
  )
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params) => {
        const p = Array.isArray(params) ? params[0] : params
        if (!p) {
          return ''
        }
        const val = p.value != null ? Number(p.value) : 0
        return `${p.name}<br/>补贴金额 ${val.toLocaleString('zh-CN', {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })} 万元`
      }
    },
    grid: GRID,
    xAxis: {
      type: 'category',
      data: categories,
      axisLabel: { ...AXIS_LABEL, interval: 0, fontSize: 9, margin: 6 },
      axisLine: AXIS_LINE,
      axisTick: { show: false }
    },
    yAxis: {
      type: 'value',
      name: '万元',
      nameTextStyle: { color: '#6a9f90', fontSize: 10 },
      axisLabel: AXIS_LABEL,
      axisLine: AXIS_LINE,
      splitLine: SPLIT_LINE
    },
    series: [
      {
        name: '补贴金额',
        type: 'bar',
        barMaxWidth: 28,
        data: typeStats.map((item, index) => ({
          value: Number(item.amountWan ?? 0),
          itemStyle: { color: STACK_BAR_COLORS[index % STACK_BAR_COLORS.length] }
        }))
      }
    ]
  }
}

const TRAINING_ACTIVITY_LINE = '#ff9f43'
const TRAINING_ACTIVITY_AREA = {
  type: 'linear',
  x: 0,
  y: 0,
  x2: 0,
  y2: 1,
  colorStops: [
    { offset: 0, color: 'rgba(255, 159, 67, 0.55)' },
    { offset: 1, color: 'rgba(255, 159, 67, 0.04)' }
  ]
}

const TRAINING_ENROLL_LINE = '#40e0d0'
const TRAINING_ENROLL_AREA = {
  type: 'linear',
  x: 0,
  y: 0,
  x2: 0,
  y2: 1,
  colorStops: [
    { offset: 0, color: 'rgba(64, 224, 208, 0.5)' },
    { offset: 1, color: 'rgba(64, 224, 208, 0.04)' }
  ]
}

const TRAINING_GRID = { left: 36, right: 36, top: 30, bottom: 6, containLabel: true }
const TRAINING_SPLIT_LINE = {
  lineStyle: { color: 'rgba(120, 140, 160, 0.28)', type: 'dashed' }
}

/**
 * 人均收入（双折线）：perCapitaIncomeTrend[]
 * 项含 statYear / ruralDisposableIncome / povertyNetIncome，单位：元
 */
export function buildPerCapitaIncomeTrendOption(trend) {
  if (!trend?.length) {
    return emptyOption()
  }
  const years = trend.map((item) => String(item.statYear ?? ''))
  const rural = trend.map((item) =>
    pickNumber(item, ['ruralDisposableIncome', 'rural_disposable_income'])
  )
  const poverty = trend.map((item) =>
    pickNumber(item, ['povertyNetIncome', 'poverty_net_income'])
  )
  if (!rural.some((v) => v > 0) && !poverty.some((v) => v > 0)) {
    return emptyOption()
  }
  return {
    color: ['#3ecf9a', '#e0b84a'],
    tooltip: {
      trigger: 'axis',
      formatter: (params) => {
        if (!Array.isArray(params) || !params.length) {
          return ''
        }
        const title = `${params[0].axisValue}年`
        const lines = params.map((p) => `${p.marker}${p.seriesName} ${p.value ?? 0} 元`)
        return `${title}<br/>${lines.join('<br/>')}`
      }
    },
    legend: {
      top: 2,
      left: 'center',
      itemWidth: 14,
      itemHeight: 4,
      textStyle: { color: '#e8eef5', fontSize: 10 }
    },
    grid: { left: 12, right: 12, top: 32, bottom: 6, containLabel: true },
    xAxis: {
      type: 'category',
      data: years,
      boundaryGap: false,
      axisLabel: { color: '#9fb0c3', fontSize: 10 },
      axisLine: { lineStyle: { color: 'rgba(150, 170, 190, 0.45)' } },
      axisTick: { show: false }
    },
    yAxis: {
      type: 'value',
      name: '元',
      nameTextStyle: { color: '#9fb0c3', fontSize: 10 },
      axisLabel: AXIS_LABEL,
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: TRAINING_SPLIT_LINE
    },
    series: [
      {
        name: '农村居民人均可支配收入',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 5,
        lineStyle: { width: 2, color: '#3ecf9a' },
        itemStyle: { color: '#3ecf9a' },
        data: rural
      },
      {
        name: '脱贫人口人均纯收入',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 5,
        lineStyle: { width: 2, color: '#e0b84a' },
        itemStyle: { color: '#e0b84a' },
        data: poverty
      }
    ]
  }
}

/** 实战培训报名趋势（双面积折线，滚动 12 月） */
export function buildTrainingOption(trainingTrend) {
  if (!trainingTrend?.hasTrainingData) {
    return emptyOption('暂无培训数据')
  }
  const monthly = trainingTrend.monthly || []
  if (!monthly.length) {
    return emptyOption('暂无培训数据')
  }
  const axis = buildRollingAxis(monthly)
  return {
    tooltip: {
      trigger: 'axis',
      formatter: (params) => {
        if (!Array.isArray(params) || !params.length) {
          return ''
        }
        const title = axis.titleAt(params[0].dataIndex)
        const lines = params.map((p) => {
          const unit = p.seriesName === '活动数' ? '个' : '人'
          return `${p.marker}${p.seriesName} ${p.value ?? 0} ${unit}`
        })
        return `${title}<br/>${lines.join('<br/>')}`
      }
    },
    legend: {
      top: 4,
      left: 'center',
      itemWidth: 14,
      itemHeight: 4,
      textStyle: { color: '#e8eef5', fontSize: 10 }
    },
    grid: TRAINING_GRID,
    xAxis: {
      type: 'category',
      data: axis.categories,
      axisLabel: { ...MONTH_AXIS_LABEL, interval: 0, color: '#e8eef5' },
      axisLine: { lineStyle: { color: 'rgba(150, 170, 190, 0.45)' } },
      axisTick: { show: false }
    },
    yAxis: [
      {
        type: 'value',
        name: '个',
        nameTextStyle: { color: '#9fb0c3', fontSize: 10 },
        minInterval: 1,
        axisLabel: { ...AXIS_LABEL, color: '#9fb0c3' },
        axisLine: { show: false },
        axisTick: { show: false },
        splitLine: TRAINING_SPLIT_LINE
      },
      {
        type: 'value',
        name: '人',
        nameTextStyle: { color: '#9fb0c3', fontSize: 10 },
        minInterval: 1,
        axisLabel: { ...AXIS_LABEL, color: '#9fb0c3' },
        axisLine: { show: false },
        axisTick: { show: false },
        splitLine: { show: false }
      }
    ],
    series: [
      {
        name: '活动数',
        type: 'line',
        smooth: true,
        symbol: 'none',
        yAxisIndex: 0,
        lineStyle: {
          color: TRAINING_ACTIVITY_LINE,
          width: 2,
          shadowColor: 'rgba(255, 159, 67, 0.65)',
          shadowBlur: 10
        },
        areaStyle: { color: TRAINING_ACTIVITY_AREA },
        data: rollingSeries(monthly, 'activityCount', ['activity_count'])
      },
      {
        name: '报名人数',
        type: 'line',
        yAxisIndex: 1,
        smooth: true,
        symbol: 'none',
        lineStyle: {
          color: TRAINING_ENROLL_LINE,
          width: 2,
          shadowColor: 'rgba(64, 224, 208, 0.65)',
          shadowBlur: 10
        },
        areaStyle: { color: TRAINING_ENROLL_AREA },
        data: rollingSeries(monthly, 'enrolledCount', ['enrolled_count'])
      }
    ]
  }
}
