package platform

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
)

// gb32960FieldReference is the platform copy of the authoritative Chinese
// terminology supplied for GB/T 32960 and the Guangdong fuel-cell extension.
// It enriches protocol values at read time without changing the stored RAW
// evidence or replacing the parser's stable source-field keys.
type gb32960FieldReference struct {
	Label         string
	Unit          string
	Description   string
	ValueMappings []MetricValueMapping
}

func enumMappings(values ...string) []MetricValueMapping {
	result := make([]MetricValueMapping, 0, len(values)/3)
	for index := 0; index+2 < len(values); index += 3 {
		result = append(result, MetricValueMapping{Value: values[index], Label: values[index+1], Description: values[index+2]})
	}
	return result
}

var gb32960PositionMappings = func() []MetricValueMapping {
	result := make([]MetricValueMapping, 0, 8)
	for value := 0; value < 8; value++ {
		parts := []string{"有效定位", "北纬", "东经"}
		if value&1 != 0 {
			parts[0] = "无效定位"
		}
		if value&2 != 0 {
			parts[1] = "南纬"
		}
		if value&4 != 0 {
			parts[2] = "西经"
		}
		result = append(result, MetricValueMapping{
			Value:       strconv.Itoa(value),
			Label:       strings.Join(parts, " · "),
			Description: "bit0 表示定位有效性，bit1 表示纬度方向，bit2 表示经度方向。",
		})
	}
	return result
}()

