import type { WaterNetworkSourceId } from "../map/sources";
import { formatValue } from "./format-value";

export type LocalizedFeatureProperty = {
  key: string;
  label: string;
  value: string;
};

export type FeaturePanelBadgeTone = "active" | "inactive" | "warning" | "critical" | "info";

export type FeaturePanelBadge = {
  label: string;
  tone: FeaturePanelBadgeTone;
};

export type FeaturePanelModel = {
  id: string;
  badge?: FeaturePanelBadge;
  attributes: LocalizedFeatureProperty[];
};

export type FeatureInsightMetric = {
  label: string;
  value: string;
};

const PROPERTY_LABELS: Record<string, string> = {
  fid: "GeoServer 要素 ID",
  id: "编号",
  scada_id: "编号 UUID",
  sensor_id: "传感器 ID",
  sensor_name: "传感器名称",
  swmm_node: "SWMM 节点",
  topology_order: "拓扑序",
  distance_to_wwtp_m: "距处理厂距离",
  upstream_node_count: "上游节点数",
  upstream_sensors: "上游传感器",
  downstream_path: "下游路径",
  x: "X 坐标",
  y: "Y 坐标",
  cod_mg_l: "COD",
  氨氮_mg_l: "氨氮",
  电导率_us_cm: "电导率",
  液位_m: "液位",
  流量_m3_s: "流量",
  gid: "要素编号",
  name: "名称",
  code: "编码",
  type: "类型",
  node1: "起点节点",
  node2: "终点节点",
  from_node: "起点节点",
  to_node: "终点节点",
  diameter: "管径",
  dn: "管径",
  length: "长度",
  roughness: "粗糙系数",
  shape: "断面形状",
  max_depth: "最大深度",
  invert_elevation: "井底高程",
  v_type: "阀门类型",
  setting: "阀门设定",
  minor_loss: "局部损失系数",
  orifice_type: "孔口类型",
  discharge_coeff: "流量系数",
  gated: "闸门",
  offset_height: "偏移高度",
  geom1: "几何参数 1",
  geom2: "几何参数 2",
  pump_curve: "泵曲线",
  startup_depth: "启动水深",
  shutoff_depth: "停泵水深",
  outfall_type: "排放类型",
  stage_data: "阶段数据",
  status: "状态",
  head: "水头",
  pattern: "模式",
  init_level: "初始水位",
  min_level: "最低水位",
  max_level: "最高水位",
  material: "材质",
  elevation: "高程",
  demand: "需水量",
  pressure: "压力",
  flow: "流量",
  velocity: "流速",
  zone: "分区",
  district: "片区",
  source: "来源",
  updated_at: "更新时间",
  point_id: "测点 ID",
  point_external_id: "测点编号",
  point_name: "测点名称",
  associated_element_id: "关联资产",
  transmission_mode: "传输方式",
  transmission_frequency: "传输频率",
  reliability: "可靠性",
  device_id: "设备 ID",
  device_external_id: "设备编号",
  device_type_id: "设备类型 ID",
  device_type_name: "设备类型",
  device_icon_code: "设备图标编码",
  active: "运行状态",
  external_id: "设备编号",
  junction_id: "关联节点",
  kind: "设备类型",
  location_source: "位置来源",
  site_external_id: "站点编号",
  synced_at: "同步时间"
};

const PROPERTY_ORDER: Record<string, number> = {
  fid: 9,
  id: 10,
  scada_id: 10,
  sensor_id: 10,
  sensor_name: 12,
  swmm_node: 13,
  topology_order: 14,
  distance_to_wwtp_m: 15,
  upstream_node_count: 16,
  upstream_sensors: 17,
  downstream_path: 18,
  cod_mg_l: 20,
  氨氮_mg_l: 21,
  电导率_us_cm: 22,
  液位_m: 23,
  流量_m3_s: 24,
  gid: 11,
  name: 12,
  code: 13,
  diameter: 20,
  dn: 20,
  length: 21,
  roughness: 22,
  max_depth: 30,
  invert_elevation: 31,
  orifice_type: 32,
  outfall_type: 32,
  shape: 33,
  pump_curve: 34,
  material: 23,
  node1: 24,
  from_node: 24,
  node2: 25,
  to_node: 25,
  elevation: 30,
  demand: 31,
  pressure: 32,
  flow: 33,
  velocity: 34,
  status: 90
};

