<template>
  <m-card title="图斑详情" :width="width" :height="height">
    <div class="feature-info">
      <div v-if="loading" class="feature-info-state">正在查询图斑信息</div>
      <div v-else-if="empty" class="feature-info-state">当前点击位置未查询到图斑</div>
      <div v-else-if="!feature" class="feature-info-state">点击地图图层查看图斑/要素信息</div>
      <template v-else>
        <template v-if="orderedDisplayRows.length">
          <div class="feature-table">
            <div v-for="row in orderedDisplayRows" :key="row.key" class="feature-row">
              <span>{{ row.label }}</span>
              <strong :title="row.value">{{ row.value }}</strong>
            </div>
          </div>
        </template>
        <div v-else class="feature-info-state is-inline">当前图斑暂无可展示的业务字段</div>
      </template>
    </div>
  </m-card>
</template>

<script setup>
import { computed } from "vue"
import mCard from "@/components/mCard/index.vue"
import { getHongyuanTownshipNameByCode } from "@/config/townshipBoundaries"

const props = defineProps({
  feature: {
    type: Object,
    default: null,
  },
  empty: {
    type: Boolean,
    default: false,
  },
  loading: {
    type: Boolean,
    default: false,
  },
  height: {
    type: Number,
    default: 380,
  },
  width: {
    type: Number,
    default: 430,
  },
  compactGrassland: {
    type: Boolean,
    default: false,
  },
})

const locationBusinessFields = [
  [["townName", "town_name", "xiangName", "xiang_name", "xiang", "xzqmc", "xzqdm", "town_code", "areaCode", "area_code"], "所在乡镇"],
  [["village_name", "cunName", "cun_name", "cun", "c_name", "cmc"], "所在村"],
  [["full_name"], "所在区域"],
  [["land_number", "patch_no"], "图斑编号"],
  [["areaWanMu", "area_wan_mu", "area_mu", "acreage", "mj", "xbmj", "tbdlmj", "tbmj", "geomj", "shape_area"], "图斑面积"],
]

const tailBusinessFields = [
  [["investigator"], "调查人"],
  [["survey_time", "dc_rq", "sjnf", "delimitation_year"], "调查时间"],
  [["adjust_opinion_name"], "调整意见"],
  [["adjust_reason"], "调整原因"],
]

const grasslandCoreBusinessFields = [
  [["pastureName", "pasture_name"], "所属牧场"],
  [["yakCount", "yak_count"], "牦牛数量"],
  [["acreage", "area_mu", "mj", "xbmj", "tbdlmj", "tbmj", "geomj", "shape_area", "areaWanMu", "area_wan_mu"], "草场面积"],
  [["full_name", "townName", "town_name", "xiangName", "xiang_name", "xiang", "xzqmc", "xzqdm", "town_code", "areaCode", "area_code"], "所在区域"],
  [["grassTypeName", "grass_type_name", "grassland_type_name", "grassType", "grass_type"], "草原类"],
  [["grasslandLevelName", "grassland_level_name", "grasslandLevel", "grassland_level", "level_name", "level"], "草原级别"],
  [["vegetationCover", "vegetation_cover"], "植被盖度"],
  [["xcMuYield", "xc_mu_yield", "xbXcMuYield", "xb_xc_mu_yield", "mu_yield"], "鲜草亩产"],
  [["gcMuYield", "gc_mu_yield", "xbGcMuYield", "xb_gc_mu_yield"], "干草亩产"],
]