var gb32960FieldReferences = map[string]gb32960FieldReference{
	"gb32960.vehicle.vehicle_status":   {Label: "车辆状态", Description: "车辆运行、停止等状态编码。", ValueMappings: enumMappings("1", "启动", "车辆处于可行驶启动状态。", "2", "熄火", "车辆处于熄火状态。", "3", "其他", "车辆处于其他状态。", "254", "异常", "协议异常值。", "255", "无效", "协议无效值。")},
	"gb32960.vehicle.charge_status":    {Label: "充电状态", Description: "车辆充电状态编码。", ValueMappings: enumMappings("1", "停车充电", "车辆停车充电。", "2", "行驶充电", "车辆行驶充电。", "3", "未充电", "车辆未充电。", "4", "充电完成", "车辆充电完成。", "254", "异常", "协议异常值。", "255", "无效", "协议无效值。")},
	"gb32960.vehicle.running_mode":     {Label: "运行模式", Description: "纯电、混合动力、燃料电池等运行模式编码。", ValueMappings: enumMappings("1", "纯电", "纯电驱动模式。", "2", "混合动力", "混合动力驱动模式。", "3", "燃料电池", "燃料电池驱动模式。", "254", "异常", "协议异常值。", "255", "无效", "协议无效值。")},
	"gb32960.vehicle.speed_kmh":        {Label: "车速", Unit: "km/h", Description: "车辆当前速度。"},
	"gb32960.vehicle.total_mileage_km": {Label: "累计里程", Unit: "km", Description: "车辆累计行驶里程。"},
	"gb32960.vehicle.total_voltage_v":  {Label: "总电压", Unit: "V", Description: "动力系统总电压。"},
	"gb32960.vehicle.total_current_a":  {Label: "总电流", Unit: "A", Description: "动力系统总电流。"},
	"gb32960.vehicle.soc_percent":      {Label: "SOC", Unit: "%", Description: "动力电池荷电状态。"},
	"gb32960.vehicle.dc_dc_status":     {Label: "DC/DC 状态", Description: "DC/DC 工作状态编码。", ValueMappings: enumMappings("1", "工作", "DC/DC 处于工作状态。", "2", "断开", "DC/DC 处于断开状态。", "254", "异常", "协议异常值。", "255", "无效", "协议无效值。")},
	"gb32960.vehicle.gear":             {Label: "挡位原始值", Description: "挡位、驱动力和制动力组合原始编码。"},
	"gb32960.vehicle.insulation_kohm":  {Label: "绝缘电阻", Unit: "kΩ", Description: "高压系统绝缘电阻。"},
	"gb32960.vehicle.accelerator_pct":  {Label: "加速踏板行程", Unit: "%", Description: "2016 版字段，加速踏板开度。"},
	"gb32960.vehicle.brake_pct":        {Label: "制动踏板状态", Unit: "%", Description: "2016 版字段，制动踏板状态或开度。"},

	"gb32960.drive_motor.serial_no":                {Label: "驱动电机序号", Description: "电机编号。"},
	"gb32960.drive_motor.state":                    {Label: "驱动电机状态", Description: "电机工作状态编码。", ValueMappings: enumMappings("1", "耗电", "驱动电机耗电。", "2", "发电", "驱动电机发电。", "3", "关闭", "驱动电机关闭。", "4", "准备", "驱动电机准备。", "254", "异常", "协议异常值。", "255", "无效", "协议无效值。")},
	"gb32960.drive_motor.controller_temperature_c": {Label: "控制器温度", Unit: "℃", Description: "驱动电机控制器温度。"},
	"gb32960.drive_motor.speed_rpm":                {Label: "转速", Unit: "rpm", Description: "驱动电机转速。"},
	"gb32960.drive_motor.torque_nm":                {Label: "转矩", Unit: "N·m", Description: "驱动电机输出转矩。"},
	"gb32960.drive_motor.motor_temperature_c":      {Label: "电机温度", Unit: "℃", Description: "驱动电机温度。"},
	"gb32960.drive_motor.controller_voltage_v":     {Label: "控制器输入电压", Unit: "V", Description: "电机控制器直流母线输入电压。"},
	"gb32960.drive_motor.controller_current_a":     {Label: "控制器直流母线电流", Unit: "A", Description: "电机控制器直流母线电流。"},

	"gb32960.fuel_cell.fuel_cell_voltage_v":                 {Label: "燃料电池电压", Unit: "V", Description: "燃料电池系统输出电压。"},
	"gb32960.fuel_cell.fuel_cell_current_a":                 {Label: "燃料电池电流", Unit: "A", Description: "燃料电池系统输出电流。"},
	"gb32960.fuel_cell.hydrogen_consumption_kg_per_100km":   {Label: "氢耗", Unit: "kg/100km", Description: "燃料电池氢气消耗率。"},
	"gb32960.fuel_cell.temperature_probe_values_c":          {Label: "探针温度", Unit: "℃", Description: "燃料电池温度探针列表。"},
	"gb32960.fuel_cell.max_hydrogen_temperature_c":          {Label: "氢系统最高温度", Unit: "℃", Description: "氢系统最高温度。"},
	"gb32960.fuel_cell.max_hydrogen_concentration_percent":  {Label: "最高氢浓度", Unit: "%", Description: "氢气浓度最高值。"},
	"gb32960.fuel_cell.max_hydrogen_pressure_mpa":           {Label: "最高氢压力", Unit: "MPa", Description: "氢系统最高压力。"},
	"gb32960.fuel_cell.dc_dc_status":                        {Label: "高压 DC/DC 状态", Description: "燃料电池高压 DC/DC 状态。"},
	"gb32960.fuel_cell.max_hydrogen_temperature_probe_id":   {Label: "最高氢温探针编号", Description: "检测到氢系统最高温度的探针编号。"},
	"gb32960.fuel_cell.max_hydrogen_concentration_probe_id": {Label: "最高氢浓度探针编号", Description: "检测到最高氢浓度的探针编号。"},
	"gb32960.fuel_cell.max_hydrogen_pressure_probe_id":      {Label: "最高氢压探针编号", Description: "检测到最高氢压力的探针编号。"},

	"gb32960.position.position_status":   {Label: "定位状态标志", Description: "定位有效性及经纬度方向标志。", ValueMappings: gb32960PositionMappings},
	"gb32960.position.coordinate_system": {Label: "坐标系", Description: "2025 版新增坐标系编码。", ValueMappings: enumMappings("1", "WGS84", "WGS84 坐标系。", "2", "GCJ-02", "GCJ-02 坐标系。", "3", "其他", "其他坐标系。")},
	"gb32960.position.longitude":         {Label: "经度", Unit: "°", Description: "车辆经度。"},
	"gb32960.position.latitude":          {Label: "纬度", Unit: "°", Description: "车辆纬度。"},

	"gb32960.alarm.max_alarm_level":    {Label: "最高报警等级", Description: "当前最高报警等级。", ValueMappings: enumMappings("0", "无故障", "当前无报警故障。", "1", "一级故障", "一级报警故障。", "2", "二级故障", "二级报警故障。", "3", "三级故障", "三级报警故障。")},
	"gb32960.alarm.general_alarm_flag": {Label: "通用报警标志", Description: "通用报警位图。"},
	"gb32960.alarm.battery_faults":     {Label: "可充电储能装置故障码", Description: "动力电池相关故障码列表。"},
	"gb32960.alarm.motor_faults":       {Label: "驱动电机故障码", Description: "驱动电机相关故障码列表。"},
	"gb32960.alarm.engine_faults":      {Label: "发动机故障码", Description: "发动机相关故障码列表。"},
	"gb32960.alarm.other_faults":       {Label: "其他故障码", Description: "其他故障码列表。"},

	"gb32960.gd_fc_stack.stack_count":                 {Label: "电堆数量", Description: "本包包含的电堆数量。"},
	"gb32960.gd_fc_stack.engine_work_state":           {Label: "发动机工作状态", Description: "燃料电池发动机工作状态。"},
	"gb32960.gd_fc_stack.stack_water_outlet_temp_c":   {Label: "电堆出水温度", Unit: "℃", Description: "电堆冷却水出口温度。"},
	"gb32960.gd_fc_stack.hydrogen_inlet_pressure_kpa": {Label: "氢气入口压力", Unit: "kPa", Description: "电堆氢气入口压力。"},
	"gb32960.gd_fc_stack.air_inlet_pressure_kpa":      {Label: "空气入口压力", Unit: "kPa", Description: "电堆空气入口压力。"},
	"gb32960.gd_fc_stack.air_inlet_temp_c":            {Label: "空气入口温度", Unit: "℃", Description: "电堆空气入口温度。"},
	"gb32960.gd_fc_stack.max_cell_voltage_v":          {Label: "单体最高电压", Unit: "V", Description: "本电堆单体最高电压。"},
	"gb32960.gd_fc_stack.min_cell_voltage_v":          {Label: "单体最低电压", Unit: "V", Description: "本电堆单体最低电压。"},
	"gb32960.gd_fc_stack.avg_cell_voltage_v":          {Label: "单体平均电压", Unit: "V", Description: "本电堆单体平均电压。"},
	"gb32960.gd_fc_stack.cell_count":                  {Label: "单体总数", Description: "电堆单体总数量。"},
	"gb32960.gd_fc_stack.frame_cell_start":            {Label: "本帧单体起始序号", Description: "当前分段电压起始单体序号。"},
	"gb32960.gd_fc_stack.frame_cell_count":            {Label: "本帧单体数量", Description: "当前分段包含的单体数量。"},
	"gb32960.gd_fc_stack.frame_cell_voltages_v":       {Label: "本帧单体电压列表", Unit: "V", Description: "当前分段的单体电压数组；未跨帧合并时不代表完整电堆快照。"},

	"gb32960.gd_fc_dcdc.input_voltage_v":   {Label: "输入电压", Unit: "V", Description: "DC/DC 输入电压。"},
	"gb32960.gd_fc_dcdc.input_current_a":   {Label: "输入电流", Unit: "A", Description: "DC/DC 输入电流。"},
	"gb32960.gd_fc_dcdc.output_voltage_v":  {Label: "输出电压", Unit: "V", Description: "DC/DC 输出电压。"},
	"gb32960.gd_fc_dcdc.output_current_a":  {Label: "输出电流", Unit: "A", Description: "DC/DC 输出电流。"},
	"gb32960.gd_fc_dcdc.controller_temp_c": {Label: "控制器温度", Unit: "℃", Description: "DC/DC 控制器温度。"},

	"gb32960.gd_fc_air_conditioner.status":                     {Label: "空调状态", Description: "空调工作状态。", ValueMappings: enumMappings("0", "关闭", "空调关闭。", "1", "启动", "空调启动。", "254", "异常", "协议异常值。", "255", "无效", "协议无效值。")},
	"gb32960.gd_fc_air_conditioner.power_kw":                   {Label: "空调功率", Unit: "kW", Description: "空调消耗功率。"},
	"gb32960.gd_fc_air_conditioner.compressor_input_voltage_v": {Label: "压缩机输入电压", Unit: "V", Description: "空调压缩机输入电压。"},

	"gb32960.gd_fc_vehicle_info.collision_alarm":      {Label: "碰撞报警", Description: "碰撞报警状态。", ValueMappings: enumMappings("0", "无碰撞报警", "当前无碰撞报警。", "1", "有碰撞报警", "当前有碰撞报警。", "254", "异常", "协议异常值。", "255", "无效", "协议无效值。")},
	"gb32960.gd_fc_vehicle_info.ambient_temp_c":       {Label: "环境温度", Unit: "℃", Description: "车辆环境温度。"},
	"gb32960.gd_fc_vehicle_info.ambient_pressure_kpa": {Label: "环境压力", Unit: "kPa", Description: "车辆环境压力。"},
	"gb32960.gd_fc_vehicle_info.hydrogen_mass_kg":     {Label: "车载氢量", Unit: "kg", Description: "当前车载氢气质量。"},
}