const STATUS_LABELS: Record<string, string> = {
  on: "运行",
  off: "停止",
  active: "运行中",
  inactive: "停用",
  online: "在线",
  offline: "离线",
  open: "开启",
  closed: "关闭",
  normal: "正常",
  warning: "告警",
  critical: "严重"
};

const VALVE_TYPE_LABELS: Record<string, string> = {
  prv: "减压阀",
  psv: "持压阀",
  pbv: "压降控制阀",
  fcv: "流量控制阀",
  tcv: "节流控制阀",
  gpv: "通用阀",
  cv: "止回阀"
};

const MATERIAL_LABELS: Record<string, string> = {
  di: "球墨铸铁",
  ci: "铸铁",
  steel: "钢管",
  st: "钢管",
  pvc: "PVC",
  pe: "PE",
  hdpe: "HDPE",
  concrete: "混凝土",
  rc: "钢筋混凝土"
};

const ASSET_TYPE_LABELS: Record<string, string> = {
  pipe: "管线",
  conduit: "管线",
  junction: "节点",
  node: "节点",
  valve: "阀门",
  reservoir: "水库",
  tank: "水箱",
  pump: "泵站",
  scada: "SCADA",
  pressure: "压力监测",
  pipe_flow: "流量监测"
};

const TRANSMISSION_MODE_LABELS: Record<string, string> = {
  wired: "有线",
  wire: "有线",
  cable: "有线",
  wireless: "无线",
  cellular: "蜂窝网络",
  mobile: "移动网络",
  gprs: "GPRS",
  "4g": "4G",
  "5g": "5G",
  nb_iot: "NB-IoT",
  nbiot: "NB-IoT",
  lora: "LoRa",
  realtime: "实时",
  real_time: "实时",
  non_realtime: "非实时",
  non_real_time: "非实时"
};

const RELIABILITY_LABELS: Record<string, string> = {
  high: "高",
  medium: "中",
  mid: "中",
  low: "低",
  good: "良好",
  fair: "一般",
  poor: "较差"
};

const PATTERN_LABELS: Record<string, string> = {
  none: "无",
  null: "无",
  default: "默认"
};

const OUTFALL_TYPE_LABELS: Record<string, string> = {
  free: "自由出流"
};

const GATED_LABELS: Record<string, string> = {
  no: "否",
  false: "否",
  "0": "否",
  yes: "是",
  true: "是",
  "1": "是"
};

const SCADA_KIND_LABELS: Record<string, string> = {
  water_quality: "水质监测",
  radar_level: "雷达液位",
  ultrasonic_flow: "超声流量",
  integrated_monitoring: "综合监测点"
};

export const SCADA_METRIC_PROPERTY_KEYS = [
  "COD_mg_L",
  "氨氮_mg_L",
  "电导率_uS_cm",
  "液位_m",
  "流量_m3_s"
] as const;

const PROPERTY_UNITS: Record<string, string> = {
  cod_mg_l: "mg/L",
  氨氮_mg_l: "mg/L",
  电导率_us_cm: "μS/cm",
  液位_m: "m",
  流量_m3_s: "m³/s"
};

const FEATURE_PANEL_PROPERTY_KEYS: Record<WaterNetworkSourceId, readonly string[]> = {
  pipes: ["id", "diameter", "length", "material"],
  junctions: ["id", "elevation", "demand", "pressure"],
  valves: ["id", "node1", "node2", "diameter", "v_type", "setting"],
  reservoirs: ["id", "head", "pattern"],
  scada: ["id", "type", "associated_element_id", "transmission_mode", "transmission_frequency", "reliability"],
  pumps: ["id", "node1", "node2", "status"],
  tanks: ["id", "elevation", "init_level", "min_level", "max_level"]
};

const FEATURE_PANEL_BADGE_KEYS: Partial<Record<WaterNetworkSourceId, string>> = {
  pipes: "status",
  valves: "setting"
};

type FeatureInsightMetricDefinition = {
  label: string;
  key?: string;
  value?: string;
};

