package recharge

import (
	"context"
	"fmt"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/store/postgres"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
	"github.com/break/junhong_cmp_fiber/pkg/payment"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

// ForceRechargeRequirement 强充要求信息
type ForceRechargeRequirement struct {
	NeedForceRecharge   bool   `json:"need_force_recharge"`   // 是否需要强充
	ForceRechargeAmount int64  `json:"force_recharge_amount"` // 强充金额（分）
	TriggerType         string `json:"trigger_type"`          // 触发类型: single_recharge/accumulated_recharge
	MinAmount           int64  `json:"min_amount"`            // 最小充值金额
	MaxAmount           int64  `json:"max_amount"`            // 最大充值金额
	CurrentAccumulated  int64  `json:"current_accumulated"`   // 当前累计充值
	Threshold           int64  `json:"threshold"`             // 佣金触发阈值
	Message             string `json:"message"`               // 提示信息
}

// WechatConfigServiceInterface 支付配置服务接口
type WechatConfigServiceInterface interface {
	GetActiveConfig(ctx context.Context) (*model.WechatConfig, error)
}

// Service 充值服务
// 负责资产钱包（IoT卡/设备）的充值订单创建、预检、支付回调处理等业务逻辑
type Service struct {
	db                          *gorm.DB
	assetWalletStore            *postgres.AssetWalletStore
	assetWalletTransactionStore *postgres.AssetWalletTransactionStore
	iotCardStore                *postgres.IotCardStore
	deviceStore                 *postgres.DeviceStore
	shopSeriesAllocationStore   *postgres.ShopSeriesAllocationStore
	packageSeriesStore          *postgres.PackageSeriesStore
	commissionRecordStore       *postgres.CommissionRecordStore
	wechatConfigService         WechatConfigServiceInterface
	paymentLoader               payment.PaymentConfigLoader
	logger                      *zap.Logger
}

// New 创建充值服务实例
func New(
	db *gorm.DB,
	assetWalletStore *postgres.AssetWalletStore,
	assetWalletTransactionStore *postgres.AssetWalletTransactionStore,
	iotCardStore *postgres.IotCardStore,
	deviceStore *postgres.DeviceStore,
	shopSeriesAllocationStore *postgres.ShopSeriesAllocationStore,
	packageSeriesStore *postgres.PackageSeriesStore,
	commissionRecordStore *postgres.CommissionRecordStore,
	wechatConfigService WechatConfigServiceInterface,
	paymentLoader payment.PaymentConfigLoader,
	logger *zap.Logger,
) *Service {
	return &Service{
		db:                          db,
		assetWalletStore:            assetWalletStore,
		assetWalletTransactionStore: assetWalletTransactionStore,
		iotCardStore:                iotCardStore,
		deviceStore:                 deviceStore,
		shopSeriesAllocationStore:   shopSeriesAllocationStore,
		packageSeriesStore:          packageSeriesStore,
		commissionRecordStore:       commissionRecordStore,
		wechatConfigService:         wechatConfigService,
		paymentLoader:               paymentLoader,
		logger:                      logger,
	}
}

// GetRechargeCheck 充值预检
// 返回强充要求、金额限制等信息
func (s *Service) GetRechargeCheck(ctx context.Context, resourceType string, resourceID uint) (*ForceRechargeRequirement, error) {
	// 验证资源类型
	if resourceType != "iot_card" && resourceType != "device" {
		return nil, errors.New(errors.CodeInvalidParam, "无效的资源类型")
	}

	// 验证资源是否存在
	if resourceType == "iot_card" {
		if _, err := s.iotCardStore.GetByID(ctx, resourceID); err != nil {
			if err == gorm.ErrRecordNotFound {
				return nil, errors.New(errors.CodeIotCardNotFound, "IoT卡不存在")
			}
			return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询IoT卡失败")
		}
	} else {
		if _, err := s.deviceStore.GetByID(ctx, resourceID); err != nil {
			if err == gorm.ErrRecordNotFound {
				return nil, errors.New(errors.CodeNotFound, "设备不存在")
			}
			return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询设备失败")
		}
	}

	return s.checkForceRechargeRequirement(ctx, resourceType, resourceID)
}

// checkForceRechargeRequirement 检查强充要求
// 根据资源类型和ID检查是否需要强制充值指定金额
func (s *Service) checkForceRechargeRequirement(ctx context.Context, resourceType string, resourceID uint) (*ForceRechargeRequirement, error) {
	result := &ForceRechargeRequirement{
		NeedForceRecharge: false,
		MinAmount:         constants.AssetRechargeMinAmount,
		MaxAmount:         constants.AssetRechargeMaxAmount,
		Message:           "无强充要求，可自由充值",
	}

	var seriesID *uint
	var shopID *uint
	var accumulatedRecharge int64
	var firstCommissionPaid bool

	if resourceType == "iot_card" {
		card, err := s.iotCardStore.GetByID(ctx, resourceID)
		if err != nil {
			if err == gorm.ErrRecordNotFound {
				return nil, errors.New(errors.CodeIotCardNotFound, "IoT卡不存在")
			}
			return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询IoT卡失败")
		}
		seriesID = card.SeriesID
		shopID = card.ShopID
		if seriesID != nil {
			accumulatedRecharge = card.GetAccumulatedRechargeBySeries(*seriesID)
			firstCommissionPaid = card.IsFirstRechargeTriggeredBySeries(*seriesID)
		}
	} else if resourceType == "device" {
		device, err := s.deviceStore.GetByID(ctx, resourceID)
		if err != nil {
			if err == gorm.ErrRecordNotFound {
				return nil, errors.New(errors.CodeNotFound, "设备不存在")
			}
			return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询设备失败")
		}
		seriesID = device.SeriesID
		shopID = device.ShopID
		if seriesID != nil {
			accumulatedRecharge = device.GetAccumulatedRechargeBySeries(*seriesID)
			firstCommissionPaid = device.IsFirstRechargeTriggeredBySeries(*seriesID)
		}
	}

	result.CurrentAccumulated = accumulatedRecharge

	if seriesID == nil || shopID == nil {
		return result, nil
	}

	series, err := s.packageSeriesStore.GetByID(ctx, *seriesID)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return result, nil
		}
		return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询套餐系列失败")
	}

	config, err := series.GetOneTimeCommissionConfig()
	if err != nil || config == nil || !config.Enable {
		return result, nil
	}

	result.Threshold = config.Threshold
	result.TriggerType = config.TriggerType

	if firstCommissionPaid {
		result.Message = "一次性佣金已发放，无强充要求"
		return result, nil
	}

	if config.TriggerType == model.OneTimeCommissionTriggerFirstRecharge {
		result.NeedForceRecharge = true
		result.ForceRechargeAmount = config.Threshold
		result.Message = fmt.Sprintf("首次充值必须充值%d分", config.Threshold)
	} else if config.EnableForceRecharge {
		result.NeedForceRecharge = true
		if config.ForceAmount > 0 {
			result.ForceRechargeAmount = config.ForceAmount
		} else {
			result.ForceRechargeAmount = config.Threshold
		}
		result.Message = fmt.Sprintf("每次充值必须充值%d分", result.ForceRechargeAmount)
	} else {
		result.Message = "累计充值模式，可自由充值"
	}

	return result, nil
}