func canonicalGB32960ReferenceKey(sourceField string) string {
	sourceField = strings.ToLower(strings.TrimSpace(sourceField))
	if !strings.HasPrefix(sourceField, "gb32960.") {
		return sourceField
	}
	if strings.HasPrefix(sourceField, "gb32960.drive_motor.") {
		return "gb32960.drive_motor." + lastSourcePart(sourceField)
	}
	if strings.HasPrefix(sourceField, "gb32960.gd_fc_stack.") {
		return "gb32960.gd_fc_stack." + lastSourcePart(sourceField)
	}
	return sourceField
}

func lastSourcePart(sourceField string) string {
	if index := strings.LastIndexByte(sourceField, '.'); index >= 0 && index+1 < len(sourceField) {
		return sourceField[index+1:]
	}
	return sourceField
}

func gb32960ReferenceForSource(sourceField string) (gb32960FieldReference, bool) {
	reference, ok := gb32960FieldReferences[canonicalGB32960ReferenceKey(sourceField)]
	if !ok {
		return gb32960FieldReference{}, false
	}
	reference.ValueMappings = append([]MetricValueMapping(nil), reference.ValueMappings...)
	return reference, true
}

func protocolDisplayValue(sourceField string, value any) string {
	reference, ok := gb32960ReferenceForSource(sourceField)
	if !ok || len(reference.ValueMappings) == 0 || value == nil {
		return ""
	}
	raw := metricMappingValue(value)
	for _, mapping := range reference.ValueMappings {
		if mapping.Value == raw {
			return fmt.Sprintf("%s（%s）", mapping.Label, raw)
		}
	}
	return fmt.Sprintf("未知状态（%s）", raw)
}