const FEATURE_INSIGHT_METRICS: Record<WaterNetworkSourceId, readonly FeatureInsightMetricDefinition[]> = {
  pipes: [
    { label: "管径", key: "diameter" },
    { label: "长度", key: "length" },
    { label: "材质", key: "material" },
    { label: "状态", key: "status" }
  ],
  junctions: [
    { label: "需水量", key: "demand" },
    { label: "高程", key: "elevation" },
    { label: "压力", key: "pressure" },
    { label: "状态", value: "在线" }
  ],
  valves: [
    { label: "管径", key: "diameter" },
    { label: "类型", key: "v_type" },
    { label: "设定", key: "setting" },
    { label: "局部损失", key: "minor_loss" }
  ],
  reservoirs: [
    { label: "水头", key: "head" },
    { label: "模式", key: "pattern" },
    { label: "状态", value: "在线" }
  ],
  scada: [
    { label: "类型", key: "type" },
    { label: "关联资产", key: "associated_element_id" },
    { label: "传输方式", key: "transmission_mode" },
    { label: "可靠性", key: "reliability" }
  ],
  pumps: [
    { label: "起点", key: "node1" },
    { label: "终点", key: "node2" },
    { label: "状态", key: "status" }
  ],
  tanks: [
    { label: "高程", key: "elevation" },
    { label: "初始水位", key: "init_level" },
    { label: "最高水位", key: "max_level" },
    { label: "状态", value: "在线" }
  ]
};

export function getLocalizedFeatureProperties(properties: Record<string, unknown>): LocalizedFeatureProperty[] {
  return Object.entries(properties).filter(([key]) => normalizePropertyKey(key) !== "cluster_size").map(([key, value]) => ({
    key,
    label: getFeaturePropertyLabel(key),
    value: formatFeaturePropertyValue(key, value)
  })).sort((first, second) => getPropertyOrder(first.key) - getPropertyOrder(second.key));
}

export function getFeaturePanelProperties(
  layer: WaterNetworkSourceId,
  properties: Record<string, unknown>,
  featureId?: string
): LocalizedFeatureProperty[] {
  return FEATURE_PANEL_PROPERTY_KEYS[layer].map((key) => {
    const propertyValue = getPropertyValue(properties, key);
    const value = key === "id" || key === "scada_id" || key === "sensor_id" ? propertyValue ?? featureId : propertyValue;

    return {
      key,
      label: getFeaturePropertyLabel(key),
      value: formatFeaturePropertyValue(key, value)
    };
  });
}

export function getScadaMetricProperties(
  properties: Record<string, unknown>
): LocalizedFeatureProperty[] {
  return SCADA_METRIC_PROPERTY_KEYS.map((key) => ({
    key,
    label: getFeaturePropertyLabel(key),
    value: formatFeaturePropertyValue(key, getPropertyValue(properties, key))
  }));
}

export function getFeatureInsightMetrics(
  layer: WaterNetworkSourceId,
  properties: Record<string, unknown>
): FeatureInsightMetric[] {
  return FEATURE_INSIGHT_METRICS[layer].map((metric) => ({
    label: metric.label,
    value: metric.key
      ? formatFeaturePropertyValue(metric.key, getPropertyValue(properties, metric.key))
      : metric.value ?? "暂无"
  }));
}

export function getFeaturePanelModel(
  layer: WaterNetworkSourceId,
  properties: Record<string, unknown>,
  featureId?: string
): FeaturePanelModel {
  const entries = getFeaturePanelProperties(layer, properties, featureId);
  const idKey = "id";
  const id = entries.find((entry) => entry.key === idKey)?.value ?? "暂无";
  const badgeKey = FEATURE_PANEL_BADGE_KEYS[layer];
  const badgeEntry = badgeKey ? entries.find((entry) => entry.key === badgeKey) : undefined;

  return {
    id,
    badge: badgeEntry ? getFeaturePanelBadge(layer, badgeEntry.value) : undefined,
    attributes: entries.filter((entry) => entry.key !== idKey && entry.key !== badgeKey)
  };
}

export function getFeaturePropertyLabel(key: string) {
  const normalizedKey = normalizePropertyKey(key);
  return PROPERTY_LABELS[normalizedKey] ?? key;
}