const topicBusinessFields = {
  woodland: [
    [["dlmc", "layer_class_name"], "地类名称"],
    ...locationBusinessFields,
    [["qsdwmc"], "权属单位"],
    [["zldwmc"], "坐落单位"],
    [["lin_ban"], "林班"],
    [["xiao_ban"], "小班"],
    [["ld_qs", "tdsyqs", "qsxz", "ownership_name", "ownership"], "土地权属"],
    [["gjgyl_bhdj", "bh_dj", "protection_level_name", "protection_level"], "保护等级"],
    [["sen_lin_lb", "forest_type"], "森林类别"],
    [["lin_zhong", "forest_category"], "林种"],
    [["zl_dj", "quality_level_name", "quality_level"], "质量等级"],
    [["you_shi_sz", "tree_species", "dominant_tree_species"], "优势树种"],
    [["qi_yuan", "origin"], "起源"],
    [["ling_zu"], "龄组"],
    [["yu_bi_du"], "郁闭度"],
    [["pingjun_sg"], "平均树高"],
    [["mei_gq_zs"], "每公顷株数"],
    [["mei_gq_xj"], "每公顷蓄积"],
    [["huo_lm_xj"], "活立木蓄积"],
    [["sheng_wu_l"], "生物量"],
    [["tan_chu_l"], "碳储量"],
    [["stqwmc"], "生态区位"],
    [["po_du", "slope"], "坡度"],
    [["po_wei"], "坡位"],
    [["tu_ceng_hd", "soil_depth"], "土层厚度"],
    ...tailBusinessFields,
  ],
  grassland: [
    ...grasslandCoreBusinessFields,
    [["pastureName", "pasture_name"], "所属牧场"],
    ...locationBusinessFields,
    [["land_class_name", "landUseName", "land_use_name", "landUse", "land_use"], "地类名称"],
    [["landType", "land_type"], "资源大类"],
    [["resourceType", "resource_type"], "资源类别"],
    [["grasslandCategory", "grassland_category_name", "grassland category", "base_grass"], "草原类别"],
    [["basic_type_name"], "基本草原类型"],
    [["grassTypeName", "grass_type_name", "grassland_type_name", "grassType", "grass_type"], "草原类"],
    [["grassMinType", "grass_min_type"], "草原型"],
    [["grasslandLevelName", "grassland_level_name", "grasslandLevel", "grassland_level", "level_name", "level"], "草原级别"],
    [["degradationLevelName", "degradation_level_name", "degradationLevel", "degradation_level"], "退化等级"],
    [["vegetationStructureName", "vegetation_structure_name", "vegetationStructure", "vegetation_structure"], "植被结构"],
    [["vegetationCover", "vegetation_cover"], "植被盖度"],
    [["lbmjbl"], "裸斑面积比例"],
    [["dominanceLevel", "dominance_level"], "优势度"],
    [["dominantGrassSpecies", "dominant_grass_species"], "优势草种"],
    [["functionalCategory", "functional_category"], "功能类别"],
    [["xcYield", "xc_yield"], "鲜草产量"],
    [["xcMuYield", "xc_mu_yield", "xbXcMuYield", "xb_xc_mu_yield", "mu_yield"], "鲜草亩产"],
    [["xbXcYield", "xb_xc_yield"], "小班鲜草产量"],
    [["xbXcMuYield", "xb_xc_mu_yield"], "小班鲜草亩产"],
    [["gcYield", "gc_yield"], "干草产量"],
    [["gcMuYield", "gc_mu_yield", "xbGcMuYield", "xb_gc_mu_yield"], "干草亩产"],
    [["xbGcYield", "xb_gc_yield"], "小班干草产量"],
    [["xbGcMuYield", "xb_gc_mu_yield"], "小班干草亩产"],
    [["elevation"], "海拔"],
    [["landformName", "landform_name", "landform"], "地貌"],
    [["slope"], "坡度"],
    [["aspect"], "坡向"],
    [["soilDepth", "soil_depth", "tu_ceng_hd"], "土层厚度"],
    [["soil texture"], "土壤质地"],
    [["sddl"], "三调地类"],
    [["hqlm"], "划区轮牧"],
    [["cdsyq"], "草地所有权"],
    [["cdsyq2"], "草地使用权"],
    [["cdjjq"], "草地经营权"],
    ...tailBusinessFields,
  ],
  wetland: [
    [["grass_min_type", "grassland_category_name", "grassland_type_name", "land_class_name", "land_use_name"], "湿地类型"],
    ...locationBusinessFields,
    [["grass_type_name", "grass_type"], "湿地草地型"],
    [["grassland_level_name", "grassland_level", "level_name", "level"], "湿地级别"],
    [["vegetation_structure_name", "vegetation_structure"], "植被结构"],
    [["vegetation_cover"], "植被盖度"],
    [["dominant_grass_species"], "优势草种"],
    [["functional_category"], "功能类别"],
    [["xc_yield", "xb_xc_yield"], "鲜草产量"],
    [["xc_mu_yield", "xb_xc_mu_yield", "mu_yield"], "鲜草亩产"],
    [["edible_xc_yield"], "可食鲜草产量"],
    [["edible_xc_mu_yield"], "可食鲜草亩产"],
    [["gc_yield", "xb_gc_yield"], "干草产量"],
    [["elevation"], "海拔"],
    [["landform_name", "landform"], "地貌"],
    [["soil_depth", "tu_ceng_hd"], "土层厚度"],
    ...tailBusinessFields,
  ],
  ecological: [
    [["type"], "管控分区"],
    [["project_name"], "项目名称"],
    [["project_category"], "项目类型"],
    [["measure_type"], "措施类型"],
    [["feature_role"], "要素类型"],
    [["township"], "涉及乡镇"],
    [["year"], "建设年份"],
    [["totalAcreage"], "总面积"],
    [["cdAcreage"], "草地面积"],
    [["sdAcreage"], "湿地面积"],
    [["area_mu"], "治理面积"],
    [["length_meter"], "工程长度"],
    [["cdScl"], "草地生产力"],
    [["sdScl"], "湿地生产力"],
    [["geometry_type"], "几何类型"],
  ],
}

