package businesserr

import (
	"fmt"
	"github.com/go-kratos/kratos/v2/errors"
	"strings"
	err2 "voucher/api/err"
)

// 定义错误码常量
// https://pay.weixin.qq.com/doc/v3/merchant/4012463767
const (
	SYSTEM_ERROR ErrCode = "SYSTEM_ERROR"
	SIGN_ERROR   ErrCode = "SIGN_ERROR"

	APPID_MCHID_NOT_MATCH ErrCode = "APPID_MCHID_NOT_MATCH"
	INVALID_REQUEST       ErrCode = "INVALID_REQUEST"
	PARAM_ERROR           ErrCode = "PARAM_ERROR"
	MCH_NOT_EXISTS        ErrCode = "MCH_NOT_EXISTS"
	NOT_ENOUGH            ErrCode = "NOT_ENOUGH"
	REQUEST_BLOCKED       ErrCode = "REQUEST_BLOCKED"
	RULE_LIMIT            ErrCode = "RULE_LIMIT"
	USER_ACCOUNT_ABNORMAL ErrCode = "USER_ACCOUNT_ABNORMAL"
	RESOURCE_NOT_EXISTS   ErrCode = "RESOURCE_NOT_EXISTS"
	FREQUENCY_LIMITED     ErrCode = "FREQUENCY_LIMITED"
)

const (
	BATCH_NOT_STARTED ErrCode = "BATCH_NOT_STARTED"
	BATCH_ENDED       ErrCode = "BATCH_ENDED"
)

