import classifiedDataRaw from "./yakIndustryClassifiedData.json?raw"
import familyPastureDataRaw from "./familyPastureData.json?raw"
import artificialGrasslandSummaryRaw from "./artificialGrasslandSummary.json?raw"
import artificialGrasslandBusinessSummaryRaw from "./artificialGrasslandBusinessSummary.json?raw"
import xiangfaBreedingBaseImage from "@/assets/images/yak-industry/xiangfa-breeding-base.png"
import {
  estimatedStock,
  grasslandYakRows,
  homeCore,
  townRecognitionRows,
} from "@/views/gdMap/livestockData"
import { hongyuanTownshipLabelPoints } from "@/config/townshipBoundaries"
import { HONGYUAN_BOUNDS } from "@/config/layers"

export const industryStageDefs = [
  { key: "family-pasture", name: "家庭生态牧场", color: "#30dcff", unit: "处", metricLabel: "生态牧场", width: 126 },
  { key: "artificial-grassland", name: "人工种草", color: "#19ffc6", unit: "万亩", metricLabel: "种草面积", width: 112 },
  { key: "scale-breeding", name: "规模化养殖基地", color: "#46e7ff", unit: "个", metricLabel: "基地", width: 132 },
  { key: "breeding-selection", name: "选育/扩繁基地", color: "#7aefff", unit: "个", metricLabel: "基地", width: 132 },
  { key: "forage-storage", name: "防灾减灾", subName: "饲草储备库", color: "#25cbe8", unit: "吨", metricLabel: "库容", width: 126 },
  { key: "milk-source-station", name: "奶源站", color: "#5cdfff", unit: "个", metricLabel: "站点", width: 112 },
  { key: "slaughter-processing", name: "屠宰与加工", color: "#1fafd2", unit: "万元", metricLabel: "产值", width: 112 },
  { key: "farm-equipment", name: "农机装备", color: "#30dcff", unit: "个", metricLabel: "装备", width: 112 },
  { key: "forage-trade", name: "牧草交易", color: "#19ffc6", unit: "个", metricLabel: "点位", width: 112 },
  { key: "social-service", name: "社会化服务", subName: "金融/疫病/保险/培训", color: "#8aefff", unit: "个", metricLabel: "主体", width: 132 },
]

const townNames = grasslandYakRows.map((item) => item.zoneName)
const townCenterByName = new Map(hongyuanTownshipLabelPoints.map((item) => [item.name, item.center]))
const classifiedData = JSON.parse(classifiedDataRaw)
const familyPastureDataset = JSON.parse(familyPastureDataRaw)
const artificialGrasslandSummary = JSON.parse(artificialGrasslandSummaryRaw)
const artificialGrasslandBusinessSummary = JSON.parse(artificialGrasslandBusinessSummaryRaw)
const categoryList = classifiedData.categories || []
const categoryMap = new Map(categoryList.map((item) => [item.categoryCode, item]))
const familyPastureRecords = (familyPastureDataset.records || []).map((item) => ({
  ...item,
  areaName: item.town,
  address: item.village,
  categoryCode: "YC-FAMILY-PASTURE",
  categoryName: "家庭生态牧场",
  stageKey: "family-pasture",
  stageName: "家庭生态牧场",
}))
const nonBusinessNames = new Set([
  "企业全称",
  "主体全称",
  "畜牧工作站",
  "规划建设股",
  "执法大队",
  "疫控中心",
  "科教股",
  "科技股",
  "乡村振兴股",
  "农产品检测站",
  "数据欠缺，请两个股室核定饲草基地数据。",
  "对接相关科研院校收集数据",
])
const nonBusinessCategoryCodes = new Set(["YC-GRASSLAND-RESOURCE", "YC-CXPT-OTHER-BASE"])
const nonBusinessNamePatterns = [/^林草局数据-\d+$/, /^(技术培训|金融服务网点|保险服务网点)-\d+$/]
const unrelatedYakChainNamePatterns = [/蔬菜/, /金针菇/, /植物园/, /污水/, /物联网/, /绵羊/]

const allClassifiedItems = categoryList.flatMap((category) =>
  (category.categoryCode === "YC-FAMILY-PASTURE" ? familyPastureRecords : category.items || []).map((item) => ({
    ...item,
    categoryCode: category.categoryCode,
    categoryName: category.categoryName,
    stageKey: category.industryStage,
    stageName: getStageDef(category.industryStage)?.name || category.categoryName,
  })),
)
const businessItems = allClassifiedItems.filter(isBusinessItem)
const itemById = new Map(allClassifiedItems.map((item) => [String(item.id), item]))

const familyPastureItems = categoryItems("YC-FAMILY-PASTURE")
const breedingStockItems = categoryItems(["YC-BREEDING-STOCK", "YC-CXPT-BREEDING-STOCK-BASE"])
const forageBaseItems = categoryItems(["YC-FORAGE-BASE", "YC-CXPT-FORAGE-BASE", "YC-CXPT-GRASS-SEED-BASE"])
const forageStorageItems = categoryItems("YC-DISASTER-FORAGE-STORAGE")
const processingItems = categoryItems("YC-PROCESSING-PLANT")
const slaughterItems = categoryItems("YC-SLAUGHTERHOUSE")
const farmEquipmentItems = categoryItems("YC-FARM-EQUIPMENT")
const diseaseControlItems = categoryItems("YC-DISEASE-CONTROL")
const trainingItems = categoryItems("YC-TECH-TRAINING")
const financeItems = categoryItems("YC-SERVICE-FINANCE")
const insuranceItems = categoryItems("YC-SERVICE-INSURANCE")

const familyPastureTotal = countBusinessItems(familyPastureItems)
const familyPastureGreenhouseArea = sumBy(familyPastureItems, (item) => metricValue(item, ["标准化暖棚 (㎡)"]))
const familyPastureManagementArea = sumBy(familyPastureItems, (item) => metricValue(item, ["管理用房 (㎡)"]))
const familyPastureFodderArea = sumBy(familyPastureItems, (item) => metricValue(item, ["饲草料库 (㎡)"]))
const familyPastureActivityArea = sumBy(familyPastureItems, (item) => metricValue(item, ["活动场地及通道 (㎡)"]))
const forageBaseTotal = countBusinessItems(forageBaseItems)
const forageStorageTotal = countBusinessItems(forageStorageItems)
const breedingStockTotal = countBusinessItems(breedingStockItems)
const breedingStockDesignStock = sumBy(breedingStockItems, (item) => metricValue(item, ["设计存栏量 (头)"]))
const processingTotal = countBusinessItems(processingItems)
const slaughterTotal = countBusinessItems(slaughterItems)
const farmEquipmentTotal = countBusinessItems(farmEquipmentItems)
const diseaseControlTotal = countBusinessItems(diseaseControlItems)
const trainingTotal = countBusinessItems(trainingItems)
const financeTotal = countBusinessItems(financeItems)
const insuranceTotal = countBusinessItems(insuranceItems)
const businessCategoryTotal = categoryList.filter((category) => categoryItems(category.categoryCode).some(isBusinessItem)).length
const sourceItemTotal = businessItems.length
const coveredTownTotal = new Set(businessItems.map(normalizeTown).filter(Boolean)).size || townNames.length
const equipmentTotal = Math.max(farmEquipmentTotal, townRecognitionRows.reduce((sum, item) => sum + Number(item.devices || 0), 0))

const forageAreaMu = sumBy(forageBaseItems, (item) => metricValue(item, ["种植面积 (亩)", "acreage"]) || parseNumber(item.scale))
const storageCapacity = sumBy(forageStorageItems, (item) => metricValue(item, ["总库容 (吨)"]))
const breedingDesignStock = sumBy(categoryItems("YC-BREEDING-BASE"), (item) => metricValue(item, ["设计存栏量 (头)"]))
const breedingAnnualOutput = sumBy(categoryItems("YC-BREEDING-BASE"), (item) => metricValue(item, ["年出栏量 (头)"]))
const processingOutputValue = sumBy(processingItems, (item) => metricValue(item, ["年产值 (万元)"]))
const processingRawCapacity = sumBy(processingItems, (item) => metricValue(item, ["年加工鲜奶总量 (吨)", "年加工原料肉总量 (吨)"]))
const processingDrivenHouseholds = sumBy(processingItems, (item) => metricValue(item, ["带动本地农户数"]))
const slaughterOutputValue = sumBy(slaughterItems, (item) => metricValue(item, ["年总产值 (万元)"]))
const slaughterAnnualHeads = sumBy(slaughterItems, (item) => metricValue(item, ["年屠宰总量 (头)"]))
const slaughterColdCapacity = sumBy(slaughterItems, (item) => metricValue(item, ["冷冻库容量 (吨)"]))
const industryOutputValue = processingOutputValue + slaughterOutputValue
const financeMaxLoan = maxByValue(financeItems, (item) => metricValue(item, ["最高单户贷款额度 (万元)"]))
const financeMaxTownCoverage = maxByValue(financeItems, (item) => metricValue(item, ["服务覆盖乡镇数"]))
const insuranceMaxTownCoverage = maxByValue(insuranceItems, (item) => metricValue(item, ["服务覆盖乡镇数"]))
const trainingSessionCount = sumBy(trainingItems, (item) => metricValue(item, ["年培训场次"]))
const trainingPersonCount = sumBy(trainingItems, (item) => metricValue(item, ["年培训人次"]))
const breedingBaseItems = categoryItems("YC-BREEDING-BASE")
const scaleBreedingCategoryCodes = new Set(["YC-BREEDING-BASE"])