const codeNameMaps = {
  land_type: {
    1: "草地",
    2: "湿地",
    caodi: "草地",
    shidi: "湿地",
    woodland: "林地",
    grassland: "草地",
    wetland: "湿地",
  },
  landType: {
    1: "草地",
    2: "湿地",
    caodi: "草地",
    shidi: "湿地",
    woodland: "林地",
    grassland: "草地",
    wetland: "湿地",
  },
  vegetation_structure: {
    1: "草本型",
  },
  landform: {
    2: "平原",
    5: "中山",
    6: "高山",
  },
  land_use: {
    "0401": "天然牧草地",
    "0403": "人工牧草地",
    "0404": "其他草地",
  },
  sddl: {
    "0401": "天然牧草地",
    "0403": "人工牧草地",
    "0404": "其他草地",
  },
  ld_qs: {
    10: "集体林地",
    20: "国有或其他",
  },
  qsxz: {
    10: "集体林地",
    20: "国有或其他",
  },
  tdsyqs: {
    10: "集体林地",
    20: "国有或其他",
  },
  gjgyl_bhdj: {
    0: "未划定",
    1: "国家一级公益林",
    2: "国家二级公益林",
  },
  bh_dj: {
    0: "未划定",
    1: "国家一级公益林",
    2: "国家二级公益林",
  },
  zl_dj: {
    2: "二级质量",
    3: "三级质量",
    4: "四级质量",
    5: "五级质量",
  },
  po_wei: {
    1: "脊部",
    2: "上坡",
    3: "中坡",
    4: "下坡",
    5: "谷地",
    6: "平地",
  },
}

const codedTextKeys = new Set([
  "lin_zhong",
  "sen_lin_lb",
  "you_shi_sz",
  "qi_yuan",
  "ling_zu",
  "po_xiang",
  "tu_rang_lx",
  "ownership",
  "ownership_name",
  "protection_level",
  "forest_category",
  "forest_type",
  "quality_level",
  "origin",
  "tree_species",
  "dominant_tree_species",
  "base_grass",
  "degradation_level",
  "land_class",
  "grass_type",
])