func metricMappingValue(value any) string {
	switch typed := value.(type) {
	case json.Number:
		return typed.String()
	case float64:
		if typed == float64(int64(typed)) {
			return strconv.FormatInt(int64(typed), 10)
		}
		return strconv.FormatFloat(typed, 'f', -1, 64)
	case float32:
		return strconv.FormatFloat(float64(typed), 'f', -1, 32)
	case int:
		return strconv.Itoa(typed)
	case int8:
		return strconv.FormatInt(int64(typed), 10)
	case int16:
		return strconv.FormatInt(int64(typed), 10)
	case int32:
		return strconv.FormatInt(int64(typed), 10)
	case int64:
		return strconv.FormatInt(typed, 10)
	case uint:
		return strconv.FormatUint(uint64(typed), 10)
	case uint8:
		return strconv.FormatUint(uint64(typed), 10)
	case uint16:
		return strconv.FormatUint(uint64(typed), 10)
	case uint32:
		return strconv.FormatUint(uint64(typed), 10)
	case uint64:
		return strconv.FormatUint(typed, 10)
	default:
		return strings.TrimSpace(fmt.Sprint(value))
	}
}

func enrichMetricDefinitions(definitions []MetricDefinition) []MetricDefinition {
	result := make([]MetricDefinition, len(definitions))
	copy(result, definitions)
	for index := range result {
		definition := &result[index]
		sourceField := definition.SourceFields["GB32960"]
		reference, ok := gb32960ReferenceForSource(sourceField)
		if !ok {
			continue
		}
		if len(definition.Protocols) == 1 && strings.EqualFold(definition.Protocols[0], "GB32960") {
			definition.Label = reference.Label
			definition.Description = reference.Description
			definition.Unit = reference.Unit
		}
		definition.ValueMappings = reference.ValueMappings
	}
	return result
}