export function formatFeaturePropertyValue(key: string, value: unknown) {
  const normalizedKey = normalizePropertyKey(key);

  if (typeof value === "string") {
    const mappedValue = getMappedPropertyValue(normalizedKey, value);
    if (mappedValue) return mappedValue;
  }

  if (normalizedKey === "outfall_type" && typeof value === "string") {
    return OUTFALL_TYPE_LABELS[value.toLowerCase()] ?? value;
  }

  if (normalizedKey === "gated" && value !== null && value !== undefined && value !== "") {
    return GATED_LABELS[String(value).toLowerCase()] ?? formatValue(value);
  }

  if (normalizedKey === "active" && typeof value === "boolean") {
    return value ? "在线" : "离线";
  }

  if (normalizedKey === "location_source" && value === "density_cluster_demo") {
    return "密度聚类模拟位置";
  }

  if (normalizedKey === "location_source" && value === "uniform_farthest_point_demo") {
    return "空间均匀采样模拟位置";
  }

  if (normalizedKey === "kind" && typeof value === "string") {
    return SCADA_KIND_LABELS[value] ?? value;
  }

  const unit = PROPERTY_UNITS[normalizedKey];
  if (unit && value !== null && value !== undefined && value !== "") {
    return `${formatValue(value)} ${unit}`;
  }

  if ((normalizedKey === "diameter" || normalizedKey === "dn") && value !== null && value !== undefined && value !== "") {
    const diameterInMillimeters = typeof value === "number" ? value : Number(value);
    return Number.isFinite(diameterInMillimeters)
      ? `${formatValue(diameterInMillimeters)} mm`
      : formatValue(value);
  }

  if (["length", "elevation", "invert_elevation", "max_depth", "startup_depth", "shutoff_depth", "distance_to_wwtp_m"].includes(normalizedKey)
    && value !== null && value !== undefined && value !== "") {
    return `${formatValue(value)} m`;
  }

  return formatValue(value);
}

function getPropertyOrder(key: string) {
  return PROPERTY_ORDER[normalizePropertyKey(key)] ?? 100;
}

function normalizePropertyKey(key: string) {
  return key.trim().replaceAll("-", "_").toLowerCase();
}

function getPropertyValue(properties: Record<string, unknown>, key: string) {
  if (Object.prototype.hasOwnProperty.call(properties, key)) {
    return properties[key];
  }

  const normalizedKey = normalizePropertyKey(key);
  const matchingKey = Object.keys(properties).find((propertyKey) => normalizePropertyKey(propertyKey) === normalizedKey);
  return matchingKey ? properties[matchingKey] : undefined;
}

function getMappedPropertyValue(normalizedKey: string, value: string) {
  const normalizedValue = normalizePropertyValue(value);

  if (isStatusLikeKey(normalizedKey)) {
    return STATUS_LABELS[normalizedValue];
  }

  if (normalizedKey === "v_type") {
    return VALVE_TYPE_LABELS[normalizedValue];
  }

  if (normalizedKey === "material") {
    return MATERIAL_LABELS[normalizedValue];
  }

  if (normalizedKey === "type") {
    return ASSET_TYPE_LABELS[normalizedValue];
  }

  if (normalizedKey === "transmission_mode") {
    return TRANSMISSION_MODE_LABELS[normalizedValue];
  }

  if (normalizedKey === "reliability") {
    return RELIABILITY_LABELS[normalizedValue];
  }

  if (normalizedKey === "pattern") {
    return PATTERN_LABELS[normalizedValue];
  }

  return undefined;
}

function normalizePropertyValue(value: string) {
  return value.trim().replaceAll("-", "_").replaceAll(" ", "_").toLowerCase();
}

function isStatusLikeKey(normalizedKey: string) {
  return normalizedKey === "status" || normalizedKey === "setting";
}

function getFeaturePanelBadge(
  layer: WaterNetworkSourceId,
  value: string
): FeaturePanelBadge {
  const normalizedValue = value.toLowerCase();

  if (["运行", "运行中", "在线", "开启", "正常"].includes(value)) {
    return { label: value, tone: "active" };
  }

  if (["停止", "停用", "离线", "关闭"].includes(value)) {
    return { label: value, tone: "inactive" };
  }

  if (normalizedValue === "warning" || value === "告警") {
    return { label: value, tone: "warning" };
  }

  if (normalizedValue === "critical" || value === "严重") {
    return { label: value, tone: "critical" };
  }

  return { label: value, tone: "inactive" };
}