const fieldLabels = {
  xiang: "所在乡镇",
  xzqdm: "所在乡镇",
  xzqmc: "所在乡镇",
  town_code: "所在乡镇",
  area_code: "所在乡镇",
  areaCode: "所在乡镇",
  cun: "所在村",
  cmc: "所在村",
  c_name: "所在村",
  acreage: "图斑面积",
  mj: "图斑面积",
  xbmj: "小班面积",
  tbdlmj: "图斑地类面积",
  geomj: "图斑面积",
  tbmj: "图斑面积",
  shape_area: "图斑面积",
  area_mu: "图斑面积",
  pastureName: "所属牧场",
  pasture_name: "所属牧场",
  pastureAcreage: "牧场面积",
  pasture_acreage: "牧场面积",
  relationAcreage: "关系面积",
  relation_acreage: "关系面积",
  pastureOverlapAcreage: "重叠面积",
  pasture_overlap_acreage: "重叠面积",
  relatedPastureCount: "关联牧场数",
  related_pasture_count: "关联牧场数",
  relatedPastureNames: "关联牧场",
  related_pasture_names: "关联牧场",
  yakCount: "牦牛数量",
  yak_count: "牦牛数量",
  grass_min_type: "草原型",
  grassMinType: "草原型",
  grass_type: "草原类",
  grassType: "草原类",
  grass_type_name: "草原类",
  grassTypeName: "草原类",
  grassland_type_name: "草原类",
  patch_no: "图斑编号",
  land_number: "图斑编号",
  grassland_level: "草原级别",
  grasslandLevel: "草原级别",
  grassland_level_name: "草原级别",
  grasslandLevelName: "草原级别",
  level: "等级",
  level_name: "等级",
  land_class_name: "地类名称",
  land_use_name: "地类名称",
  landUseName: "地类名称",
  landUse: "地类名称",
  basic_type_name: "草原类型",
  grassland_category_name: "草原类别",
  grasslandCategory: "草原类别",
  degradation_level: "退化等级",
  degradationLevel: "退化等级",
  degradation_level_name: "退化等级",
  degradationLevelName: "退化等级",
  vegetation_structure: "植被结构",
  vegetationStructure: "植被结构",
  vegetation_structure_name: "植被结构",
  vegetationStructureName: "植被结构",
  xc_yield: "鲜草产量",
  xcYield: "鲜草产量",
  gc_yield: "干草产量",
  gcYield: "干草产量",
  xc_mu_yield: "鲜草亩产",
  xcMuYield: "鲜草亩产",
  gc_mu_yield: "干草亩产",
  gcMuYield: "干草亩产",
  mu_yield: "亩产",
  edible_xc_yield: "可食鲜草产量",
  edible_xc_mu_yield: "可食鲜草亩产",
  dlmc: "地类名称",
  qsdwmc: "权属单位",
  zldwmc: "坐落单位",
  lin_ban: "林班",
  xiao_ban: "小班",
  ld_qs: "土地权属",
  tdsyqs: "土地权属",
  qsxz: "土地权属",
  gjgyl_bhdj: "保护等级",
  bh_dj: "保护等级",
  sen_lin_lb: "森林类别",
  lin_zhong: "林种",
  zl_dj: "质量等级",
  you_shi_sz: "优势树种",
  qi_yuan: "起源",
  cdsyq: "草地所有权",
  cdsyq2: "草地使用权",
  cdjjq: "草地经营权",
  resource_type: "资源类型",
  "grassland category": "草原类别",
  dominant_grass_species: "优势草种",
  functional_category: "功能类别",
  functionalCategory: "功能类别",
  vegetation_cover: "植被盖度",
  vegetationCover: "植被盖度",
  xb_xc_yield: "小班鲜草产量",
  xbXcYield: "小班鲜草产量",
  xb_gc_yield: "小班干草产量",
  xbGcYield: "小班干草产量",
  base_grass: "基本草原",
  hqlm: "划区轮牧",
  elevation: "海拔",
  soil_depth: "土层厚度",
  "soil texture": "土壤质地",
  aspect: "坡向",
  slope: "坡度",
  landform: "地貌",
  landform_name: "地貌",
  sddl: "三调地类",
  dominance_level: "优势度",
  investigator: "调查人",
  survey_time: "调查时间",
  land_type: "土地类型",
  landType: "土地类型",
  status: "状态",
  type: "类型",
  xb_gc_mu_yield: "干草亩产",
  xbGcMuYield: "干草亩产",
  xb_xc_mu_yield: "鲜草亩产",
  xbXcMuYield: "鲜草亩产",
  grass_yield: "草地产量",
  grassYield: "草地产量",
  full_name: "所在区域",
  gyl_bhlx: "公益林保护类型",
  ling_zu: "龄组",
  yu_bi_du: "郁闭度",
  pingjun_xj: "平均胸径",
  mei_gq_zs: "每公顷株数",
  mei_gq_xj: "每公顷蓄积",
  stqwmc: "生态区位",
  lyfq: "林业分区",
  qykz: "区域控制",
  po_wei: "坡位",
  tu_rang_zd: "土壤质地",
  zzsxmc: "主导属性",
  lin_chang: "林场",
  di_mao: "地貌",
  jt_qw: "交通区位",
  zbfglx: "植被覆盖类型",
  disaster_c: "灾害类型",
  dispe: "病虫害",
  pingjun_sg: "平均树高",
  huo_lm_xj: "活立木蓄积",
  sheng_wu_l: "生物量",
  tan_chu_l: "碳储量",
  g_cheng_lb: "工程类别",
  shi_quan_d: "事权等级",
  sf_tbq: "是否特别区",
  td_th_lx: "土地退化类型",
  project_name: "项目名称",
  project_category: "项目类型",
  measure_type: "措施类型",
  feature_role: "要素类型",
  township: "涉及乡镇",
  year: "建设年份",
  length_meter: "工程长度",
  geometry_type: "几何类型",
  totalAcreage: "总面积",
  cdAcreage: "草地面积",
  sdAcreage: "湿地面积",
  cdScl: "草地生产力",
  sdScl: "湿地生产力",
}