// Leadership-facing profiles use the supplied project introductions; the overall
// stock and output totals still come from the existing base list above.
export const featuredBreedingBaseProfiles = [
  {
    key: "longri-2025",
    aliases: ["龙日坝标准化养殖基地 (2025)"],
    name: "龙日坝标准化养殖基地",
    town: "龙日镇",
    village: "龙日坝村",
    operator: "红原县高原犇犇农副产品有限公司",
    tag: "标准化育肥示范",
    projectInvestment: 5118,
    summary: "以牦牛育肥为主，联动科研机构和饲料企业开展标准化育肥。",
    facts: [
      { label: "建设规模", value: "30,685㎡", note: "规划总建筑面积" },
      { label: "项目投资", value: "5,118万元", note: "重点项目建设" },
      { label: "示范带动", value: "500户", note: "牧民增收" },
    ],
    highlights: ["科研协作", "补饲精料", "育肥增效"],
  },
  {
    key: "seyong",
    aliases: ["瓦切镇标准化色永村养殖基地"],
    name: "色永村标准化养殖基地",
    town: "瓦切镇",
    village: "色永村",
    operator: "红原县高原犇犇农副产品有限公司",
    tag: "设施育肥示范",
    projectInvestment: 1566,
    summary: "依托双育肥舍开展集中育肥，形成标准化养殖和补饲配套。",
    facts: [
      { label: "建设规模", value: "6,651㎡", note: "规划总建筑面积" },
      { label: "项目投资", value: "1,566万元", note: "基地建设" },
      { label: "示范带动", value: "100户", note: "牧民增收" },
    ],
    highlights: ["双育肥舍", "集中育肥", "标准化配套"],
  },
  {
    key: "dae",
    aliases: ["瓦切镇达俄村标准化养殖基地", "瓦切镇达峨村标准化养殖基地"],
    name: "达峨村标准化养殖基地",
    town: "瓦切镇",
    village: "达峨村",
    operator: "红原县雅卓阳养殖农民专业合作社",
    tag: "联牧联营示范",
    projectInvestment: 997,
    summary: "以联牧联营组织资源，推进分区放牧、分群饲养和专业化管理。",
    facts: [
      { label: "项目投资", value: "997万元", note: "基地建设" },
      { label: "优质草场", value: "8,800亩", note: "养殖基础" },
      { label: "增收成效", value: "约6万元", note: "社员户均增收" },
    ],
    highlights: ["联牧联营", "分群饲养", "四季均衡出栏"],
  },
  {
    key: "xiangfa",
    aliases: ["邛溪镇麻萨阳德村标准化养殖基地", "邛溪镇麻色阳德村标准化养殖基地", "祥发牧业综合养殖基地"],
    name: "祥发牧业综合养殖基地",
    town: "邛溪镇",
    village: "麻色阳德村",
    operator: "红原县祥发牧业发展有限责任公司",
    tag: "联农带农示范",
    projectInvestment: 515,
    summary: "以“4218”标准化养殖和联农带农模式，提升育肥效益与产业带动能力。",
    image: xiangfaBreedingBaseImage,
    facts: [
      { label: "项目投资", value: "515万元", note: "项目建设" },
      { label: "建设面积", value: "7,517㎡", note: "建筑面积" },
      { label: "养殖模式", value: "4218", note: "标准化养殖" },
    ],
    highlights: ["标准化养殖", "联农带农", "集中育肥"],
  },
]

const forageGrassTypeRows = buildGrassTypeRows([...forageBaseItems, ...forageStorageItems])
const artificialGrasslandBusinessMetrics = artificialGrasslandBusinessSummary.summary || {}
const artificialGrasslandBusinessProjectRows = artificialGrasslandBusinessSummary.projectRows || []
const artificialGrasslandYearRows = artificialGrasslandBusinessSummary.yearRows || []
const artificialGrasslandTypeRows = artificialGrasslandBusinessSummary.typeRows || []
const artificialGrasslandOperationRows = artificialGrasslandBusinessSummary.operationRows || []
const artificialGrasslandDisturbanceRows = artificialGrasslandBusinessSummary.disturbanceRows || []
const artificialGrasslandTownRows = [...(artificialGrasslandBusinessSummary.townRows || [])].sort(sortByValue)
const artificialGrasslandInvestmentRows = artificialGrasslandBusinessSummary.investmentRows || []
const artificialGrasslandPlotRows = artificialGrasslandSummary.plotRows || []
const processingChainRows = buildProcessingChainRows()
const serviceTypeRows = buildServiceTypeRows()
const equipmentDeviceRows = townRecognitionRows
  .map((item) => ({
    key: item.name,
    name: item.name,
    value: Number(item.devices || 0),
    unit: "套",
    extra: `${formatNumber(item.count)}头识别样本`,
  }))
  .filter((item) => item.value > 0)
  .sort(sortByValue)
const equipmentRecognitionRows = townRecognitionRows
  .map((item) => ({
    key: item.name,
    name: item.name,
    value: Number(item.count || 0),
    unit: "头",
    extra: `${formatNumber(item.devices)}套设备`,
  }))
  .filter((item) => item.value > 0)
  .sort(sortByValue)
const farmEquipmentPointRows = buildFarmEquipmentPointRows()
const grasslandResourceWanMu = round(homeCore.grasslandArea / 10000, 2)

export const industryDatasetGeneratedAt = classifiedData.generatedAt || ""
export const supportPointRows = forageStorageItems.map(toLegacyPointRow)
export const processingPointRows = [...processingItems, ...slaughterItems].map(toLegacyPointRow)
export const industryPointRows = businessItems.map(toLegacyPointRow)
export const industryChainListRows = businessItems
  .map(toIndustryChainListRow)
  .sort((a, b) => Number(b.canLocate) - Number(a.canLocate) || a.stageOrder - b.stageOrder || String(a.name).localeCompare(String(b.name), "zh-CN"))

export function getFeaturedBreedingBaseRows() {
  return featuredBreedingBaseProfiles.map((profile) => {
    const point = industryChainListRows.find((row) => profile.aliases.includes(row.fullName))
    return {
      ...profile,
      point: point ? { ...point, featuredBaseKey: profile.key } : null,
    }
  })
}

export function getFeaturedBreedingBaseProfile(point = {}) {
  const featuredBaseKey = String(point.featuredBaseKey || "").trim()
  if (featuredBaseKey) {
    return featuredBreedingBaseProfiles.find((profile) => profile.key === featuredBaseKey) || null
  }
  const names = [point.name, point.fullName].filter(Boolean).map((item) => String(item))
  return featuredBreedingBaseProfiles.find((profile) =>
    profile.aliases.some((alias) => names.some((name) => name === alias || name.includes(alias) || alias.includes(name))),
  ) || null
}

const industryMapPointTotal = industryStageDefs.reduce((sum, stage) => sum + stagePointCount(stage.key), 0)
const pointCoveredTownTotal = new Set(industryStageDefs.flatMap((stage) => getStagePointListRows(stage.key).map((row) => row.town)).filter(Boolean)).size || townNames.length

export const industryTopStats = [
  { zh: "产业点位", name: "产业点位", value: industryMapPointTotal, unit: "个" },
  { zh: "产业产值", name: "产业产值", value: round(industryOutputValue, 1), unit: "万元", decimals: 1 },
  { zh: "饲草库容", name: "饲草库容", value: storageCapacity, unit: "吨" },
  { zh: "覆盖乡镇", name: "覆盖乡镇", value: pointCoveredTownTotal, unit: "个" },
]

export function getStageTopStats(stageKey) {
  const fallbackRow = getStageRow(stageKey)
  const scaleBreedingSummary = getScaleBreedingSummary()
  const stageStats = {
    "family-pasture": [
      { zh: "家庭生态牧场", name: "家庭生态牧场", value: familyPastureTotal, unit: "处", icon: "town" },
      { zh: "标准化暖棚", name: "标准化暖棚", value: familyPastureGreenhouseArea, unit: "㎡", icon: "area" },
      { zh: "饲草料库", name: "饲草料库", value: familyPastureFodderArea, unit: "㎡", icon: "stack" },
      { zh: "活动场地", name: "活动场地", value: familyPastureActivityArea, unit: "㎡", icon: "project" },
    ],
    "artificial-grassland": [
      {
        zh: "实测种草面积",
        name: "实测种草面积",
        value: round(Number(artificialGrasslandBusinessMetrics.actualAreaMu || 0) / 10000, 2),
        unit: "万亩",
        icon: "area",
      },
      { zh: "建设项目", name: "建设项目", value: artificialGrasslandBusinessMetrics.projectCount || 0, unit: "项", icon: "project" },
      { zh: "覆盖乡镇", name: "覆盖乡镇", value: artificialGrasslandBusinessMetrics.coveredTownCount || 0, unit: "个", icon: "town" },
      {
        zh: "项目投资",
        name: "项目投资",
        value: artificialGrasslandBusinessMetrics.investmentWanYuan || 0,
        unit: "万元",
        icon: "certificate",
      },
    ],
    "scale-breeding": [
      { zh: "养殖基地", name: "养殖基地", value: scaleBreedingSummary.baseCount, unit: "个" },
      { zh: "设计存栏", name: "设计存栏", value: scaleBreedingSummary.designStock, unit: "头" },
      { zh: "年出栏", name: "年出栏", value: scaleBreedingSummary.annualOutput, unit: "头" },
      { zh: "覆盖乡镇", name: "覆盖乡镇", value: scaleBreedingSummary.townCount, unit: "个" },
    ],
    "breeding-selection": [
      { zh: "选育/扩繁基地", name: "选育/扩繁基地", value: breedingStockTotal, unit: "个" },
      { zh: "设计存栏", name: "设计存栏", value: breedingStockDesignStock, unit: "头" },
      { zh: "覆盖乡镇", name: "覆盖乡镇", value: uniqueCount(breedingStockItems, normalizeTown), unit: "个" },
      { zh: "育种等级", name: "育种等级", value: breedingLevelRows.length, unit: "类" },
    ],
    "forage-storage": [
      { zh: "储备库", name: "储备库", value: forageStorageTotal, unit: "个" },
      { zh: "总库容", name: "总库容", value: storageCapacity, unit: "吨" },
      { zh: "覆盖乡镇", name: "覆盖乡镇", value: uniqueCount(forageStorageItems, normalizeTown), unit: "个" },
      { zh: "草种类型", name: "草种类型", value: forageGrassTypeRows.length, unit: "类" },
    ],
    "milk-source-station": [
      { zh: "奶源站", name: "奶源站", value: 0, unit: "个" },
      { zh: "覆盖乡镇", name: "覆盖乡镇", value: 0, unit: "个" },
      { zh: "年收奶量", name: "年收奶量", value: 0, unit: "吨" },
      { zh: "建档主体", name: "建档主体", value: 0, unit: "家" },
    ],
    "slaughter-processing": [
      { zh: "加工屠宰点位", name: "加工屠宰点位", value: stagePointCount("slaughter-processing"), unit: "个" },
      { zh: "产业产值", name: "产业产值", value: round(industryOutputValue, 1), unit: "万元", decimals: 1 },
      { zh: "年屠宰量", name: "年屠宰量", value: slaughterAnnualHeads, unit: "头" },
      { zh: "带动农户", name: "带动农户", value: processingDrivenHouseholds, unit: "户" },
    ],
    "farm-equipment": [
      { zh: "监测点位", name: "监测点位", value: stagePointCount("farm-equipment"), unit: "个" },
      { zh: "识别设备", name: "识别设备", value: townRecognitionRows.reduce((sum, item) => sum + Number(item.devices || 0), 0), unit: "套" },
      { zh: "乡镇样本", name: "乡镇样本", value: townRecognitionRows.length, unit: "个" },
      { zh: "识别样本", name: "识别样本", value: townRecognitionRows.reduce((sum, item) => sum + Number(item.count || 0), 0), unit: "头" },
    ],
    "forage-trade": [
      { zh: "交易点位", name: "交易点位", value: 0, unit: "个" },
      { zh: "覆盖乡镇", name: "覆盖乡镇", value: 0, unit: "个" },
      { zh: "交易草量", name: "交易草量", value: 0, unit: "吨" },
      { zh: "建档主体", name: "建档主体", value: 0, unit: "家" },
    ],
    "social-service": [
      { zh: "服务点位", name: "服务点位", value: stagePointCount("social-service"), unit: "个" },
      { zh: "最高授信", name: "最高授信", value: financeMaxLoan, unit: "万元" },
      { zh: "培训人次", name: "培训人次", value: trainingPersonCount, unit: "人次" },
      { zh: "服务类型", name: "服务类型", value: serviceTypeRows.length, unit: "类" },
    ],
  }

  return (stageStats[stageKey] || [
    { zh: fallbackRow.name, name: fallbackRow.name, value: fallbackRow.value, unit: fallbackRow.unit },
    { zh: fallbackRow.capacityUnit ? "能力规模" : "主体规模", name: fallbackRow.capacityUnit ? "能力规模" : "主体规模", value: fallbackRow.capacity, unit: fallbackRow.capacityUnit },
    ...(fallbackRow.fields || []).map((item) => ({
      zh: item.label,
      name: item.label,
      value: item.value,
      unit: item.unit,
    })),
  ]).filter((item) => item.value !== undefined && item.value !== null && item.value !== "").slice(0, 4)
}