// CmbAPIErrorMap 定义错误映射，方便根据错误码获取错误信息
var CmbAPIErrorMap = map[ErrCode][]CmbAPIError{

	SYSTEM_ERROR: {
		{
			StatusCode:   500,
			ErrorCode:    SYSTEM_ERROR,
			Description:  "系统异常，请稍后重试",
			Hint:         "请稍后重试",
			ThirdErrCode: ThirdErrCodeDefault,
		},
	},
	SIGN_ERROR: {
		{
			StatusCode:   401,
			ErrorCode:    SIGN_ERROR,
			Description:  "验证不通过",
			Hint:         "请参阅 签名常见问题",
			ThirdErrCode: ThirdErrCodeDefault,
		},
	},

	APPID_MCHID_NOT_MATCH: {
		{
			StatusCode:   400,
			ErrorCode:    APPID_MCHID_NOT_MATCH,
			Description:  "商户号与AppID不匹配",
			Hint:         "调用接口的商户号需与接口传入的AppID有绑定关系，请参考常见问题Q4",
			ThirdErrCode: ThirdErrCodeDefault,
		},
	},
	INVALID_REQUEST: {
		{
			StatusCode:   400,
			ErrorCode:    INVALID_REQUEST,
			Description:  "HTTP 请求不符合微信支付 APIv3 接口规则",
			Hint:         "请参阅 接口规则",
			ThirdErrCode: ThirdErrCodeDefault,
		},
		{
			StatusCode:   400,
			ErrorCode:    INVALID_REQUEST,
			Description:  "OpenID与AppID不匹配",
			Hint:         "OpenID与AppID需有对应关系",
			ThirdErrCode: ThirdErrCodeAppIDOpenIDMismatch,
		},
		{
			StatusCode:   400,
			ErrorCode:    INVALID_REQUEST,
			Description:  "非法的商户号",
			Hint:         "请检查商户号准确性",
			ThirdErrCode: ThirdErrCodeDefault,
		},
		{
			StatusCode:   400,
			ErrorCode:    INVALID_REQUEST,
			Description:  "调用频率过高",
			Hint:         "请降低API调用频率",
			ThirdErrCode: ThirdErrCodeCallHigh,
		},
		{
			StatusCode:   400,
			ErrorCode:    INVALID_REQUEST,
			Description:  "活动已结束或未激活",
			Hint:         "请检查批次状态",
			ThirdErrCode: ThirdErrCodeBatchEnded, //前置判断时间处理一下
		},
		{
			StatusCode:   400,
			ErrorCode:    INVALID_REQUEST,
			Description:  "批次信息获取失败，请确认参数是否有误",
			Hint:         "请检查创建商户号与批次号的对应关系",
			ThirdErrCode: ThirdErrCodeDefault,
		},
	},
	PARAM_ERROR: {
		{
			StatusCode:   400,
			ErrorCode:    PARAM_ERROR,
			Description:  "参数错误",
			Hint:         "请根据错误提示正确传入参数",
			ThirdErrCode: ThirdErrCodeDefault,
		},

		{
			StatusCode:   400,
			ErrorCode:    PARAM_ERROR,
			Description:  "AppID必填",
			Hint:         "请输入AppID",
			ThirdErrCode: ThirdErrCodeDefault,
		},
		{
			StatusCode:   400,
			ErrorCode:    PARAM_ERROR,
			Description:  "OpenID必填",
			Hint:         "请输入OpenID",
			ThirdErrCode: ThirdErrCodeDefault,
		},
		{
			StatusCode:   400,
			ErrorCode:    PARAM_ERROR,
			Description:  "批次号必填",
			Hint:         "请输入批次号",
			ThirdErrCode: ThirdErrCodeDefault,
		},
		{
			StatusCode:   400,
			ErrorCode:    PARAM_ERROR,
			Description:  "商户号必填",
			Hint:         "请输入商户号",
			ThirdErrCode: ThirdErrCodeDefault,
		},
		{
			StatusCode:   400,
			ErrorCode:    PARAM_ERROR,
			Description:  "非法的批次状态",
			Hint:         "请检查批次状态，仅支持发放状态为“运营中”的代金券批次",
			ThirdErrCode: ThirdErrCodeDefault,
		},
	},
	MCH_NOT_EXISTS: {
		{
			StatusCode:   403,
			ErrorCode:    MCH_NOT_EXISTS,
			Description:  "商户号不合法",
			Hint:         "请检查商户号准确性",
			ThirdErrCode: ThirdErrCodeDefault,
		},
	},
	NOT_ENOUGH: {
		{
			StatusCode:   403,
			ErrorCode:    NOT_ENOUGH,
			Description:  "批次预算不足",
			Hint:         "批次预算已发放完，请补充批次预算",
			ThirdErrCode: ThirdErrCodeAdvanceFundingNotEnough,
		},
		{
			StatusCode:   403,
			ErrorCode:    NOT_ENOUGH,
			Description:  "发券超过单天限额",
			Hint:         "已超过该批次设置的单天发放限制额度，无法发放",
			ThirdErrCode: ThirdErrCodeDailyLimit,
		},
		{
			StatusCode:   403,
			ErrorCode:    NOT_ENOUGH,
			Description:  "账户余额不足，请充值",
			Hint:         "商户号余额不足，无法继续发券，请充值",
			ThirdErrCode: ThirdErrCodeAdvanceFundingNotEnough,
		},
		{
			StatusCode:   403,
			ErrorCode:    NOT_ENOUGH,
			Description:  "批次预算耗尽",
			Hint:         "该批次的预算已经耗尽",
			ThirdErrCode: ThirdErrCodeAdvanceFundingNotEnough,
		},
	},
	REQUEST_BLOCKED: {
		{
			StatusCode:   403,
			ErrorCode:    REQUEST_BLOCKED,
			Description:  "商户无权发券",
			Hint:         "该批次不支持其他商户发放，请参考常见问题Q1",
			ThirdErrCode: ThirdErrCodeDefault,
		},
		{
			StatusCode:   403,
			ErrorCode:    REQUEST_BLOCKED,
			Description:  "批次不支持跨商户发券",
			Hint:         "该批次不支持其他商户发放，请参考常见问题Q1",
			ThirdErrCode: ThirdErrCodeDefault,
		},
		{
			StatusCode:   403,
			ErrorCode:    REQUEST_BLOCKED,
			Description:  "用户被限领拦截",
			Hint:         "该用户已达到该批次的领取上限，请参考常见问题Q6",
			ThirdErrCode: ThirdErrCodeUserParticipationExceeded,
		},
		{
			StatusCode:   403,
			ErrorCode:    REQUEST_BLOCKED,
			Description:  "不能在API渠道发放",
			Hint:         "请检查批次信息，仅支持发放微信支付代金券，不支持发放立减与折扣",
			ThirdErrCode: ThirdErrCodeDefault,
		},
		{
			StatusCode:   403,
			ErrorCode:    REQUEST_BLOCKED,
			Description:  "不支持指定面额发券",
			Hint:         "仅在发券时指定面额及门槛的场景才生效，常规发券场景请勿传入该信息",
			ThirdErrCode: ThirdErrCodeDefault,
		},
		{
			StatusCode:   403,
			ErrorCode:    REQUEST_BLOCKED,
			Description:  "仅在广告场景下发放批次",
			Hint:         "该批次已在朋友圈广告发放，不支持在其他渠道发放",
			ThirdErrCode: ThirdErrCodeDefault,
		},
	},
	RULE_LIMIT: {
		{
			StatusCode:   403,
			ErrorCode:    RULE_LIMIT,
			Description:  "用户已达最大领券次数",
			Hint:         "该用户已达到该批次的领取上限，请参考常见问题Q6",
			ThirdErrCode: ThirdErrCodeUserParticipationExceeded,
		},
		{
			StatusCode:   403,
			ErrorCode:    RULE_LIMIT,
			Description:  "被自然人规则拦截",
			Hint:         "该自然人已达到该批次的领取上限，请参考常见问题Q6",
			ThirdErrCode: ThirdErrCodeUserAccountAbnormal,
		},
	},
	USER_ACCOUNT_ABNORMAL: {
		{
			StatusCode:   403,
			ErrorCode:    USER_ACCOUNT_ABNORMAL,
			Description:  "用户非法",
			Hint:         "用户命中微信支付风控模型，请参考常见问题Q5",
			ThirdErrCode: ThirdErrCodeUserAccountFrozen,
		},
	},
	RESOURCE_NOT_EXISTS: {
		{
			StatusCode:   404,
			ErrorCode:    RESOURCE_NOT_EXISTS,
			Description:  "批次不存在",
			Hint:         "请检查批次及制券商户号信息",
			ThirdErrCode: ThirdErrCodeDefault,
		},
	},
	FREQUENCY_LIMITED: {
		{
			StatusCode:   429,
			ErrorCode:    FREQUENCY_LIMITED,
			Description:  "当前请求人数过多，请稍后重试",
			Hint:         "请降低API调用频率",
			ThirdErrCode: ThirdErrCodeCallHigh,
		},
	},
}