const readableFallbackKeys = new Set(Object.keys(fieldLabels))

const zeroHiddenKeys = new Set([
  "pingjun_sg",
  "pingjun_xj",
  "mei_gq_zs",
  "mei_gq_xj",
  "huo_lm_xj",
  "sheng_wu_l",
  "tan_chu_l",
  "yu_bi_du",
  "grass_yield",
  "xb_xc_yield",
  "xb_xc_mu_yield",
  "xc_mu_yield",
  "xb_gc_yield",
  "xb_gc_mu_yield",
  "gc_mu_yield",
])

const duplicatedFallbackKeys = new Set([
  "xb_xc_yield",
  "xb_gc_yield",
  "grass_yield",
  "gc_yield",
  "xc_yield",
  "yield",
  "output",
  "remark1",
  "remark2",
  "remark3",
  "remark4",
  "remark5",
  "remarks",
])

const propsData = computed(() => props.feature?.properties || {})
const featureGeometry = computed(() => props.feature?.feature?.geometry || props.feature?.geometry || null)

const activeTopicKey = computed(() => {
  const layerId = String(props.feature?.id || "").toLowerCase()
  const layerKey = String(props.feature?.layer?.key || "").toLowerCase()
  const layerName = String(props.feature?.layer?.layerName || "").toLowerCase()
  const layerSignal = `${layerKey} ${layerName}`
  const data = propsData.value
  if (layerSignal.includes("national-park") || layerSignal.includes("restoration") || data.project_name || data.project_category || data.totalAcreage) return "ecological"
  if (data.dlmc || layerId.includes("woodland") || layerId.includes("t_woodland") || layerSignal.includes("woodland")) return "woodland"
  if (layerSignal.includes("wetland") || layerSignal.includes("shidi") || layerId.includes("shidi") || data.land_type === "shidi" || data.landType === "shidi" || data.land_type === "湿地" || data.landType === "湿地" || data.land_type === 2 || data.landType === 2 || data.landType === "2") return "wetland"
  if (layerSignal.includes("grassland") || layerSignal.includes("caodi") || data.grassland_category_name || data.grasslandCategory || data.basic_type_name || layerId.includes("caodi") || data.land_type === "caodi" || data.landType === "caodi" || data.land_type === 1 || data.landType === 1 || data.landType === "1") return "grassland"
  return "woodland"
})

const displayRows = computed(() => {
  const rows = []
  const used = new Set()
  const isGrassland = activeTopicKey.value === "grassland"
  const useCompactGrassland = isGrassland && props.compactGrassland
  const businessFields = useCompactGrassland ? grasslandCoreBusinessFields : topicBusinessFields[activeTopicKey.value] || topicBusinessFields.woodland
  businessFields.forEach(([keys, label]) => {
    const row = buildRow(propsData.value, keys, label, used)
    if (row && !rows.some((item) => item.label === row.label)) {
      rows.push(row)
      used.add(row.sourceKey)
    }
  })
  const areaLabel = isGrassland ? "草场面积" : "图斑面积"
  if (!rows.some((row) => row.label === areaLabel || row.label === "图斑面积")) {
    addStaticRow(rows, used, areaLabel, formatGeometryArea(featureGeometry.value), "geometry-area")
  }
  if (useCompactGrassland) return rows.slice(0, 10)
  Object.entries(propsData.value).forEach(([key, value]) => {
    if (used.has(key) || shouldHideFallbackField(key, value)) return
    const formattedValue = formatValue(key, value)
    if (!hasValue(formattedValue)) return
    if (rows.some((row) => row.value === formattedValue || row.label === (fieldLabels[key] || normalizeFieldLabel(key)))) return
    rows.push({
      key: `fallback-${key}`,
      sourceKey: key,
      label: fieldLabels[key] || normalizeFieldLabel(key),
      value: formattedValue,
    })
    used.add(key)
  })
  return rows
})