export const industryOverviewRows = [
  { key: "chain-subject", name: "产业点位", value: industryMapPointTotal, unit: "个", icon: "town", extra: `${businessCategoryTotal}类主体` },
  { key: "chain-town", name: "镇域覆盖", value: pointCoveredTownTotal, unit: "个", icon: "town", extra: "全链覆盖" },
  { key: "chain-output", name: "产业产值", value: round(industryOutputValue, 1), unit: "万元", icon: "certificate", extra: "加工+屠宰" },
  { key: "chain-forage", name: "饲草库容", value: storageCapacity, unit: "吨", icon: "yield", extra: "防灾储备" },
]

export const stageCompositionRows = industryStageDefs.map((stage) => ({
  key: stage.key,
  name: stage.name,
  value: stagePointCount(stage.key),
  unit: stage.key === "family-pasture" ? "处" : "个",
  color: stage.color,
}))

export const industryStageRows = [
  {
    key: "family-pasture",
    name: "家庭生态牧场",
    value: familyPastureTotal,
    unit: "处",
    capacity: round(familyPastureGreenhouseArea / 10000, 2),
    capacityUnit: "万㎡",
    note: "家庭生态牧场建设及标准化养殖设施",
    fields: [
      { label: "标准化暖棚", value: round(familyPastureGreenhouseArea / 10000, 2), unit: "万㎡" },
      { label: "管理用房", value: round(familyPastureManagementArea / 10000, 2), unit: "万㎡" },
      { label: "饲草料库", value: round(familyPastureFodderArea / 10000, 2), unit: "万㎡" },
    ],
  },
  {
    key: "artificial-grassland",
    name: "人工种草",
    value: round(Number(artificialGrasslandBusinessMetrics.actualAreaMu || 0) / 10000, 2),
    unit: "万亩",
    capacity: artificialGrasslandBusinessMetrics.projectCount || 0,
    capacityUnit: "项",
    note: "实测种草项目建设资料",
    fields: [
      { label: "实测种草面积", value: round(Number(artificialGrasslandBusinessMetrics.actualAreaMu || 0) / 10000, 2), unit: "万亩" },
      { label: "建设项目", value: artificialGrasslandBusinessMetrics.projectCount || 0, unit: "项" },
      { label: "覆盖乡镇", value: artificialGrasslandBusinessMetrics.coveredTownCount || 0, unit: "个" },
    ],
  },
  {
    key: "scale-breeding",
    name: "规模化养殖基地",
    value: getScaleBreedingSummary().baseCount,
    unit: "个",
    capacity: getScaleBreedingSummary().designStock,
    capacityUnit: "头",
    note: "标准化养殖、选育扩繁与种畜基地",
    fields: [
      { label: "设计存栏", value: getScaleBreedingSummary().designStock, unit: "头" },
      { label: "年出栏", value: getScaleBreedingSummary().annualOutput, unit: "头" },
      { label: "覆盖乡镇", value: getScaleBreedingSummary().townCount, unit: "个" },
    ],
  },
  {
    key: "forage-storage",
    name: "防灾减灾饲草储备库",
    value: forageStorageTotal,
    unit: "个",
    capacity: storageCapacity,
    capacityUnit: "吨",
    note: "饲草储备、防灾调拨和草种保障",
    fields: [
      { label: "储备库", value: forageStorageTotal, unit: "个" },
      { label: "总库容", value: storageCapacity, unit: "吨" },
      { label: "覆盖乡镇", value: uniqueCount(forageStorageItems, normalizeTown), unit: "个" },
    ],
  },
  {
    key: "slaughter-processing",
    name: "屠宰与加工",
    value: stagePointCount("slaughter-processing"),
    unit: "个",
    capacity: round(industryOutputValue, 1),
    capacityUnit: "万元",
    note: "乳品加工、肉制品加工与定点屠宰",
    fields: [
      { label: "加工产值", value: processingOutputValue, unit: "万元" },
      { label: "屠宰产值", value: round(slaughterOutputValue, 1), unit: "万元" },
      { label: "年屠宰量", value: slaughterAnnualHeads, unit: "头" },
    ],
  },
  {
    key: "farm-equipment",
    name: "农机装备",
    value: stagePointCount("farm-equipment"),
    unit: "个",
    capacity: equipmentTotal,
    capacityUnit: "套",
    note: "农机服务主体与生产监测设备",
    fields: [
      { label: "监测点位", value: stagePointCount("farm-equipment"), unit: "个" },
      { label: "识别设备", value: townRecognitionRows.reduce((sum, item) => sum + Number(item.devices || 0), 0), unit: "套" },
      { label: "乡镇样本", value: townRecognitionRows.length, unit: "个" },
    ],
  },
  {
    key: "social-service",
    name: "社会化服务",
    value: stagePointCount("social-service"),
    unit: "个",
    capacity: financeMaxLoan,
    capacityUnit: "万元",
    note: "金融、保险、防疫、培训和其他服务网点",
    fields: [
      { label: "金融网点", value: financeTotal, unit: "家" },
      { label: "最高授信", value: financeMaxLoan, unit: "万元" },
      { label: "培训人次", value: trainingPersonCount, unit: "人次" },
    ],
  },
]

export const breedingLevelRows = buildBreedingLevelRows()

export const forageSecurityRows = aggregateRows(forageStorageItems, normalizeTown, (item) => metricValue(item, ["总库容 (吨)"]))
  .map((item) => ({ ...item, unit: "吨", extra: `${item.count}个库点` }))

export const industryValueRows = [
  { key: "milk-processing", name: "乳品加工", value: sumBy(processingItems.filter(isMilkProcessing), (item) => metricValue(item, ["年产值 (万元)"])), unit: "万元", color: "#32dcff" },
  { key: "meat-processing", name: "肉品加工", value: sumBy(processingItems.filter(isMeatProcessing), (item) => metricValue(item, ["年产值 (万元)"])), unit: "万元", color: "#48cfff" },
  { key: "slaughter-output", name: "定点屠宰", value: round(slaughterOutputValue, 1), unit: "万元", color: "#8bf7ff" },
].filter((item) => item.value > 0)

export const processingAbilityRows = [
  { key: "raw-capacity", name: "年加工原料", value: processingRawCapacity, unit: "吨", extra: `${processingItems.filter(isBusinessItem).length}家加工主体` },
  { key: "slaughter-heads", name: "年屠宰总量", value: slaughterAnnualHeads, unit: "头", extra: `${slaughterItems.filter(isBusinessItem).length}家定点屠宰` },
  { key: "farmer-driven", name: "带动本地农户", value: processingDrivenHouseholds, unit: "户", extra: "加工企业申报" },
  { key: "cold-storage", name: "冷冻/冷藏能力", value: slaughterColdCapacity, unit: "吨", extra: "屠宰冷链" },
]

export const serviceCapabilityRows = [
  { key: "finance", name: "金融服务", value: scoreBy(financeMaxTownCoverage, 10), count: financeTotal, unit: "家", extra: `最高${formatNumber(financeMaxLoan)}万元` },
  { key: "insurance", name: "保险服务", value: scoreBy(insuranceMaxTownCoverage, 10), count: insuranceTotal, unit: "家", extra: `覆盖${formatNumber(insuranceMaxTownCoverage)}乡镇` },
  { key: "training", name: "技术培训", value: scoreBy(trainingPersonCount, 200), count: trainingTotal, unit: "家", extra: `${formatNumber(trainingPersonCount)}人次` },
  { key: "disease", name: "疫病防控", value: scoreBy(diseaseControlTotal, 4), count: diseaseControlTotal, unit: "个", extra: "防疫主体" },
  { key: "equipment", name: "农机装备", value: scoreBy(farmEquipmentTotal, 3), count: farmEquipmentTotal, unit: "个", extra: "服务主体" },
]

const familyPastureForageSegments = [
  { key: "cutting", name: "割草地", headerName: "割草地" },
  { key: "storage", name: "储草基地", headerName: "储草基地", valuePrefix: "≥" },
  { key: "netFence", name: "网围栏种草", headerName: "网围栏" },
]

const familyPastureGrassBaseSegments = [
  { key: "cutting", name: "割草地", color: "#37DDF3" },
  { key: "storage", name: "储草基地", color: "#8bf7ff" },
]

function getStageMetricRows(stageKey) {
  return getStageTopStats(stageKey).map((item, index) => ({
    key: item.key || `${stageKey}-metric-${index}`,
    name: item.name || item.zh || `指标${index + 1}`,
    value: item.value,
    unit: item.unit || "",
    extra: item.extra || "",
  }))
}

