package cardobservation

import (
	"strings"

	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
)

// NetworkObservation 是领域层接收的标准 Gateway 网络观测。
type NetworkObservation struct {
	CardID        uint
	GatewayStatus string
	GatewayExtend string
	GatewayIMEI   string
	Metadata      ObservationMetadata
}

// CardNetworkSnapshot 是网络规则需要的最小卡快照。
type CardNetworkSnapshot struct {
	CardID        uint
	NetworkStatus int
	StopReason    string
	IsStandalone  bool
	EnablePolling bool
}

// NetworkDecision 描述一次网络观测可安全持久化的最终值。
type NetworkDecision struct {
	StatusKnown       bool
	StatusChanged     bool
	BeforeStatus      int
	AfterStatus       int
	GatewayExtend     string
	GatewayIMEI       string
	UpdateIMEI        bool
	StopReason        string
	StopReasonChanged bool
	StopPolling       bool
}

// ApplyNetwork 应用 Gateway 状态映射、运营商停机原因和独立风险卡规则。
func ApplyNetwork(snapshot CardNetworkSnapshot, observation NetworkObservation) (NetworkDecision, error) {
	if err := validateObservationMetadata(observation.CardID, observation.Metadata); err != nil {
		return NetworkDecision{}, err
	}
	if snapshot.NetworkStatus != constants.NetworkStatusOffline && snapshot.NetworkStatus != constants.NetworkStatusOnline {
		return NetworkDecision{}, errors.New(errors.CodeInvalidStatus, "卡网络状态无效")
	}
	status, known := MapGatewayNetworkStatus(observation.GatewayStatus, observation.GatewayExtend)
	extend := strings.TrimSpace(observation.GatewayExtend)
	imei := strings.TrimSpace(observation.GatewayIMEI)
	decision := NetworkDecision{
		StatusKnown: known, BeforeStatus: snapshot.NetworkStatus, AfterStatus: snapshot.NetworkStatus,
		GatewayExtend: extend, GatewayIMEI: imei, UpdateIMEI: imei != "", StopReason: snapshot.StopReason,
		StopPolling: snapshot.EnablePolling && ShouldStopPollingForRisk(snapshot.IsStandalone, extend),
	}
	if !known {
		return decision, nil
	}
	decision.AfterStatus = status
	decision.StatusChanged = status != snapshot.NetworkStatus
	if decision.StatusChanged && status == constants.NetworkStatusOffline && snapshot.StopReason == "" &&
		strings.TrimSpace(observation.GatewayStatus) == constants.GatewayCardStatusStopped {
		decision.StopReason = constants.StopReasonCarrierStopped
		decision.StopReasonChanged = true
	}
	return decision, nil
}

// MapGatewayNetworkStatus 将 Gateway 状态稳定映射为本地网络状态。
func MapGatewayNetworkStatus(cardStatus, extend string) (int, bool) {
	status := strings.TrimSpace(cardStatus)
	ext := strings.TrimSpace(extend)
	switch status {
	case constants.GatewayCardStatusNormal:
		return constants.NetworkStatusOnline, true
	case constants.GatewayCardStatusStopped, constants.GatewayCardStatusReady:
		return constants.NetworkStatusOffline, true
	}
	if ext == constants.GatewayCardExtendPendingActivation {
		return constants.NetworkStatusOffline, true
	}
	return constants.NetworkStatusOffline, false
}

// ShouldStopPollingForRisk 判断独立卡是否命中运营商风险终止状态。
func ShouldStopPollingForRisk(isStandalone bool, extend string) bool {
	return isStandalone && (extend == constants.GatewayCardExtendRiskStop || extend == constants.GatewayCardExtendCancelled)
}