const orderedDisplayRows = computed(() => {
  return displayRows.value
    .map((row, index) => ({
      ...row,
      displayOrder: getRowPriority(row, index),
    }))
    .sort((a, b) => a.displayOrder - b.displayOrder)
})

function getRowPriority(row, index) {
  const label = row?.label || ""
  const sourceKey = String(row?.sourceKey || "").toLowerCase()
  if ([
    "所属牧场",
    "牦牛数量",
    "草场面积",
    "牧场面积",
    "关系面积",
    "重叠面积",
    "关联牧场数",
    "关联牧场",
  ].includes(label)) return index
  if ([
    "所在乡镇",
    "所在村",
    "所在区域",
    "图斑编号",
    "图斑面积",
    "小班面积",
    "图斑地类面积",
    "地类名称",
    "湿地类型",
  ].includes(label)) return index
  if ([
    "基本草原类型",
    "草原类型",
    "草原类",
    "草原型",
    "湿地草地型",
    "草原级别",
    "湿地级别",
    "退化等级",
    "功能类别",
    "保护等级",
    "森林类别",
    "林种",
    "质量等级",
    "优势树种",
    "起源",
    "龄组",
  ].includes(label)) return 100 + index
  if (
    label.includes("产量") ||
    label.includes("亩产") ||
    label.includes("植被") ||
    label.includes("优势草种") ||
    label.includes("优势度") ||
    label.includes("海拔") ||
    label.includes("地貌") ||
    label.includes("坡") ||
    label.includes("土壤") ||
    label.includes("郁闭度") ||
    label.includes("树高") ||
    label.includes("蓄积") ||
    label.includes("生物量") ||
    label.includes("碳储量")
  ) return 200 + index
  if (
    label.includes("权属") ||
    label.includes("所有权") ||
    label.includes("使用权") ||
    label.includes("经营权") ||
    label.includes("调查") ||
    label.includes("调整") ||
    label.includes("划区") ||
    label.includes("单位") ||
    sourceKey.includes("owner") ||
    sourceKey.includes("qsdw") ||
    sourceKey.includes("zldw")
  ) return 300 + index
  return 150 + index
}

function addStaticRow(rows, used, label, value, sourceKey) {
  if (!hasValue(value) || rows.some((row) => row.label === label || row.value === value)) return
  rows.push({
    key: `static-${sourceKey}`,
    sourceKey,
    label,
    value,
  })
  used.add(sourceKey)
}

function buildRow(data, keys, label, used = new Set()) {
  for (const key of keys) {
    if (used.has(key) || isHiddenField(key)) continue
    if (hasValue(data?.[key])) {
      const value = formatValue(key, data[key])
      if (!hasValue(value)) continue
      return {
        key: `${label}-${key}`,
        sourceKey: key,
        label,
        value,
      }
    }
  }
  return null
}

function hasValue(value) {
  return value !== undefined && value !== null && value !== "" && value !== " " && value !== "null" && value !== "undefined"
}