function getStageSpotlightRows(stageKey) {
  const stage = getStageDef(stageKey)
  const stageRow = industryStageRows.find((item) => item.key === stageKey)
  const metricRows = getStageMetricRows(stageKey)
  const primary = metricRows[0] || {
    key: `${stageKey}-primary`,
    name: stage.name,
    value: 0,
    unit: stage.unit || "",
  }
  const fieldRows = (stageRow?.fields?.length ? stageRow.fields : metricRows.slice(1)).map((item, index) => ({
    key: item.key || `${stageKey}-field-${index}`,
    name: item.label || item.name || `要点${index + 1}`,
    value: item.value,
    unit: item.unit || "",
    extra: item.extra || stageRow?.note || stage.metricLabel || "",
  }))
  return [
    {
      ...primary,
      key: primary.key || `${stageKey}-spotlight-main`,
      name: primary.name || stage.name,
      extra: primary.extra || stageRow?.note || stage.metricLabel || "环节核心能力",
    },
    ...fieldRows,
  ].slice(0, 4)
}

function stageMetricPanel(stageKey) {
  return chartPanel(`${stageKey}-right-metrics`, "环节核心指标", "metric", getStageMetricRows(stageKey))
}

function stageSpotlightPanel(stageKey) {
  return chartPanel(`${stageKey}-right-spotlight`, "建设要点", "spotlight", getStageSpotlightRows(stageKey))
}

function buildStageRightPanels(stageKey, listPanel = industryChainListPanel(stageKey)) {
  return [
    listPanel,
    stageMetricPanel(stageKey),
    stageSpotlightPanel(stageKey),
  ]
}

export function getStagePanelConfig(stageKey) {
  const stage = getStageDef(stageKey)
  const subjectRows = getStageSubjectRows(stageKey)
  const configs = {
    "family-pasture": {
      left: [
        chartPanel(
          "family-town",
          "家庭生态牧场乡镇分布",
          "column",
          getStageCapacityRows(stageKey),
          { variant: "townCompact", scrollable: false, uniformColor: true, fillHeight: true },
        ),
        chartPanel("family-unit", "标准化建设配置", "specGrid", getFamilyPastureUnitRows(), { fillHeight: true }),
        chartPanel(
          "family-forage",
          "乡镇割草地、储草基地面积",
          "stackColumn",
          getFamilyPastureForageRows(),
          {
            fillHeight: true,
            unit: "亩",
            segments: familyPastureGrassBaseSegments,
            sharedScale: true,
            showZero: true,
            showValue: true,
            totalLabel: "汇总面积",
          },
        ),
        chartPanel("family-support-type", "草料配套类型占比", "structure", getFamilyPastureSupportTypeRows(), { fillHeight: true }),
      ],
      right: [
        industryChainListPanel(stageKey),
        chartPanel("family-construction-year", "年度建设节奏", "line", getFamilyPastureConstructionYearRows(), {
          fixedType: true,
        }),
        chartPanel("family-net-fence", "网围栏配套面积", "rank", getFamilyPastureTownSupportRows("netFence"), {
          unit: "亩",
        }),
      ],
    },
    "artificial-grassland": {
      left: [
        chartPanel("grass-town-area", "人工种草乡镇面积", "column", artificialGrasslandTownRows, { variant: "townCompact", scrollable: false, uniformColor: true }),
        chartPanel("grass-year", "年度项目建设面积", "line", artificialGrasslandYearRows, { fixedType: true }),
        chartPanel("grass-type", "建设类型面积", "structure", artificialGrasslandTypeRows),
        chartPanel("grass-operation", "作业方式面积", "bar", artificialGrasslandOperationRows),
      ],
      right: [
        artificialGrasslandBusinessLedgerPanel(),
        chartPanel("grass-investment", "项目投资规模", "rank", artificialGrasslandInvestmentRows),
        chartPanel("grass-disturbance", "施工扰动面积", "split", artificialGrasslandDisturbanceRows),
        chartPanel("grass-project-area", "项目面积明细", "specGrid", getArtificialGrasslandProjectAreaRows()),
      ],
    },
    "scale-breeding": {
      left: [
        chartPanel("breeding-town-count", "乡镇养殖基地分布", "column", getScaleBreedingTownChartRows("baseCount", "个", "养殖基地"), {
          variant: "townCompact",
          scrollable: false,
          axisLabelMode: "short",
          uniformColor: true,
        }),
        chartPanel("breeding-town-stock", "设计存栏规模排名", "bar", getScaleBreedingTownRankRows("designStock", "头", "设计存栏"), {
          variant: "rankBar",
        }),
        chartPanel("breeding-town-output", "年出栏区域贡献", "structure", getScaleBreedingOutputStructureRows()),
        chartPanel("breeding-project-investment", "重点示范项目投入", "rank", getFeaturedBreedingInvestmentRows()),
      ],
      right: [
        ...buildStageRightPanels(stageKey, scaleBreedingLocationListPanel()),
      ],
    },
    "forage-storage": {
      left: [
        chartPanel("storage-town", "库容镇域分布", "column", getStageCapacityRows(stageKey), { variant: "townCompact", scrollable: false }),
        chartPanel("storage-point", "储备库点排名", "bar", getStoragePointRows(), { variant: "rankBar" }),
        chartPanel("storage-grass", "储备草种结构", "structure", forageGrassTypeRows),
        chartPanel("storage-capacity", "库容能力占比", "split", getStageCapacityRows(stageKey).filter((item) => Number(item.value || 0) > 0).slice(0, 7)),
      ],
      right: [
        ...buildStageRightPanels(stageKey),
      ],
    },
    "slaughter-processing": {
      left: [
        chartPanel("processing-value", "产值结构", "donut", industryValueRows, { variant: "ring" }),
        chartPanel("processing-chain", "产能与带动", "structure", processingChainRows),
        chartPanel("processing-heads", "屠宰能力排名", "bar", getSlaughterHeadRows(), { variant: "rankBar" }),
        chartPanel("processing-town", "加工点位乡镇分布", "column", getTownCountRows([...processingItems, ...slaughterItems], "加工/屠宰主体"), { variant: "townCompact", scrollable: false, uniformColor: true }),
      ],
      right: [
        ...buildStageRightPanels(stageKey),
      ],
    },
    "farm-equipment": {
      left: [
        chartPanel("equipment-device", "识别设备分布", "column", completeTownColumnRows(equipmentDeviceRows, { unit: "套", extra: "识别设备" }), { variant: "townCompact", scrollable: false }),
        chartPanel("equipment-recognition", "识别样本排名", "bar", equipmentRecognitionRows, { variant: "rankBar" }),
        chartPanel("equipment-service-town", "农机服务主体分布", "heat", getTownCountRows(farmEquipmentItems, "农机服务主体")),
        chartPanel("equipment-device-structure", "设备投放结构", "structure", equipmentDeviceRows.filter((item) => Number(item.value || 0) > 0).slice(0, 6)),
      ],
      right: [
        ...buildStageRightPanels(stageKey),
      ],
    },
    "social-service": {
      left: [
        chartPanel("service-type", "服务主体结构", "donut", serviceTypeRows, { variant: "ring" }),
        chartPanel("service-town", "服务镇域分布", "column", getTownCountRows([...diseaseControlItems, ...trainingItems, ...financeItems, ...insuranceItems], "服务主体"), { variant: "townCompact", scrollable: false }),
        chartPanel("service-training-town", "培训人次分布", "bar", getTownMetricRows(trainingItems, ["年培训人次"], { unit: "人次", extra: "技术培训" }), { variant: "rankBar" }),
        chartPanel("service-training", "培训服务能力", "line", getTrainingRows()),
      ],
      right: [
        ...buildStageRightPanels(stageKey),
      ],
    },
  }

  const fallback = {
    left: [
      chartPanel(`${stage.key}-rank`, `${stage.metricLabel}分布`, "column", getStageCapacityRows(stageKey), { variant: "townCompact", scrollable: false }),
      chartPanel(`${stage.key}-subject`, "主体结构", "structure", subjectRows),
      chartPanel(`${stage.key}-town`, "镇域覆盖分布", "heat", completeTownColumnRows(getStageTownRows(stageKey), { unit: "个", extra: "镇域覆盖" })),
      chartPanel(`${stage.key}-capacity`, "能力规模分布", "split", getStageCapacityRows(stageKey).slice(0, 7)),
    ],
    right: [
      ...buildStageRightPanels(stageKey),
    ],
  }

  return configs[stageKey] || fallback
}

export const industryFinancialRows = [
  { key: "support-capacity", name: "饲草储备能力", value: storageCapacity, unit: "吨", extra: `${forageStorageTotal}个库点` },
  { key: "processing-capacity", name: "加工原料规模", value: processingRawCapacity, unit: "吨", extra: `${processingItems.filter(isBusinessItem).length}家加工主体` },
  { key: "processing-output", name: "加工屠宰产值", value: round(industryOutputValue, 1), unit: "万元", extra: "加工+屠宰" },
  { key: "finance-credit", name: "最高单户授信", value: financeMaxLoan, unit: "万元", extra: "金融服务" },
]

export function getStageDef(key) {
  return industryStageDefs.find((item) => item.key === key) || industryStageDefs[0]
}

export function getStageRow(key) {
  return industryStageRows.find((item) => item.key === key) || industryStageRows[0]
}

export function getStageInsightRows(stageKey) {
  return getStageRow(stageKey).fields || []
}

export function getStageCapacityRows(stageKey) {
  if (stageKey === "family-pasture") {
    return completeTownColumnRows(getFamilyPastureTownMapRows(), { unit: "处", extra: "家庭生态牧场" })
  }
  if (stageKey === "artificial-grassland") {
    return artificialGrasslandTownRows
  }
  if (stageKey === "breeding-selection") {
    const rows = aggregateRows(breedingStockItems, normalizeTown, () => 1)
      .map((item) => ({ ...item, unit: "个", extra: "选育/扩繁基地" }))
    return completeTownColumnRows(rows, { unit: "个", extra: "选育/扩繁基地" })
  }
  if (stageKey === "scale-breeding") {
    const rows = aggregateRows(categoryItems("YC-BREEDING-BASE"), normalizeTown, (item) => metricValue(item, ["设计存栏量 (头)"]))
      .map((item) => ({ ...item, unit: "头", extra: `${item.count}个基地` }))
    return completeTownColumnRows(rows, { unit: "头", extra: "养殖基地" })
  }
  if (stageKey === "forage-storage") {
    return completeTownColumnRows(forageSecurityRows, { unit: "吨", extra: "饲草储备" })
  }
  if (stageKey === "slaughter-processing") {
    return [...processingItems, ...slaughterItems]
      .filter(isBusinessItem)
      .map((item) => ({
        key: item.id,
        name: compactName(item.name),
        value: metricValue(item, ["年产值 (万元)", "年总产值 (万元)"]),
        unit: "万元",
        extra: item.categoryName,
      }))
      .filter((item) => item.value > 0)
      .sort(sortByValue)
      .slice(0, 7)
  }
  if (stageKey === "farm-equipment") {
    return farmEquipmentItems.filter(isBusinessItem).map((item) => ({
      key: item.id,
      name: compactName(item.name),
      value: 1,
      unit: "个",
      extra: item.attributes?.简称 || "农机服务",
    }))
  }
  if (stageKey === "social-service") {
    return [
      { key: "finance", name: "金融服务网点", value: financeTotal, unit: "家", extra: `最高${formatNumber(financeMaxLoan)}万元` },
      { key: "insurance", name: "保险服务网点", value: insuranceTotal, unit: "家", extra: `覆盖${formatNumber(insuranceMaxTownCoverage)}乡镇` },
      { key: "training", name: "技术培训机构", value: trainingTotal, unit: "家", extra: `${formatNumber(trainingSessionCount)}场` },
      { key: "disease", name: "疫病防控主体", value: diseaseControlTotal, unit: "个", extra: "防疫服务" },
    ]
  }
  return []
}