// 使用常量定义错误描述，减少硬编码
const (
	ErrorWechatUserIllegal                       = "用户非法"
	ErrorWechatAppIDMchIDMismatch                = "商户号与AppID不匹配"
	ErrorWechatOpenIDAppIDMismatch               = "OpenID与AppID不匹配"
	ErrorWechatInvalidMerchantID                 = "非法的商户号"
	ErrorWechatHighFrequency                     = "调用频率过高"
	ErrorWechatActivityInactive                  = "活动已结束或未激活"
	ErrorWechatBatchInfoError                    = "批次信息获取失败，请确认参数是否有误"
	ErrorWechatAppIDRequired                     = "AppID必填"
	ErrorWechatOpenIDRequired                    = "OpenID必填"
	ErrorWechatBatchIDRequired                   = "批次号必填"
	ErrorWechatMerchantIDRequired                = "商户号必填"
	ErrorWechatInvalidBatchStatus                = "非法的批次状态"
	ErrorWechatMchNotExists                      = "商户号不合法"
	ErrorWechatBatchBudgetInsufficient           = "批次预算不足"
	ErrorWechatDailyLimitExceeded                = "发券超过单天限额"
	ErrorWechatAccountBalanceInsufficient        = "账户余额不足，请充值"
	ErrorWechatBatchBudgetDepleted               = "批次预算耗尽"
	ErrorWechatMerchantNoPermission              = "商户无权发券"
	ErrorWechatCrossMerchantNotSupported         = "批次不支持跨商户发券"
	ErrorWechatUserReceiveLimit                  = "用户被限领拦截"
	ErrorWechatAPIChannelNotSupported            = "不能在API渠道发放"
	ErrorWechatSpecifiedDenominationNotSupported = "不支持指定面额发券"
	ErrorWechatOnlyAdvertisingBatch              = "仅在广告场景下发放批次"
	ErrorWechatUserMaxCoupons                    = "用户已达最大领券次数"
	ErrorWechatNaturalPersonRuleBlocked          = "被自然人规则拦截"
	ErrorWechatResourceNotExists                 = "批次不存在"
	ErrorWechatFrequencyLimited                  = "当前请求人数过多，请稍后重试"
	ErrorWechatAccountFail                       = "该用户账号异常，无法领券。商家可联系微信支付或让用户联系微信支付客服处理。"
)