function formatValue(key, value) {
  if (!hasValue(value)) return ""
  if (codeNameMaps[key]?.[String(value)]) return codeNameMaps[key][String(value)]
  if (["xiang", "xzqdm", "town_code", "area_code", "areaCode"].includes(key)) return getTownNameFromCode(value)
  if (["cun", "village_code"].includes(key) && isCodeOnly(value)) return ""
  if (["grassland_level", "grasslandLevel", "level"].includes(key) && isNumberLike(value)) {
    return activeTopicKey.value === "wetland" ? `${Number(value)}级湿地` : `${Number(value)}级草原`
  }
  if (codedTextKeys.has(key) && isCodeOnly(value)) return ""
  if (isUnmappedCodeField(key, value)) return ""
  if (isDateField(key)) return formatDate(value)
  const isNumber = typeof value === "number" || /^-?\d+(\.\d+)?$/.test(String(value))
  if (isNumber) {
    const number = Number(value)
    if (number === 0 && zeroHiddenKeys.has(key)) return ""
    const formatted = Number.isInteger(number) ? `${number}` : `${Number(number.toFixed(2))}`
    if (["xbmj", "tbdlmj", "geomj", "area_square_meter"].includes(key)) return `${formatNumber(number / 666.6667)} 亩`
    if (["acreage", "mj", "area_mu", "pastureAcreage", "pasture_acreage", "relationAcreage", "relation_acreage", "pastureOverlapAcreage", "pasture_overlap_acreage"].includes(key)) return `${formatted} 亩`
    if (["yakCount", "yak_count"].includes(key)) return `${formatted} 头`
    if (["relatedPastureCount", "related_pasture_count"].includes(key)) return `${formatted} 个`
    if (["length_meter"].includes(key)) return `${formatted} 米`
    if (["totalAcreage", "cdAcreage", "sdAcreage"].includes(key)) return `${formatted} 万亩`
    if (["cdScl", "sdScl"].includes(key)) return `${formatted} 万吨`
    if (["areaWanMu", "area_wan_mu"].includes(key)) return `${formatted} 万亩`
    if (["xc_yield", "xcYield", "xb_xc_yield", "xbXcYield", "gc_yield", "gcYield", "xb_gc_yield", "xbGcYield", "edible_xc_yield", "grass_yield", "grassYield"].includes(key)) return `${formatted} 斤`
    if (["mu_yield", "xc_mu_yield", "xcMuYield", "gc_mu_yield", "gcMuYield", "xb_xc_mu_yield", "xbXcMuYield", "xb_gc_mu_yield", "xbGcMuYield", "edible_xc_mu_yield"].includes(key)) return `${formatted} 斤`
    if (["vegetation_cover", "vegetationCover", "lbmjbl", "yu_bi_du"].includes(key)) return `${formatted}%`
    if (["elevation", "tu_ceng_hd", "soilDepth", "soil_depth", "pingjun_sg"].includes(key)) return `${formatted} 米`
    if (["po_du", "slope"].includes(key)) return `${formatted}°`
    return formatted
  }
  const text = String(value)
  if (activeTopicKey.value === "wetland" && ["grassland_level", "grasslandLevel", "level"].includes(key)) {
    return text.replace(/草原/g, "湿地")
  }
  return text
}

function getTownNameFromCode(value) {
  const text = String(value || "").trim()
  if (!text) return ""
  const compact = text.replace(/\D/g, "")
  const townshipName = getHongyuanTownshipNameByCode(compact || text)
  if (townshipName) return townshipName
  return isCodeOnly(text) ? "" : text
}

function isCodeOnly(value) {
  return /^[0-9A-Za-z_-]{1,12}$/.test(String(value).trim())
}

function isNumberLike(value) {
  return /^-?\d+(\.\d+)?$/.test(String(value).trim())
}

function formatNumber(number) {
  return Number.isInteger(number) ? `${number}` : `${Number(number.toFixed(2))}`
}

function isDateField(key) {
  return ["survey_time", "dc_rq", "create_time", "update_time"].includes(String(key))
}

function formatDate(value) {
  const text = String(value)
  if (/^\d{4}-\d{2}-\d{2}/.test(text)) return text.slice(0, 10)
  return text
}

function isHiddenField(key) {
  const normalized = String(key).toLowerCase()
  if (["geom", "wkt", "geometry", "the_geom", "raw_properties"].includes(normalized)) return true
  if (["bsm", "ysdm", "gid", "id", "objectid", "object_id", "fid", "key_uid"].includes(normalized)) return true
  if (["shape_leng", "shape_length", "length", "perimeter"].includes(normalized)) return true
  if (["xzqdm", "area_code", "town_code", "patch_no", "land_number"].includes(normalized)) return false
  if (["di_lei", "qykz", "stqw", "lyfq", "tbybh", "patch_code"].includes(normalized)) return true
  if (normalized.endsWith("_code") || normalized.endsWith("dm") || normalized.endsWith("_id")) return true
  if (["create_by", "create_time", "update_by", "update_time"].includes(normalized)) return true
  return normalized.includes("geom") || normalized.includes("boundary") || normalized.includes("wkb")
}

function shouldHideFallbackField(key, value) {
  if (isHiddenField(key) || !hasValue(value)) return true
  const normalized = String(key).toLowerCase()
  if (duplicatedFallbackKeys.has(normalized)) return true
  if (normalized.includes("number") || normalized.includes("patch_no")) return true
  if (!readableFallbackKeys.has(key)) return true
  if (
    isCodeOnly(value) &&
    !codeNameMaps[key]?.[String(value)] &&
    !["xiang", "xzqdm", "town_code", "area_code", "cun", "land_type", "grassland_level", "level", "gjgyl_bhdj", "bh_dj", "ld_qs", "qsxz", "tdsyqs", "zl_dj"].includes(key)
  ) return true
  return false
}