function getScaleBreedingTownDistributionRows() {
  const byTown = new Map(townNames.map((town, index) => [town, {
    key: town,
    name: town,
    sourceIndex: index,
    segments: {
      baseCount: 0,
      designStock: 0,
      annualOutput: 0,
    },
  }]))

  getScaleBreedingLocationRows().forEach((item) => {
    const row = byTown.get(item.town)
    if (!row) return
    row.segments.baseCount += 1
    row.segments.designStock += Number(item.numericValue || item.value || 0)
    row.segments.annualOutput += Number(item.annualOutput || 0)
  })

  return townNames.map((town) => byTown.get(town))
}

function getScaleBreedingTownChartRows(segmentKey, unit, extra) {
  return getScaleBreedingTownDistributionRows().map((item, index) => {
    const rawValue = Number(item.segments?.[segmentKey] || 0)
    const hasValue = rawValue > 0
    return {
      key: `${item.key}-${segmentKey}`,
      name: item.name,
      rawValue,
      value: hasValue ? rawValue : 0.001,
      displayValue: hasValue ? rawValue : "0",
      unit,
      extra,
      zero: !hasValue,
      sourceIndex: index,
    }
  })
}

function getScaleBreedingTownRankRows(segmentKey, unit, extra) {
  return getScaleBreedingTownChartRows(segmentKey, unit, extra)
    .filter((item) => item.rawValue > 0)
    .map((item) => ({
      ...item,
      value: item.rawValue,
      displayValue: item.rawValue,
    }))
    .sort(sortByValue)
}

function getScaleBreedingOutputStructureRows() {
  const rows = getScaleBreedingTownRankRows("annualOutput", "头", "年出栏")
  const total = rows.reduce((sum, item) => sum + Number(item.value || 0), 0)
  if (!total) return []

  const primaryRows = rows.slice(0, 3)
  const remainingRows = rows.slice(3)
  const displayRows = remainingRows.length
    ? [
        ...primaryRows,
        {
          key: "other-towns-annual-output",
          name: "其他乡镇",
          value: remainingRows.reduce((sum, item) => sum + Number(item.value || 0), 0),
          unit: "头",
        },
      ]
    : primaryRows

  return displayRows.map((item) => ({
    ...item,
    extra: `占比 ${formatNumber((Number(item.value || 0) / total) * 100)}%`,
  }))
}

function getFeaturedBreedingInvestmentRows() {
  return featuredBreedingBaseProfiles
    .map((profile) => ({
      key: profile.key,
      name: profile.name
        .replace(/标准化养殖基地/g, "基地")
        .replace(/综合养殖基地/g, "基地"),
      value: Number(profile.projectInvestment || 0),
      unit: "万元",
      extra: `${profile.town} · ${profile.tag}`,
    }))
    .filter((item) => item.value > 0)
    .sort(sortByValue)
}

function getArtificialGrasslandProjectAreaRows() {
  return artificialGrasslandBusinessProjectRows
    .map((project) => ({
      key: project.key,
      name: project.name,
      value: Number(project.actualAreaMu || project.value || 0),
      unit: "亩",
      extra: project.year ? `${project.year}年` : project.category || "实测面积",
    }))
    .filter((item) => item.value > 0)
    .sort(sortByValue)
}

export function getFamilyPastureTownMapRows() {
  const counts = new Map(aggregateRows(familyPastureItems, normalizeTown, () => 1).map((item) => [item.name, item]))
  return townNames.map((town) => {
    const row = counts.get(town)
    return {
      key: town,
      name: town,
      value: Number(row?.value || 0),
      unit: "处",
      extra: "家庭生态牧场",
    }
  })
}

export function getFamilyPastureFacilityRows() {
  return [
    { key: "family-greenhouse", name: "标准化暖棚", value: familyPastureGreenhouseArea, unit: "㎡", icon: "area", extra: `${formatNumber(familyPastureTotal)}处建设台账` },
    { key: "family-management", name: "生产管理用房", value: familyPastureManagementArea, unit: "㎡", icon: "town", extra: "标准化配套" },
    { key: "family-fodder", name: "饲草料库", value: familyPastureFodderArea, unit: "㎡", icon: "stack", extra: "饲草保障配套" },
    { key: "family-activity", name: "活动场地及通道", value: familyPastureActivityArea, unit: "㎡", icon: "yield", extra: "养殖活动配套" },
  ]
}

function getFamilyPastureUnitRows() {
  const groups = new Map()
  familyPastureItems.filter(isBusinessItem).forEach((item) => {
    const greenhouse = metricValue(item, ["标准化暖棚 (㎡)"])
    const management = metricValue(item, ["管理用房 (㎡)"])
    const fodder = metricValue(item, ["饲草料库 (㎡)"])
    const activity = metricValue(item, ["活动场地及通道 (㎡)"])
    const name = `${formatNumber(greenhouse)}㎡暖棚 + ${formatNumber(management)}㎡管理房`
    const key = `${greenhouse}-${management}-${fodder}-${activity}`
    const group = groups.get(key) || {
      key,
      name,
      value: 0,
      unit: "处",
      specs: [
        { label: "饲草料库", value: fodder, unit: "㎡" },
        { label: "活动场地", value: activity, unit: "㎡" },
      ],
    }
    group.value += 1
    groups.set(key, group)
  })
  return [...groups.values()].sort(sortByValue)
}

function getFamilyPastureForageRows() {
  const rowsByTown = new Map(
    townNames.map((town) => [town, {
      key: town,
      name: town,
      unit: "亩",
      segments: { cutting: 0, storage: 0, netFence: 0 },
    }]),
  )
  familyPastureItems.filter(isBusinessItem).forEach((item) => {
    const town = normalizeTown(item)
    const row = rowsByTown.get(town)
    if (!row) return
    const type = item.grassSupportType
    const value = Number(item.grassSupportMu || 0)
    if (!value) return
    if (type === "割草地") row.segments.cutting += value
    if (type === "储草基地") row.segments.storage += value
    if (type === "网围栏种草") row.segments.netFence += value
  })
  return [...rowsByTown.values()]
}

function getFamilyPastureSupportTypeRows() {
  const townRows = getFamilyPastureForageRows()
  return familyPastureForageSegments.map((segment) => {
    const value = townRows.reduce((sum, row) => sum + Number(row.segments?.[segment.key] || 0), 0)
    const coveredTowns = townRows.filter((row) => Number(row.segments?.[segment.key] || 0) > 0).length
    return {
      key: segment.key,
      name: segment.name,
      value,
      unit: "亩",
      extra: `覆盖${coveredTowns}个乡镇`,
    }
  })
}

function getFamilyPastureTownSupportRows(segmentKey = "") {
  return getFamilyPastureForageRows()
    .map((row) => {
      const value = segmentKey
        ? Number(row.segments?.[segmentKey] || 0)
        : Object.values(row.segments || {}).reduce((sum, item) => sum + Number(item || 0), 0)
      return {
        key: row.key,
        name: row.name,
        value,
        unit: "亩",
        extra: segmentKey === "netFence" ? "网围栏种草" : "草料配套",
      }
    })
    .filter((row) => row.value > 0)
    .sort(sortByValue)
}

function getFamilyPastureConstructionYearRows() {
  return aggregateRows(familyPastureItems.filter(isBusinessItem), (item) => String(item.constructionYear || "未标注"), () => 1)
    .map((row) => ({
      ...row,
      name: row.name === "未标注" ? row.name : `${row.name}年`,
      unit: "处",
      extra: "建成牧场",
    }))
    .sort((a, b) => String(a.key).localeCompare(String(b.key), "zh-CN"))
}

export function getStageTownRows(stageKey) {
  return aggregateRows(stageItems(stageKey), normalizeTown, () => 1).map((item) => ({
    ...item,
    unit: "个",
    extra: `${item.count}条`,
  }))
}

export function getStageDetailRows(stageKey) {
  return stageItems(stageKey)
    .filter(isBusinessItem)
    .map(toDetailRow)
    .sort((a, b) => b.numericValue - a.numericValue || a.name.localeCompare(b.name, "zh-CN"))
}

export function getPointExtraRows(point = {}) {
  const item = findClassifiedItem(point)
  if (!item) return []
  const rows = []
  const metrics = item.metrics || {}
  const attrs = item.attributes || {}
  const add = (label, value, unit = "", extra = {}) => {
    if (isBlank(value)) return
    rows.push({ label, value: formatValueWithUnit(value, unit), ...extra })
  }
  if (item.categoryCode === "YC-FAMILY-PASTURE") {
    add("户主", item.owner || attrs["户主"])
    add("建设年份", item.constructionYear, "年")
    add("所在村", item.village)
    add("标准化暖棚", metrics["标准化暖棚 (㎡)"], "㎡")
    add("生产管理用房", metrics["管理用房 (㎡)"], "㎡")
    add("饲草料库", metrics["饲草料库 (㎡)"], "㎡")
    add("活动场地及通道", metrics["活动场地及通道 (㎡)"], "㎡")
    add("草料配套", item.grassSupportText || attrs["草料配套"], "", { wide: true })
    return rows
  }
  add("运营单位", attrs["运营单位"])
  add("育种等级", attrs["育种等级"])
  add("育种方向", attrs["主要育种方向"])
  add("设计存栏", metrics["设计存栏量 (头)"], "头")
  add("年出栏量", metrics["年出栏量 (头)"], "头")
  add("种植面积", metrics["种植面积 (亩)"] || item.scale, item.scale ? "" : "亩")
  add("总库容", metrics["总库容 (吨)"], "吨")
  add("年产值", metrics["年产值 (万元)"] || metrics["年总产值 (万元)"], "万元")
  add("年加工量", metrics["年加工鲜奶总量 (吨)"] || metrics["年加工原料肉总量 (吨)"], "吨")
  add("年屠宰量", metrics["年屠宰总量 (头)"], "头")
  add("服务覆盖", metrics["服务覆盖乡镇数"], "个乡镇")
  add("最高授信", metrics["最高单户贷款额度 (万元)"], "万元")
  add("主要产品", attrs["主要产品"])
  add("主要草种", attrs["主要草种"] || attrs["储备草种"])
  return rows.slice(0, 8)
}

