package envelope

import "strings"

func IsRealtimeTelemetryFrame(env FrameEnvelope) bool {
	if env.ParseStatus == ParseBadFrame {
		return false
	}
	switch env.Protocol {
	case ProtocolGB32960:
		command := strings.TrimSpace(env.MessageID)
		if command == "" && env.Parsed != nil {
			if header, ok := env.Parsed["header"].(map[string]any); ok {
				command = strings.TrimSpace(stringAny(header["command"]))
			}
		}
		if command != "" && !strings.EqualFold(command, "0x02") && !strings.EqualFold(command, "0x03") {
			return false
		}
		_, hasDataUnits := env.Parsed["data_units"]
		return hasDataUnits || hasGB32960ParsedTelemetryField(env) || hasRealtimeField(env)
	case ProtocolJT808:
		messageID := strings.TrimSpace(env.MessageID)
		if messageID != "" && !strings.EqualFold(messageID, "0x0200") {
			return false
		}
		if _, ok := env.Parsed["location"]; ok {
			return true
		}
		return hasParsedFieldPrefix(env, "jt808.location.") || hasRealtimeField(env)
	case ProtocolYutongMQTT:
		data, ok := env.Parsed["data"].(map[string]any)
		if ok && len(data) > 0 {
			return true
		}
		return hasParsedFieldPrefix(env, "yutong_mqtt.data.") ||
			hasParsedFieldPrefix(env, "yutong_mqtt.root.data.")
	default:
		return false
	}
}

func hasGB32960ParsedTelemetryField(env FrameEnvelope) bool {
	for field := range env.ParsedFields {
		if !strings.HasPrefix(field, "gb32960.") {
			continue
		}
		if strings.HasPrefix(field, "gb32960.header.") ||
			strings.HasPrefix(field, "gb32960.platform.") ||
			strings.HasPrefix(field, "gb32960.identity.") ||
			strings.HasPrefix(field, "gb32960.device_time.") {
			continue
		}
		return true
	}
	return false
}

// RequiresVehicleIdentity keeps platform/control frames out of vehicle identity
// quality metrics while preserving JT808's phone-centric registration/auth flow.
func RequiresVehicleIdentity(env FrameEnvelope) bool {
	if env.ParseStatus == ParseBadFrame {
		return false
	}
	switch env.Protocol {
	case ProtocolGB32960:
		return IsRealtimeTelemetryFrame(env)
	case ProtocolJT808:
		return true
	case ProtocolYutongMQTT:
		return IsRealtimeTelemetryFrame(env)
	default:
		return false
	}
}

func hasRealtimeField(env FrameEnvelope) bool {
	if env.Fields[FieldLatitude] != nil ||
		env.Fields[FieldLongitude] != nil ||
		env.Fields[FieldTotalMileageKM] != nil ||
		env.Fields[FieldSpeedKMH] != nil ||
		env.Fields[FieldSOCPercent] != nil {
		return true
	}
	for field := range env.ParsedFields {
		if strings.HasSuffix(field, ".latitude") ||
			strings.HasSuffix(field, ".longitude") ||
			strings.HasSuffix(field, ".total_mileage_km") ||
			strings.HasSuffix(field, ".speed_kmh") ||
			strings.HasSuffix(field, ".soc_percent") {
			return true
		}
	}
	return false
}

func hasParsedFieldPrefix(env FrameEnvelope, prefix string) bool {
	for field := range env.ParsedFields {
		if strings.HasPrefix(field, prefix) {
			return true
		}
	}
	return false
}

func stringAny(value any) string {
	if text, ok := value.(string); ok {
		return text
	}
	return ""
}