function isUnmappedCodeField(key, value) {
  if (!isCodeOnly(value)) return false
  if (codeNameMaps[key]?.[String(value)]) return false
  return [
    "resource_type",
    "grassland category",
    "functional_category",
    "aspect",
    "soil_depth",
    "soil texture",
    "cdsyq",
    "cdsyq2",
    "cdjjq",
  ].includes(key)
}

function formatGeometryArea(geometry) {
  const squareMeters = getGeometryAreaSquareMeters(geometry)
  if (!squareMeters) return ""
  const mu = squareMeters / 666.6667
  if (mu >= 10000) return `${formatNumber(mu / 10000)} 万亩`
  return `${formatNumber(mu)} 亩`
}

function getGeometryAreaSquareMeters(geometry) {
  if (!geometry?.coordinates) return 0
  if (geometry.type === "Polygon") return getPolygonAreaSquareMeters(geometry.coordinates)
  if (geometry.type === "MultiPolygon") {
    return geometry.coordinates.reduce((sum, polygon) => sum + getPolygonAreaSquareMeters(polygon), 0)
  }
  return 0
}

function getPolygonAreaSquareMeters(rings = []) {
  if (!rings.length) return 0
  const [outer, ...holes] = rings
  const outerArea = Math.abs(getRingAreaSquareMeters(outer))
  const holesArea = holes.reduce((sum, ring) => sum + Math.abs(getRingAreaSquareMeters(ring)), 0)
  return Math.max(0, outerArea - holesArea)
}

function getRingAreaSquareMeters(ring = []) {
  if (ring.length < 3) return 0
  const averageLat = ring.reduce((sum, point) => sum + Number(point?.[1] || 0), 0) / ring.length
  const metersPerDegree = 111320
  const xScale = metersPerDegree * Math.cos((averageLat * Math.PI) / 180)
  let area = 0
  for (let index = 0; index < ring.length; index++) {
    const current = ring[index]
    const next = ring[(index + 1) % ring.length]
    const x1 = Number(current?.[0] || 0) * xScale
    const y1 = Number(current?.[1] || 0) * metersPerDegree
    const x2 = Number(next?.[0] || 0) * xScale
    const y2 = Number(next?.[1] || 0) * metersPerDegree
    area += x1 * y2 - x2 * y1
  }
  return area / 2
}

function normalizeFieldLabel(key) {
  return String(key)
    .replace(/_/g, " ")
    .replace(/\b\w/g, (text) => text.toUpperCase())
}
</script>

<style lang="scss">
.feature-info {
  display: block;
  height: 100%;
  padding: 10px 12px 12px;
  box-sizing: border-box;
  overflow: hidden;

  &-state {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgba(255, 255, 255, 0.52);
    font-size: 14px;
    text-align: center;

    &.is-inline {
      height: 190px;
    }
  }
}

.feature-table {
  display: flex;
  flex-direction: column;
  height: 100%;
  max-height: 100%;
  padding-right: 5px;
  overflow-y: auto;

  &::-webkit-scrollbar {
    width: 4px;
  }

  &::-webkit-scrollbar-thumb {
    background: rgba(48, 220, 255, 0.32);
  }
}

.feature-row {
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr);
  min-height: 34px;
  align-items: stretch;
  border: 1px solid rgba(48, 220, 255, 0.13);
  border-top: 0;
  background: rgba(5, 24, 37, 0.56);

  &:first-child {
    border-top: 1px solid rgba(48, 220, 255, 0.13);
  }

  span {
    display: flex;
    align-items: center;
    padding: 7px 10px;
    border-right: 1px solid rgba(48, 220, 255, 0.13);
    background: rgba(48, 220, 255, 0.08);
    color: rgba(255, 255, 255, 0.56);
    font-size: 12px;
    line-height: 18px;
  }

  strong {
    display: flex;
    align-items: center;
    min-width: 0;
    padding: 7px 11px;
    color: rgba(239, 252, 255, 0.94);
    font-size: 13px;
    font-weight: 600;
    line-height: 18px;
    word-break: break-word;
  }

  &:first-child strong,
  &:nth-child(2) strong {
    color: #1afcff;
    font-family: D-DIN, Arial, sans-serif;
    font-size: 15px;
  }
}
</style>