function categoryItems(codes) {
  const codeList = Array.isArray(codes) ? codes : [codes]
  return codeList.flatMap((code) => {
    const category = categoryMap.get(code)
    const items = code === "YC-FAMILY-PASTURE" ? familyPastureRecords : category?.items || []
    return items.map((item) => ({
      ...item,
      categoryCode: category.categoryCode,
      categoryName: category.categoryName,
      stageKey: category.industryStage,
      stageName: getStageDef(category.industryStage)?.name || category.categoryName,
    }))
  })
}

function stageItems(stageKey) {
  if (stageKey === "scale-breeding") return breedingBaseItems.filter(isBusinessItem)
  if (stageKey === "breeding-selection") return breedingStockItems.filter(isBusinessItem)
  if (stageKey === "milk-source-station" || stageKey === "forage-trade") return []
  return businessItems.filter((item) => item.stageKey === stageKey)
}

function stageItemCount(stageKey) {
  return stageItems(stageKey).length
}

function getStagePointListRows(stageKey) {
  if (stageKey === "artificial-grassland") return artificialGrasslandPlotRows
  if (stageKey === "farm-equipment") return farmEquipmentPointRows
  if (stageKey === "scale-breeding") {
    return getScaleBreedingLocationRows()
  }
  if (stageKey === "breeding-selection") {
    return industryChainListRows
      .filter((row) => ["YC-BREEDING-STOCK", "YC-CXPT-BREEDING-STOCK-BASE"].includes(row.categoryCode) && row.canLocate)
      .map((row) => ({ ...row, stageKey, stageName: getStageDef(stageKey).name, stageOrder: industryStageDefs.findIndex((stage) => stage.key === stageKey) }))
  }
  return industryChainListRows.filter((row) => row.stageKey === stageKey && row.canLocate)
}

function stagePointCount(stageKey) {
  if (stageKey === "family-pasture") return familyPastureTotal
  return getStagePointListRows(stageKey).length
}

function buildFarmEquipmentPointRows() {
  return townRecognitionRows
    .map((item, index) => {
      const center = townCenterByName.get(item.name)
      const longitude = Number(center?.[0])
      const latitude = Number(center?.[1])
      if (!isCoordinateInHongyuanBounds(longitude, latitude)) return null
      const key = `YC-FARM-EQUIPMENT-TOWN-${String(index + 1).padStart(3, "0")}`
      const name = `${item.name}农机装备监测点`
      const devices = Number(item.devices || 0)
      const count = Number(item.count || 0)
      return {
        key,
        id: key,
        name,
        fullName: name,
        stageKey: "farm-equipment",
        stageName: getStageDef("farm-equipment").name,
        stageOrder: industryStageDefs.findIndex((stage) => stage.key === "farm-equipment"),
        typeName: "农机装备监测点",
        categoryName: "农机装备监测点",
        town: item.name,
        address: `${item.name}乡镇中心`,
        status: "监测样本",
        value: devices,
        unit: "套",
        numericValue: devices,
        valueText: `${formatNumber(devices)}套`,
        extra: `${formatNumber(count)}头识别样本`,
        longitude,
        latitude,
        locateText: "定位",
        canLocate: true,
        searchText: [name, "农机装备", item.name, `${devices}套`, `${count}头识别样本`].join(" "),
      }
    })
    .filter(Boolean)
    .sort((a, b) => b.numericValue - a.numericValue || String(a.name).localeCompare(String(b.name), "zh-CN"))
}

function isBusinessItem(item = {}) {
  const name = cleanText(item.name)
  const sourceOwner = cleanText(item.attributes?.["序号"])
  if (!name || nonBusinessNames.has(name) || nonBusinessCategoryCodes.has(item.categoryCode)) return false
  if (unrelatedYakChainNamePatterns.some((pattern) => pattern.test(name))) return false
  if (sourceOwner && nonBusinessNames.has(sourceOwner) && !hasBusinessMetric(item)) return false
  if (nonBusinessNamePatterns.some((pattern) => pattern.test(name))) return false
  return true
}

function countBusinessItems(rows = []) {
  return rows.filter(isBusinessItem).length
}

function hasBusinessMetric(item = {}) {
  return Object.values(item.metrics || {}).some((value) => parseNumber(value) > 0)
}

function toLegacyPointRow(item = {}) {
  const value = primaryValue(item)
  return {
    key: String(item.id || item.name),
    name: item.name,
    stageKey: item.stageKey,
    categoryCode: item.categoryCode,
    typeName: item.categoryName,
    categoryName: item.categoryName,
    town: normalizeTown(item),
    address: item.address || item.village || item.areaFullName || "",
    status: item.status || "",
    products: item.attributes?.["主要产品"] || item.attributes?.["主要草种"] || item.attributes?.["储备草种"] || item.attributes?.["主要育种方向"] || "",
    capacity: value,
    capacityUnit: primaryUnit(item),
    outputValue: metricValue(item, ["年产值 (万元)", "年总产值 (万元)"]),
    longitude: item.longitude,
    latitude: item.latitude,
  }
}

function toDetailRow(item = {}) {
  const value = primaryValue(item)
  const unit = primaryUnit(item)
  const town = normalizeTown(item)
  return {
    key: String(item.id || item.name),
    name: compactName(item.name),
    fullName: item.name,
    stageKey: item.stageKey,
    categoryCode: item.categoryCode,
    typeName: item.categoryName,
    categoryName: item.categoryName,
    town: town || "全县",
    address: item.address || item.village || item.areaFullName || "",
    status: item.status || "待完善",
    value,
    unit,
    numericValue: Number(value) || 0,
    valueText: buildPrimaryValueText(item, value, unit),
    extra: buildDetailExtra(item),
    sourceSheet: item.sourceSheet,
  }
}

function toIndustryChainListRow(item = {}) {
  const row = toDetailRow(item)
  const coordinate = getItemCoordinate(item)
  const stage = getStageDef(item.stageKey)
  const fullName = cleanText(item.name)
  const categoryName = cleanText(item.categoryName).replace(/^cxpt/i, "")
  const address = cleanText(item.address || item.village || item.areaFullName || "")
  const attrs = item.attributes || {}
  const metrics = item.metrics || {}
  const searchText = [
    fullName,
    row.name,
    stage?.name,
    categoryName,
    row.town,
    address,
    attrs["简称"],
    attrs["运营单位"],
    attrs["主要产品"],
    attrs["主要草种"],
    attrs["储备草种"],
    attrs["主要育种方向"],
    item.owner,
    item.village,
    item.constructionYear,
    item.facilityBrief,
    item.grassSupportText,
    metrics["主要贷款产品（可多选）"],
    row.valueText,
    row.extra,
    item.sourceSheet,
  ].filter(Boolean).join(" ")
  return {
    ...row,
    name: row.name,
    fullName,
    stageName: stage?.name || row.stageName || "",
    stageOrder: industryStageDefs.findIndex((stageItem) => stageItem.key === item.stageKey),
    categoryName,
    address,
    longitude: coordinate?.longitude ?? "",
    latitude: coordinate?.latitude ?? "",
    locateText: coordinate ? "定位" : "暂无",
    canLocate: Boolean(coordinate),
    owner: item.owner || attrs["户主"] || "",
    village: item.village || "",
    constructionYear: item.constructionYear || "",
    facilityBrief: item.facilityBrief || "",
    facilityDetail: item.facilityDetail || attrs["设施配置"] || "",
    grassSupportText: item.grassSupportText || attrs["草料配套"] || "",
    pointName: item.pointName || "",
    preferCoordinateMatch: item.categoryCode === "YC-FAMILY-PASTURE",
    ledgerName: item.categoryCode === "YC-FAMILY-PASTURE"
      ? item.owner || row.name.replace(/家庭生态牧场$/, "")
      : row.name,
    ledgerLocation: [row.town, item.village].filter(Boolean).join(" · "),
    facilityCompact: item.categoryCode === "YC-FAMILY-PASTURE"
      ? compactFamilyPastureFacility(item.facilityBrief)
      : item.facilityBrief || "",
    annualOutput: item.categoryCode === "YC-BREEDING-BASE"
      ? metricValue(item, ["年出栏量 (头)"])
      : 0,
    searchText,
  }
}

function getScaleBreedingLocationRows() {
  return industryChainListRows.filter((row) => scaleBreedingCategoryCodes.has(row.categoryCode) && row.canLocate)
}

function getScaleBreedingSummary() {
  const rows = getScaleBreedingLocationRows()
  return {
    baseCount: rows.length,
    designStock: rows.reduce((sum, row) => sum + Number(row.numericValue || row.value || 0), 0),
    annualOutput: rows.reduce((sum, row) => sum + Number(row.annualOutput || 0), 0),
    townCount: new Set(rows.map((row) => row.town).filter(Boolean)).size,
  }
}

function compactFamilyPastureFacility(value = "") {
  return String(value)
    .replace(/管理房/g, "管理")
    .replace(/\s*\/\s*/g, " · ")
}

function primaryValue(item = {}) {
  if (item.stageKey === "family-pasture") return 1
  if (item.categoryCode === "YC-BREEDING-STOCK") return item.attributes?.["育种等级"] || "待完善"
  if (item.categoryCode === "YC-CXPT-BREEDING-STOCK-BASE") return parseNumber(item.scale) || 1
  if (item.categoryCode === "YC-BREEDING-BASE") return metricValue(item, ["设计存栏量 (头)"])
  if (item.categoryCode === "YC-FORAGE-BASE") return metricValue(item, ["种植面积 (亩)"])
  if (item.categoryCode === "YC-DISASTER-FORAGE-STORAGE") return metricValue(item, ["总库容 (吨)"])
  if (item.categoryCode === "YC-PROCESSING-PLANT") return metricValue(item, ["年产值 (万元)"]) || metricValue(item, ["年加工鲜奶总量 (吨)", "年加工原料肉总量 (吨)"])
  if (item.categoryCode === "YC-SLAUGHTERHOUSE") return metricValue(item, ["年总产值 (万元)"]) || metricValue(item, ["年屠宰总量 (头)"])
  if (item.categoryCode === "YC-SERVICE-FINANCE") return metricValue(item, ["最高单户贷款额度 (万元)", "服务覆盖乡镇数"])
  if (item.categoryCode === "YC-SERVICE-INSURANCE") return metricValue(item, ["服务覆盖乡镇数"])
  if (item.categoryCode === "YC-TECH-TRAINING") return metricValue(item, ["年培训人次", "年培训场次"])
  if (item.categoryCode?.startsWith("YC-CXPT")) return parseNumber(item.scale) || metricValue(item, ["acreage"])
  return metricValue(item, Object.keys(item.metrics || {})) || 1
}