// WechatError 映射错误描述到具体的错误处理
var WechatError = map[string]*errors.Error{
	ErrorWechatUserIllegal:                       err2.ErrorWechatUserIllegal(ErrorWechatUserIllegal),
	ErrorWechatAppIDMchIDMismatch:                err2.ErrorWechatAppIDMchIDMismatch(ErrorWechatAppIDMchIDMismatch),
	ErrorWechatOpenIDAppIDMismatch:               err2.ErrorWechatOpenIDAppIDMismatch(ErrorWechatOpenIDAppIDMismatch),
	ErrorWechatInvalidMerchantID:                 err2.ErrorWechatInvalidMerchantID(ErrorWechatInvalidMerchantID),
	ErrorWechatHighFrequency:                     err2.ErrorWechatHighFrequency(ErrorWechatHighFrequency),
	ErrorWechatActivityInactive:                  err2.ErrorWechatActivityInactive(ErrorWechatActivityInactive),
	ErrorWechatBatchInfoError:                    err2.ErrorWechatBatchInfoError(ErrorWechatBatchInfoError),
	ErrorWechatAppIDRequired:                     err2.ErrorWechatAppIDRequired(ErrorWechatAppIDRequired),
	ErrorWechatOpenIDRequired:                    err2.ErrorWechatOpenIDRequired(ErrorWechatOpenIDRequired),
	ErrorWechatBatchIDRequired:                   err2.ErrorWechatBatchIDRequired(ErrorWechatBatchIDRequired),
	ErrorWechatMerchantIDRequired:                err2.ErrorWechatMerchantIDRequired(ErrorWechatMerchantIDRequired),
	ErrorWechatInvalidBatchStatus:                err2.ErrorWechatInvalidBatchStatus(ErrorWechatInvalidBatchStatus),
	ErrorWechatMchNotExists:                      err2.ErrorWechatMchNotExists(ErrorWechatMchNotExists),
	ErrorWechatBatchBudgetInsufficient:           err2.ErrorWechatBatchBudgetInsufficient(ErrorWechatBatchBudgetInsufficient),
	ErrorWechatDailyLimitExceeded:                err2.ErrorWechatDailyLimitExceeded(ErrorWechatDailyLimitExceeded),
	ErrorWechatAccountBalanceInsufficient:        err2.ErrorWechatAccountBalanceInsufficient(ErrorWechatAccountBalanceInsufficient),
	ErrorWechatBatchBudgetDepleted:               err2.ErrorWechatBatchBudgetDepleted(ErrorWechatBatchBudgetDepleted),
	ErrorWechatMerchantNoPermission:              err2.ErrorWechatMerchantNoPermission(ErrorWechatMerchantNoPermission),
	ErrorWechatCrossMerchantNotSupported:         err2.ErrorWechatCrossMerchantNotSupported(ErrorWechatCrossMerchantNotSupported),
	ErrorWechatUserReceiveLimit:                  err2.ErrorWechatUserReceiveLimit(ErrorWechatUserReceiveLimit),
	ErrorWechatAPIChannelNotSupported:            err2.ErrorWechatAPIChannelNotSupported(ErrorWechatAPIChannelNotSupported),
	ErrorWechatSpecifiedDenominationNotSupported: err2.ErrorWechatSpecifiedDenominationNotSupported(ErrorWechatSpecifiedDenominationNotSupported),
	ErrorWechatOnlyAdvertisingBatch:              err2.ErrorWechatOnlyAdvertisingBatch(ErrorWechatOnlyAdvertisingBatch),
	ErrorWechatUserMaxCoupons:                    err2.ErrorWechatUserMaxCoupons(ErrorWechatUserMaxCoupons),
	ErrorWechatNaturalPersonRuleBlocked:          err2.ErrorWechatNaturalPersonRuleBlocked(ErrorWechatNaturalPersonRuleBlocked),
	ErrorWechatResourceNotExists:                 err2.ErrorWechatResourceNotExists(ErrorWechatResourceNotExists),
	ErrorWechatFrequencyLimited:                  err2.ErrorWechatFrequencyLimited(ErrorWechatFrequencyLimited),
	ErrorWechatAccountFail:                       err2.ErrorWechatAccountFail(ErrorWechatAccountFail),
}

type WechatErrBody struct {
	Code    ErrCode `json:"Code"`
	Message string  `json:"Message"`
}

// GetWechatError 根据错误描述获取具体的错误处理
func (s WechatErrBody) GetWechatError() *errors.Error {
	lowerDesc := strings.ToLower(s.Message)
	for desc, err := range WechatError {
		if strings.ToLower(desc) == lowerDesc {
			return err
		}
	}
	return err2.ErrorWechatFAIL(fmt.Sprintf("微信返回错误:%s", s.Message))
}