function primaryUnit(item = {}) {
  if (item.stageKey === "family-pasture") return "处"
  if (item.categoryCode === "YC-BREEDING-STOCK") return ""
  if (item.categoryCode === "YC-BREEDING-BASE") return "头"
  if (["YC-FORAGE-BASE", "YC-CXPT-FORAGE-BASE", "YC-CXPT-GRASS-SEED-BASE", "YC-CXPT-BREEDING-STOCK-BASE"].includes(item.categoryCode)) return "亩"
  if (item.categoryCode === "YC-DISASTER-FORAGE-STORAGE") return "吨"
  if (item.categoryCode === "YC-PROCESSING-PLANT") return "万元"
  if (item.categoryCode === "YC-SLAUGHTERHOUSE") return "万元"
  if (item.categoryCode === "YC-SERVICE-FINANCE") return "万元"
  if (item.categoryCode === "YC-SERVICE-INSURANCE") return "乡镇"
  if (item.categoryCode === "YC-TECH-TRAINING") return "人次"
  if (item.categoryCode?.startsWith("YC-CXPT")) return "亩"
  return ""
}

function buildPrimaryValueText(item, value, unit) {
  if (item.categoryCode === "YC-BREEDING-STOCK") return String(value || "待完善")
  if (!Number.isFinite(Number(value))) return String(value || "")
  return `${formatNumber(value)}${unit || ""}`
}

function buildDetailExtra(item = {}) {
  const attrs = item.attributes || {}
  const metrics = item.metrics || {}
  return attrs["主要产品"] || attrs["主要草种"] || attrs["储备草种"] || attrs["主要育种方向"] || metrics["主要贷款产品（可多选）"] || item.sourceSheet || ""
}

function buildBreedingLevelRows() {
  const rows = new Map()
  breedingStockItems.forEach((item) => {
    const name = cleanText(item.attributes?.["育种等级"]) || "待完善"
    const current = rows.get(name) || { key: name, name, value: 0, unit: "个" }
    current.value += 1
    rows.set(name, current)
  })
  return [...rows.values()].sort((a, b) => {
    const order = { "省级": 0, "县级": 1, "待完善": 2 }
    return (order[a.name] ?? 9) - (order[b.name] ?? 9)
  })
}

function getStageSubjectRows(stageKey) {
  return categoryList
    .filter((category) => category.industryStage === stageKey)
    .map((category) => {
      const value = countBusinessItems(categoryItems(category.categoryCode))
      return {
        key: category.categoryCode,
        name: category.categoryName.replace(/^cxpt/, ""),
        value,
        unit: "条",
        extra: getStageDef(stageKey).name,
      }
    })
    .filter((item) => item.value > 0)
    .sort(sortByValue)
}

function chartPanel(key, title, type, rows, extra = {}) {
  return {
    key,
    title,
    height: 227,
    renderer: "business",
    type,
    rows,
    ...extra,
  }
}

function getIndustryChainListRows(stageKey) {
  if (stageKey === "family-pasture") {
    return industryChainListRows.filter((row) => row.stageKey === stageKey)
  }
  if (!stageKey) return industryStageDefs.flatMap((stage) => getStagePointListRows(stage.key))
  return getStagePointListRows(stageKey)
}

function industryChainListPanel(stageKey) {
  const stage = getStageDef(stageKey)
  const rows = getIndustryChainListRows(stageKey)
  if (stageKey === "family-pasture") {
    return {
      key: "family-pasture-ledger",
      title: "家庭牧场列表",
      renderer: "business",
      type: "projectTable",
      rows,
      maxRows: 12,
      fillRows: true,
      searchPlaceholder: "搜索户主、乡镇或村",
      emptyText: "无匹配家庭生态牧场",
      searchKeys: ["name", "fullName", "owner", "town", "village", "constructionYear", "facilityBrief", "facilityDetail", "grassSupportText", "sourceSheet", "searchText"],
      columns: [
        { key: "name", label: "名称", field: "ledgerName", fields: ["name"], width: "44%", className: "business-project-col-name" },
        { key: "region", label: "区域", field: "town", width: "36%", format: "townVillage" },
        { key: "locate", label: "定位", field: "locateText", width: "20%", align: "center", fallback: "定位", icon: "locate" },
      ],
    }
  }
  return {
    key: "industry-chain-list",
    title: `${stage.name}点位清单`,
    height: 466,
    span: 2,
    keepSpanHeight: true,
    renderer: "business",
    type: "projectTable",
    rows,
    searchPlaceholder: `搜索${stage.name}点位 / 乡镇`,
    emptyText: "无匹配点位",
    columns: [
      { key: "name", label: "主体", field: "name", width: "38%", className: "business-project-col-name" },
      { key: "stage", label: "类型", field: "categoryName", width: "24%" },
      { key: "town", label: "乡镇", field: "town", width: "18%" },
      { key: "locate", label: "定位", field: "locateText", width: "20%", align: "center" },
    ],
    searchKeys: ["name", "fullName", "stageName", "categoryName", "town", "address", "valueText", "extra", "sourceSheet", "searchText"],
  }
}

function scaleBreedingLocationListPanel() {
  const rows = getIndustryChainListRows("scale-breeding")
    .slice()
    .sort((a, b) => String(a.town || "").localeCompare(String(b.town || ""), "zh-CN") || String(a.name || "").localeCompare(String(b.name || ""), "zh-CN"))

  return {
    key: "scale-breeding-location-list",
    title: "养殖基地定位",
    height: 466,
    span: 2,
    keepSpanHeight: true,
    renderer: "business",
    type: "projectTable",
    rows,
    maxRows: 300,
    searchPlaceholder: "搜索养殖基地 / 乡镇",
    emptyText: "无匹配养殖基地",
    columns: [
      { key: "name", label: "养殖基地", field: "name", width: "46%", className: "business-project-col-name" },
      { key: "town", label: "区域", field: "town", width: "32%" },
      { key: "locate", label: "定位", field: "locateText", width: "22%", align: "center", fallback: "定位", action: "locate" },
    ],
    searchKeys: ["name", "fullName", "town", "address", "searchText"],
  }
}

function artificialGrasslandBusinessLedgerPanel() {
  return {
    key: "artificial-grassland-business-ledger",
    title: "项目建设台账",
    renderer: "business",
    type: "projectTable",
    rows: artificialGrasslandBusinessProjectRows,
    fixedHeight: true,
    rowSelectOnClick: false,
    showSearch: false,
    maxRows: 6,
    emptyText: "暂无项目建设台账",
    columns: [
      { key: "name", label: "项目", field: "name", width: "48%", className: "business-project-col-name" },
      { key: "year", label: "年度", field: "year", width: "16%", align: "center" },
      { key: "area", label: "实测面积", field: "actualAreaMu", width: "36%", align: "right", strong: true, unit: "亩" },
    ],
    searchKeys: ["name", "fullName", "year", "category", "towns", "searchText"],
  }
}

function getTownYakStockRows() {
  const rows = grasslandYakRows
    .map((item) => ({
      key: item.zoneName,
      name: item.zoneName,
      value: Number(item.yakCount || 0),
      unit: "头",
      extra: "牦牛存栏",
    }))
    .filter((item) => item.value > 0)
  return completeTownColumnRows(rows, { unit: "头", extra: "牦牛存栏" })
}

function getTownGrasslandResourceRows() {
  return grasslandYakRows
    .map((item) => ({
      key: item.zoneName,
      name: item.zoneName,
      value: round(Number(item.grasslandArea || 0) / 10000, 2),
      unit: "万亩",
      extra: "草地资源",
    }))
    .filter((item) => item.value > 0)
    .sort(sortByValue)
}

function getTownMetricRows(items = [], metricNames = [], options = {}) {
  const rows = aggregateRows(items, normalizeTown, (item) => metricValue(item, metricNames))
    .map((item) => ({
      ...item,
      unit: options.unit || "",
      extra: options.extra || `${item.count}个点位`,
    }))
  return completeTownColumnRows(rows, options)
}

function getTownCountRows(items = [], extra = "点位") {
  const rows = aggregateRows(items, normalizeTown, () => 1)
    .map((item) => ({
      ...item,
      unit: "个",
      extra,
    }))
  return completeTownColumnRows(rows, { unit: "个", extra })
}

function getForageBaseAreaRows() {
  return forageBaseItems
    .filter(isBusinessItem)
    .map((item) => ({
      key: item.id,
      name: compactName(item.name),
      value: metricValue(item, ["种植面积 (亩)", "acreage"]) || parseNumber(item.scale),
      unit: "亩",
      extra: normalizeTown(item) || item.categoryName,
    }))
    .filter((item) => item.value > 0)
    .sort(sortByValue)
    .slice(0, 8)
}

function getBreedingOutputRows() {
  return breedingBaseItems
    .filter(isBusinessItem)
    .map((item) => ({
      key: item.id,
      name: compactName(item.name),
      value: metricValue(item, ["年出栏量 (头)"]),
      unit: "头",
      extra: `设计${formatNumber(metricValue(item, ["设计存栏量 (头)"]))}头`,
    }))
    .filter((item) => item.value > 0)
    .sort(sortByValue)
    .slice(0, 7)
}

function getStoragePointRows() {
  return forageStorageItems
    .filter(isBusinessItem)
    .map((item) => ({
      key: item.id,
      name: compactName(item.name),
      value: metricValue(item, ["总库容 (吨)"]),
      unit: "吨",
      extra: metricValue(item, ["发放次数"]) || item.attributes?.["储备草种"] || "储备库",
    }))
    .filter((item) => item.value > 0)
    .sort(sortByValue)
    .slice(0, 8)
}

function getSlaughterHeadRows() {
  return slaughterItems
    .filter(isBusinessItem)
    .map((item) => ({
      key: item.id,
      name: compactName(item.name),
      value: metricValue(item, ["年屠宰总量 (头)"]),
      unit: "头",
      extra: `${formatNumber(metricValue(item, ["冷冻库容量 (吨)"]))}吨冷链`,
    }))
    .filter((item) => item.value > 0)
    .sort(sortByValue)
    .slice(0, 7)
}

function getFinanceCreditRows() {
  return financeItems
    .filter(isBusinessItem)
    .map((item) => ({
      key: item.id,
      name: compactName(item.attributes?.简称 || item.name),
      value: metricValue(item, ["最高单户贷款额度 (万元)"]),
      unit: "万元",
      extra: `覆盖${formatNumber(metricValue(item, ["服务覆盖乡镇数"]))}乡镇`,
    }))
    .filter((item) => item.value > 0)
    .sort(sortByValue)
    .slice(0, 7)
}

function getServiceCoverageRows() {
  return [
    ...financeItems.filter(isBusinessItem).map((item) => ({
      key: item.id,
      name: compactName(item.attributes?.简称 || item.name),
      value: metricValue(item, ["服务覆盖乡镇数"]),
      unit: "乡镇",
      extra: "金融",
    })),
    ...insuranceItems.filter(isBusinessItem).map((item) => ({
      key: item.id,
      name: compactName(item.attributes?.简称 || item.name),
      value: metricValue(item, ["服务覆盖乡镇数"]),
      unit: "乡镇",
      extra: "保险",
    })),
  ].filter((item) => item.value > 0).sort(sortByValue).slice(0, 7)
}

function getTrainingRows() {
  const rows = trainingItems
    .filter(isBusinessItem)
    .map((item) => ({
      key: item.id,
      name: compactName(item.name),
      value: metricValue(item, ["年培训人次"]),
      unit: "人次",
      extra: `${formatNumber(metricValue(item, ["年培训场次"]))}场`,
    }))
    .filter((item) => item.value > 0)
    .sort(sortByValue)
    .slice(0, 7)
  return rows.length ? rows : [
    { key: "sessions", name: "年培训场次", value: trainingSessionCount, unit: "场" },
    { key: "persons", name: "年培训人次", value: trainingPersonCount, unit: "人次" },
  ]
}

function buildGrassTypeRows(rows) {
  const aliases = [
    { key: "oat", name: "燕麦草", pattern: /燕麦/ },
    { key: "elymus", name: "披碱草", pattern: /披碱草/ },
    { key: "roegneria", name: "老芒麦", pattern: /老芒麦/ },
    { key: "other", name: "其他草种", pattern: /./ },
  ]
  const map = new Map(aliases.map((item) => [item.key, { key: item.key, name: item.name, value: 0, unit: "处" }]))
  rows.filter(isBusinessItem).forEach((item) => {
    const text = [item.attributes?.["主要草种"], item.attributes?.["储备草种"]].filter(Boolean).join("、")
    const matched = aliases.filter((alias) => alias.key !== "other" && alias.pattern.test(text))
    const targets = matched.length ? matched : [aliases[aliases.length - 1]]
    targets.forEach((alias) => {
      map.get(alias.key).value += 1
    })
  })
  return [...map.values()].filter((item) => item.value > 0).sort(sortByValue)
}

function buildProcessingChainRows() {
  return [
    { key: "raw-capacity", name: "原料加工", value: processingRawCapacity, unit: "吨" },
    { key: "slaughter-heads", name: "屠宰总量", value: slaughterAnnualHeads, unit: "头" },
    { key: "farmer-driven", name: "带动农户", value: processingDrivenHouseholds, unit: "户" },
    { key: "cold-storage", name: "冷链能力", value: slaughterColdCapacity, unit: "吨" },
  ].filter((item) => item.value > 0)
}

function buildServiceTypeRows() {
  return [
    { key: "finance", name: "金融", value: financeItems.filter(isBusinessItem).length, unit: "家" },
    { key: "insurance", name: "保险", value: insuranceItems.filter(isBusinessItem).length, unit: "家" },
    { key: "training", name: "培训", value: trainingItems.filter(isBusinessItem).length, unit: "家" },
    { key: "disease", name: "防疫", value: diseaseControlItems.filter(isBusinessItem).length, unit: "个" },
  ].filter((item) => item.value > 0)
}

function aggregateRows(rows, nameGetter, valueGetter) {
  const map = new Map()
  rows.filter(isBusinessItem).forEach((item) => {
    const name = cleanText(typeof nameGetter === "function" ? nameGetter(item) : item[nameGetter]) || "未填写"
    const current = map.get(name) || { key: name, name, value: 0, count: 0, extra: "" }
    current.value += Number(valueGetter(item) || 0)
    current.count += 1
    map.set(name, current)
  })
  return [...map.values()].sort(sortByValue)
}

function completeTownColumnRows(rows = [], options = {}) {
  const byTown = new Map()
  rows.forEach((row) => {
    const name = cleanText(row?.name)
    const matchedTown = townNames.find((town) => town === name) || townNames.find((town) => {
      const stem = town.replace(/[镇乡]$/, "")
      return stem.length >= 2 && name.includes(stem)
    })
    if (!matchedTown) return
    byTown.set(matchedTown, row)
  })
  return townNames.map((town, index) => {
    const row = byTown.get(town)
    const rawValue = Number(row?.value || 0)
    const hasValue = Number.isFinite(rawValue) && rawValue > 0
    return {
      key: row?.key || town,
      name: town,
      value: hasValue ? rawValue : 0.001,
      displayValue: hasValue ? row.displayValue : "0",
      scaleValue: row?.scaleValue,
      unit: row?.unit || options.unit || "",
      extra: row?.extra || options.extra || "",
      color: row?.color,
      zero: !hasValue,
      sourceIndex: index,
    }
  })
}

function metricValue(item = {}, names = []) {
  const metrics = item.metrics || {}
  const nameList = Array.isArray(names) ? names : [names]
  for (const name of nameList) {
    if (Object.prototype.hasOwnProperty.call(metrics, name)) {
      const value = parseNumber(metrics[name])
      if (value || value === 0) return value
    }
  }
  return 0
}

function parseNumber(value) {
  if (typeof value === "number") return Number.isFinite(value) ? value : 0
  if (isBlank(value)) return 0
  const text = String(value).replace(/,/g, "").trim()
  if (!text || text === "无" || text === "待完善") return 0
  const match = text.match(/-?\d+(?:\.\d+)?/)
  if (!match) return 0
  let number = Number(match[0])
  if (text.includes("万亩") && !text.includes("万元")) number *= 10000
  return Number.isFinite(number) ? number : 0
}

function normalizeTown(item = {}) {
  const direct = cleanText(item.town || item.areaName)
  if (townNames.includes(direct)) return direct
  const text = [item.town, item.areaName, item.areaFullName, item.address, item.village, item.name].filter(Boolean).join(" ")
  const exact = townNames.find((name) => text.includes(name))
  if (exact) return exact
  return townNames.find((name) => {
    const stem = name.replace(/[镇乡]$/, "")
    return stem.length >= 2 && text.includes(stem)
  }) || direct
}

function getItemCoordinate(item = {}) {
  const longitude = parseCoordinateNumber(item.longitude)
  const latitude = parseCoordinateNumber(item.latitude)
  if (isCoordinateInHongyuanBounds(longitude, latitude)) return { longitude, latitude }
  const location = Object.values(item.locations || {}).find((value) => (
    isCoordinateInHongyuanBounds(parseCoordinateNumber(value?.longitude), parseCoordinateNumber(value?.latitude))
  ))
  if (!location) return null
  return {
    longitude: parseCoordinateNumber(location.longitude),
    latitude: parseCoordinateNumber(location.latitude),
  }
}

function isCoordinateInHongyuanBounds(longitude, latitude) {
  const lng = Number(longitude)
  const lat = Number(latitude)
  return Number.isFinite(lng)
    && Number.isFinite(lat)
    && lng >= HONGYUAN_BOUNDS.west
    && lng <= HONGYUAN_BOUNDS.east
    && lat >= HONGYUAN_BOUNDS.south
    && lat <= HONGYUAN_BOUNDS.north
}

function parseCoordinateNumber(value) {
  if (value === undefined || value === null || value === "") return NaN
  const number = Number(value)
  return Number.isFinite(number) ? number : NaN
}

function isMilkProcessing(item = {}) {
  const text = [item.name, item.attributes?.["主要产品"]].filter(Boolean).join("")
  return /奶|乳|酸奶|奶粉/.test(text)
}

function isMeatProcessing(item = {}) {
  const text = [item.name, item.attributes?.["主要产品"]].filter(Boolean).join("")
  return /肉|屠宰|牛肉/.test(text)
}

function findClassifiedItem(point = {}) {
  const id = String(point.id || "")
  if (id && itemById.has(id)) return itemById.get(id)
  return allClassifiedItems.find((item) => item.name === point.name && item.categoryCode === point.categoryCode)
}

function scoreBy(value, target) {
  return Math.max(12, Math.min(100, Math.round((Number(value || 0) / target) * 100)))
}

function sumBy(rows, getter) {
  return rows.filter(isBusinessItem).reduce((sum, item) => sum + Number(getter(item) || 0), 0)
}

function maxByValue(rows, getter) {
  return rows.filter(isBusinessItem).reduce((max, item) => Math.max(max, Number(getter(item) || 0)), 0)
}

function uniqueCount(rows, getter) {
  return new Set(rows.filter(isBusinessItem).map(getter).filter(Boolean)).size
}

function sortByValue(a, b) {
  return b.value - a.value || b.count - a.count || String(a.name).localeCompare(String(b.name), "zh-CN")
}

function compactName(value = "") {
  return String(value)
    .replace(/^四川红原/, "")
    .replace(/^红原县/, "")
    .replace(/有限责任公司$/, "")
    .replace(/农民专业合作社$/, "合作社")
    .replace(/股份有限公司红原县支行$/, "红原支行")
    .trim()
}

function cleanText(value) {
  return String(value ?? "").replace(/\s+/g, " ").trim()
}

function isBlank(value) {
  return value === undefined || value === null || String(value).trim() === "" || String(value).trim().toLowerCase() === "nan"
}

function formatValue(value) {
  if (typeof value === "number") return formatNumber(value)
  const numeric = parseNumber(value)
  if (numeric && String(value).match(/^\s*[约≈]?\d/)) return String(value)
  return String(value ?? "")
}

function formatValueWithUnit(value, unit = "") {
  const formatted = formatValue(value)
  if (!unit) return formatted
  if (typeof value === "string" && formatted.includes(unit.replace(/^个/, ""))) return formatted
  return `${formatted}${unit}`
}

function formatNumber(value) {
  const number = Number(value || 0)
  if (!Number.isFinite(number)) return "0"
  return number.toLocaleString("zh-CN", { maximumFractionDigits: Number.isInteger(number) ? 0 : 1 })
}

function round(value, digits = 0) {
  const factor = 10 ** digits
  return Math.round(Number(value || 0) * factor) / factor
}
