package commission_calculation

import (
	"context"
	"fmt"
	"time"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/service/commission_stats"
	"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"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

type Service struct {
	db                          *gorm.DB
	commissionRecordStore       *postgres.CommissionRecordStore
	shopStore                   *postgres.ShopStore
	shopPackageAllocationStore  *postgres.ShopPackageAllocationStore
	shopSeriesAllocationStore   *postgres.ShopSeriesAllocationStore
	packageSeriesStore          *postgres.PackageSeriesStore
	iotCardStore                *postgres.IotCardStore
	deviceStore                 *postgres.DeviceStore
	agentWalletStore            *postgres.AgentWalletStore
	agentWalletTransactionStore *postgres.AgentWalletTransactionStore
	orderStore                  *postgres.OrderStore
	orderItemStore              *postgres.OrderItemStore
	packageStore                *postgres.PackageStore
	commissionStatsStore        *postgres.ShopSeriesCommissionStatsStore
	commissionStatsService      *commission_stats.Service
	logger                      *zap.Logger
}

func New(
	db *gorm.DB,
	commissionRecordStore *postgres.CommissionRecordStore,
	shopStore *postgres.ShopStore,
	shopPackageAllocationStore *postgres.ShopPackageAllocationStore,
	shopSeriesAllocationStore *postgres.ShopSeriesAllocationStore,
	packageSeriesStore *postgres.PackageSeriesStore,
	iotCardStore *postgres.IotCardStore,
	deviceStore *postgres.DeviceStore,
	agentWalletStore *postgres.AgentWalletStore,
	agentWalletTransactionStore *postgres.AgentWalletTransactionStore,
	orderStore *postgres.OrderStore,
	orderItemStore *postgres.OrderItemStore,
	packageStore *postgres.PackageStore,
	commissionStatsStore *postgres.ShopSeriesCommissionStatsStore,
	commissionStatsService *commission_stats.Service,
	logger *zap.Logger,
) *Service {
	return &Service{
		db:                          db,
		commissionRecordStore:       commissionRecordStore,
		shopStore:                   shopStore,
		shopPackageAllocationStore:  shopPackageAllocationStore,
		shopSeriesAllocationStore:   shopSeriesAllocationStore,
		packageSeriesStore:          packageSeriesStore,
		iotCardStore:                iotCardStore,
		deviceStore:                 deviceStore,
		agentWalletStore:            agentWalletStore,
		agentWalletTransactionStore: agentWalletTransactionStore,
		orderStore:                  orderStore,
		orderItemStore:              orderItemStore,
		packageStore:                packageStore,
		commissionStatsStore:        commissionStatsStore,
		commissionStatsService:      commissionStatsService,
		logger:                      logger,
	}
}

func (s *Service) CalculateCommission(ctx context.Context, orderID uint) error {
	return s.db.Transaction(func(tx *gorm.DB) error {
		order, err := s.orderStore.GetByID(ctx, orderID)
		if err != nil {
			return errors.Wrap(errors.CodeDatabaseError, err, "获取订单失败")
		}

		if order.CommissionStatus == model.CommissionStatusCompleted || order.CommissionStatus == model.CommissionStatusPendingReview {
			s.logger.Warn("订单佣金流程已结束，跳过",
				zap.String("order_id", fmt.Sprint(orderID)),
				zap.Int("commission_status", order.CommissionStatus),
			)
			return nil
		}

		costDiffRecords, err := s.CalculateCostDiffCommission(ctx, order)
		if err != nil {
			return errors.Wrap(errors.CodeInternalError, err, "计算成本价差佣金失败")
		}

		if err := s.persistCommissionRecordsInTx(ctx, tx, costDiffRecords); err != nil {
			return err
		}

		// 代购订单不触发一次性佣金和累计充值更新
		if !order.IsPurchaseOnBehalf {
			if order.OrderType == model.OrderTypeSingleCard && order.IotCardID != nil {
				if err := s.triggerOneTimeCommissionForCardInTx(ctx, tx, order, *order.IotCardID); err != nil {
					return errors.Wrap(errors.CodeInternalError, err, "触发单卡一次性佣金失败")
				}
			} else if order.OrderType == model.OrderTypeDevice && order.DeviceID != nil {
				if err := s.triggerOneTimeCommissionForDeviceInTx(ctx, tx, order, *order.DeviceID); err != nil {
					return errors.Wrap(errors.CodeInternalError, err, "触发设备一次性佣金失败")
				}
			}
		}

		commissionStatus, commissionResult, err := s.resolveOrderCommissionOutcomeInTx(tx, order.ID)
		if err != nil {
			return err
		}

		if err := tx.Model(&model.Order{}).Where("id = ?", orderID).Updates(map[string]any{
			"commission_status": commissionStatus,
			"commission_result": commissionResult,
		}).Error; err != nil {
			return errors.Wrap(errors.CodeDatabaseError, err, "更新订单佣金结果失败")
		}

		return nil
	})
}

func (s *Service) CalculateCostDiffCommission(ctx context.Context, order *model.Order) ([]*model.CommissionRecord, error) {
	var records []*model.CommissionRecord

	if order.SellerShopID == nil {
		return records, nil
	}

	if order.SeriesID == nil {
		s.logger.Warn("订单缺少系列ID，跳过成本价差佣金计算", zap.Uint("order_id", order.ID))
		return records, nil
	}

	sellerShop, err := s.shopStore.GetByID(ctx, *order.SellerShopID)
	if err != nil {
		return nil, errors.Wrap(errors.CodeDatabaseError, err, "获取销售店铺失败")
	}

	sellerProfit, shouldCalculateSellerProfit := calculateSellerProfit(order)
	if !shouldCalculateSellerProfit {
		s.logger.Warn("订单缺少实际支付金额，跳过终端销售代理成本价差佣金计算",
			zap.Uint("order_id", order.ID),
			zap.String("source", order.Source),
			zap.String("payment_method", order.PaymentMethod),
			zap.String("buyer_type", order.BuyerType),
			zap.String("purchase_role", order.PurchaseRole),
			zap.Int64("total_amount", order.TotalAmount),
			zap.Int64("seller_cost_price", order.SellerCostPrice),
		)
	}
	if sellerProfit > 0 {
		records = append(records, &model.CommissionRecord{
			BaseModel: model.BaseModel{
				Creator: order.Creator,
				Updater: order.Updater,
			},
			ShopID:           *order.SellerShopID,
			OrderID:          order.ID,
			IotCardID:        order.IotCardID,
			DeviceID:         order.DeviceID,
			CommissionSource: model.CommissionSourceCostDiff,
			Amount:           sellerProfit,
			Status:           constants.CommissionStatusReleased,
		})
	}

	// 获取订单明细以获取套餐ID（用于成本价查询）
	orderItems, err := s.orderItemStore.ListByOrderID(ctx, order.ID)
	if err != nil || len(orderItems) == 0 {
		s.logger.Warn("获取订单明细失败或订单无明细，跳过成本价差佣金计算", zap.Uint("order_id", order.ID), zap.Error(err))
		return records, nil
	}
	packageID := orderItems[0].PackageID

	childCostPrice := order.SellerCostPrice
	currentShopID := sellerShop.ParentID

	for currentShopID != nil && *currentShopID > 0 {
		currentShop, err := s.shopStore.GetByID(ctx, *currentShopID)
		if err != nil {
			s.logger.Error("获取上级店铺失败", zap.Uint("shop_id", *currentShopID), zap.Error(err))
			break
		}

		allocation, err := s.shopPackageAllocationStore.GetByShopAndPackage(ctx, currentShop.ID, packageID)
		if err != nil {
			s.logger.Warn("上级店铺未分配该套餐，佣金链断裂",
				zap.Uint("shop_id", currentShop.ID),
				zap.Uint("package_id", packageID),
				zap.Uint("order_id", order.ID))
			pendingRecord := &model.CommissionRecord{
				BaseModel: model.BaseModel{
					Creator: order.Creator,
					Updater: order.Updater,
				},
				ShopID:           currentShop.ID,
				OrderID:          order.ID,
				IotCardID:        order.IotCardID,
				DeviceID:         order.DeviceID,
				CommissionSource: model.CommissionSourceCostDiff,
				Amount:           0,
				Status:           constants.CommissionStatusPendingReview,
				Remark:           fmt.Sprintf("套餐系列[%d]未分配给该代理(shop_id=%d)，成本价差链路断裂，请人工核查", *order.SeriesID, currentShop.ID),
			}
			records = append(records, pendingRecord)
			break
		}

		myCostPrice := allocation.CostPrice
		profit := childCostPrice - myCostPrice
		if profit > 0 {
			records = append(records, &model.CommissionRecord{
				BaseModel: model.BaseModel{
					Creator: order.Creator,
					Updater: order.Updater,
				},
				ShopID:           currentShop.ID,
				OrderID:          order.ID,
				IotCardID:        order.IotCardID,
				DeviceID:         order.DeviceID,
				CommissionSource: model.CommissionSourceCostDiff,
				Amount:           profit,
				Status:           constants.CommissionStatusReleased,
			})
		}

		childCostPrice = myCostPrice
		currentShopID = currentShop.ParentID
	}

	return records, nil
}

// calculateSellerProfit 计算终端销售代理的成本价差收益。
// 代理钱包/代购链路必须以 actual_paid_amount 为准，禁止回退到 total_amount，
// 否则在 total_amount 已改成零售价后会再次产生“建议售价-成本价”的错误佣金。
func calculateSellerProfit(order *model.Order) (int64, bool) {
	if order == nil {
		return 0, false
	}

	if order.ActualPaidAmount != nil {
		return *order.ActualPaidAmount - order.SellerCostPrice, true
	}

	if order.BuyerType == model.BuyerTypeAgent ||
		order.PaymentMethod == model.PaymentMethodWallet ||
		order.IsPurchaseOnBehalf ||
		order.Source == constants.OrderSourceAdmin {
		return 0, false
	}

	return order.TotalAmount - order.SellerCostPrice, true
}

func (s *Service) triggerOneTimeCommissionForCardInTx(ctx context.Context, tx *gorm.DB, order *model.Order, cardID uint) error {
	if order.IsPurchaseOnBehalf || order.Source != constants.OrderSourceClient {
		return nil
	}

	card, err := s.iotCardStore.GetByID(ctx, cardID)
	if err != nil {
		return errors.Wrap(errors.CodeDatabaseError, err, "获取卡信息失败")
	}

	if card.SeriesID == nil || card.ShopID == nil {
		return nil
	}

	seriesID := *card.SeriesID
	series, err := s.packageSeriesStore.GetByID(ctx, seriesID)
	if err != nil {
		return errors.Wrap(errors.CodeDatabaseError, err, "获取套餐系列失败")
	}

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

	if s.isOneTimeCommissionExpired(config, card.ActivatedAt) {
		s.logger.Info("一次性佣金规则已过期，跳过",
			zap.Uint("card_id", cardID),
			zap.Uint("series_id", seriesID),
			zap.String("validity_type", config.ValidityType))
		return nil
	}

	if config.TriggerType == model.OneTimeCommissionTriggerFirstRecharge {
		accumulatedBySeries := card.GetAccumulatedRechargeBySeries(seriesID)
		newAccumulated := accumulatedBySeries + order.TotalAmount
		card.AddAccumulatedRechargeBySeries(seriesID, order.TotalAmount)
		if err := tx.Model(&model.IotCard{}).Where("id = ?", cardID).
			Update("accumulated_recharge_by_series", card.AccumulatedRechargeBySeriesJSON).Error; err != nil {
			return errors.Wrap(errors.CodeDatabaseError, err, "更新卡累计充值金额失败")
		}

		if card.IsFirstRechargeTriggeredBySeries(seriesID) {
			return nil
		}

		if newAccumulated < config.Threshold {
			return nil
		}
	}

	if card.IsFirstRechargeTriggeredBySeries(seriesID) {
		return nil
	}

	records, err := s.calculateChainOneTimeCommission(ctx, *card.ShopID, seriesID, order, &cardID, nil)
	if err != nil {
		return err
	}

	if err := s.persistCommissionRecordsInTx(ctx, tx, records); err != nil {
		return err
	}

	card.SetFirstRechargeTriggeredBySeries(seriesID, true)
	if err := tx.Model(&model.IotCard{}).Where("id = ?", cardID).
		Update("first_recharge_triggered_by_series", card.FirstRechargeTriggeredBySeriesJSON).Error; err != nil {
		return errors.Wrap(errors.CodeDatabaseError, err, "更新卡佣金发放状态失败")
	}

	return nil
}

func (s *Service) TriggerOneTimeCommissionForCard(ctx context.Context, order *model.Order, cardID uint) error {
	return s.db.Transaction(func(tx *gorm.DB) error {
		return s.triggerOneTimeCommissionForCardInTx(ctx, tx, order, cardID)
	})
}

func (s *Service) triggerOneTimeCommissionForDeviceInTx(ctx context.Context, tx *gorm.DB, order *model.Order, deviceID uint) error {
	if order.IsPurchaseOnBehalf || order.Source != constants.OrderSourceClient {
		return nil
	}

	device, err := s.deviceStore.GetByID(ctx, deviceID)
	if err != nil {
		return errors.Wrap(errors.CodeDatabaseError, err, "获取设备信息失败")
	}

	if device.SeriesID == nil || device.ShopID == nil {
		return nil
	}

	seriesID := *device.SeriesID
	series, err := s.packageSeriesStore.GetByID(ctx, seriesID)
	if err != nil {
		return errors.Wrap(errors.CodeDatabaseError, err, "获取套餐系列失败")
	}

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

	if s.isOneTimeCommissionExpired(config, device.ActivatedAt) {
		s.logger.Info("一次性佣金规则已过期，跳过",
			zap.Uint("device_id", deviceID),
			zap.Uint("series_id", seriesID),
			zap.String("validity_type", config.ValidityType))
		return nil
	}

	if config.TriggerType == model.OneTimeCommissionTriggerFirstRecharge {
		accumulatedBySeries := device.GetAccumulatedRechargeBySeries(seriesID)
		newAccumulated := accumulatedBySeries + order.TotalAmount
		device.AddAccumulatedRechargeBySeries(seriesID, order.TotalAmount)
		if err := tx.Model(&model.Device{}).Where("id = ?", deviceID).
			Update("accumulated_recharge_by_series", device.AccumulatedRechargeBySeriesJSON).Error; err != nil {
			return errors.Wrap(errors.CodeDatabaseError, err, "更新设备累计充值金额失败")
		}

		if device.IsFirstRechargeTriggeredBySeries(seriesID) {
			return nil
		}

		if newAccumulated < config.Threshold {
			return nil
		}
	}

	if device.IsFirstRechargeTriggeredBySeries(seriesID) {
		return nil
	}

	records, err := s.calculateChainOneTimeCommission(ctx, *device.ShopID, seriesID, order, nil, &deviceID)
	if err != nil {
		return err
	}

	if err := s.persistCommissionRecordsInTx(ctx, tx, records); err != nil {
		return err
	}

	device.SetFirstRechargeTriggeredBySeries(seriesID, true)
	if err := tx.Model(&model.Device{}).Where("id = ?", deviceID).
		Update("first_recharge_triggered_by_series", device.FirstRechargeTriggeredBySeriesJSON).Error; err != nil {
		return errors.Wrap(errors.CodeDatabaseError, err, "更新设备佣金发放状态失败")
	}

	return nil
}

func (s *Service) TriggerOneTimeCommissionForDevice(ctx context.Context, order *model.Order, deviceID uint) error {
	return s.db.Transaction(func(tx *gorm.DB) error {
		return s.triggerOneTimeCommissionForDeviceInTx(ctx, tx, order, deviceID)
	})
}

func (s *Service) isOneTimeCommissionExpired(config *model.OneTimeCommissionConfig, activatedAt *time.Time) bool {
	if config == nil {
		return true
	}

	now := time.Now()

	switch config.ValidityType {
	case model.OneTimeCommissionValidityPermanent:
		return false

	case model.OneTimeCommissionValidityFixedDate:
		if config.ValidityValue == "" {
			return false
		}
		expiryDate, err := time.Parse("2006-01-02", config.ValidityValue)
		if err != nil {
			s.logger.Warn("解析一次性佣金到期日期失败",
				zap.String("validity_value", config.ValidityValue),
				zap.Error(err))
			return false
		}
		expiryDate = expiryDate.Add(24*time.Hour - time.Second)
		return now.After(expiryDate)

	case model.OneTimeCommissionValidityRelative:
		if activatedAt == nil {
			return false
		}
		if config.ValidityValue == "" {
			return false
		}
		months := 0
		if _, err := fmt.Sscanf(config.ValidityValue, "%d", &months); err != nil || months <= 0 {
			s.logger.Warn("解析一次性佣金相对时长失败",
				zap.String("validity_value", config.ValidityValue),
				zap.Error(err))
			return false
		}
		expiryTime := activatedAt.AddDate(0, months, 0)
		return now.After(expiryTime)

	default:
		return false
	}
}

func (s *Service) calculateChainOneTimeCommission(ctx context.Context, bottomShopID uint, seriesID uint, order *model.Order, cardID *uint, deviceID *uint) ([]*model.CommissionRecord, error) {
	var records []*model.CommissionRecord

	series, err := s.packageSeriesStore.GetByID(ctx, seriesID)
	if err != nil {
		s.logger.Warn("获取套餐系列失败，跳过一次性佣金", zap.Uint("series_id", seriesID), zap.Error(err))
		return records, nil
	}

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

	bottomSeriesAllocation, err := s.shopSeriesAllocationStore.GetByShopAndSeries(ctx, bottomShopID, seriesID)
	if err != nil {
		s.logger.Warn("底层店铺未分配该系列，跳过一次性佣金", zap.Uint("shop_id", bottomShopID), zap.Uint("series_id", seriesID))
		return records, nil
	}

	bottomShop, err := s.shopStore.GetByID(ctx, bottomShopID)
	if err != nil {
		return nil, errors.Wrap(errors.CodeDatabaseError, err, "获取店铺信息失败")
	}

	childAmountGiven := int64(0)
	currentShopID := bottomShopID
	currentShop := bottomShop
	currentSeriesAllocation := bottomSeriesAllocation

	for {
		var myAmount int64

		if config.CommissionType == "tiered" && len(config.Tiers) > 0 {
			// 获取该代理的专属阶梯金额列表
			agentTiers, tiersErr := currentSeriesAllocation.GetCommissionTiers()
			if tiersErr != nil {
				s.logger.Warn("解析代理阶梯佣金失败，使用固定金额", zap.Uint("shop_id", currentShopID), zap.Error(tiersErr))
				myAmount = currentSeriesAllocation.OneTimeCommissionAmount
			} else if len(agentTiers) == 0 {
				// commission_tiers_json 为空（历史数据），降级到 OneTimeCommissionAmount
				s.logger.Warn("代理专属阶梯为空，fallback 到固定金额", zap.Uint("shop_id", currentShopID))
				myAmount = currentSeriesAllocation.OneTimeCommissionAmount
			} else {
				tieredAmount, tierErr := s.matchOneTimeCommissionTier(ctx, currentShopID, seriesID, currentSeriesAllocation.ID, config.Tiers, agentTiers)
				if tierErr != nil {
					s.logger.Warn("匹配梯度佣金失败，使用固定金额", zap.Uint("shop_id", currentShopID), zap.Error(tierErr))
					myAmount = currentSeriesAllocation.OneTimeCommissionAmount
				} else {
					myAmount = tieredAmount
				}
			}
		} else {
			myAmount = currentSeriesAllocation.OneTimeCommissionAmount
		}

		actualProfit := myAmount - childAmountGiven

		if actualProfit > 0 {
			remark := "一次性佣金"
			if deviceID != nil {
				remark = "一次性佣金（设备）"
			}

			records = append(records, &model.CommissionRecord{
				BaseModel: model.BaseModel{
					Creator: order.Creator,
					Updater: order.Updater,
				},
				ShopID:           currentShopID,
				OrderID:          order.ID,
				IotCardID:        cardID,
				DeviceID:         deviceID,
				CommissionSource: model.CommissionSourceOneTime,
				Amount:           actualProfit,
				Status:           constants.CommissionStatusReleased,
				Remark:           remark,
			})
		}

		if currentShop.ParentID == nil || *currentShop.ParentID == 0 {
			break
		}

		parentShopID := *currentShop.ParentID
		parentSeriesAllocation, err := s.shopSeriesAllocationStore.GetByShopAndSeries(ctx, parentShopID, seriesID)
		if err != nil {
			s.logger.Warn("上级店铺未分配该系列，佣金链断裂",
				zap.Uint("parent_shop_id", parentShopID),
				zap.Uint("series_id", seriesID),
				zap.Uint("order_id", order.ID))
			pendingRecord := &model.CommissionRecord{
				BaseModel: model.BaseModel{
					Creator: order.Creator,
					Updater: order.Updater,
				},
				ShopID:           parentShopID,
				OrderID:          order.ID,
				IotCardID:        cardID,
				DeviceID:         deviceID,
				CommissionSource: model.CommissionSourceOneTime,
				Amount:           0,
				Status:           constants.CommissionStatusPendingReview,
				Remark:           fmt.Sprintf("套餐系列[%d]未分配给该代理(shop_id=%d)，一次性佣金链路断裂，请人工核查", seriesID, parentShopID),
			}
			records = append(records, pendingRecord)
			break
		}

		parentShop, err := s.shopStore.GetByID(ctx, parentShopID)
		if err != nil {
			s.logger.Error("获取上级店铺失败", zap.Uint("shop_id", parentShopID), zap.Error(err))
			break
		}

		childAmountGiven = myAmount
		currentShopID = parentShopID
		currentShop = parentShop
		currentSeriesAllocation = parentSeriesAllocation
	}

	return records, nil
}

func (s *Service) matchOneTimeCommissionTier(ctx context.Context, shopID uint, seriesID uint, allocationID uint, tiers []model.OneTimeCommissionTier, agentTiers []model.AllocationCommissionTier) (int64, error) {
	if len(tiers) == 0 {
		return 0, nil
	}

	now := time.Now()
	var matchedAmount int64 = 0

	for _, tier := range tiers {
		var salesCount, salesAmount int64
		var err error

		if tier.StatScope == model.OneTimeCommissionStatScopeSelfAndSub {
			subordinateIDs, subErr := s.shopStore.GetSubordinateShopIDs(ctx, shopID)
			if subErr != nil {
				s.logger.Warn("获取下级店铺失败", zap.Uint("shop_id", shopID), zap.Error(subErr))
				subordinateIDs = []uint{shopID}
			}

			allocationIDs, allocErr := s.shopSeriesAllocationStore.GetIDsByShopIDsAndSeries(ctx, subordinateIDs, seriesID)
			if allocErr != nil {
				return 0, errors.Wrap(errors.CodeDatabaseError, allocErr, "获取下级分配ID失败")
			}

			salesCount, salesAmount, err = s.commissionStatsStore.GetAggregatedStats(ctx, allocationIDs, "monthly", now)
		} else {
			salesCount, salesAmount, err = s.commissionStatsStore.GetAggregatedStats(ctx, []uint{allocationID}, "monthly", now)
		}

		if err != nil {
			s.logger.Warn("获取销售统计失败", zap.Uint("allocation_id", allocationID), zap.Error(err))
			continue
		}

		var currentValue int64
		if tier.Dimension == model.TierTypeSalesCount {
			currentValue = salesCount
		} else {
			currentValue = salesAmount
		}

		// 根据 tier.Operator 判断是否命中阈值，Operator 为空时默认 >=
		var hit bool
		switch tier.Operator {
		case model.TierOperatorGT:
			hit = currentValue > tier.Threshold
		case model.TierOperatorLT:
			hit = currentValue < tier.Threshold
		case model.TierOperatorLTE:
			hit = currentValue <= tier.Threshold
		default: // >= 或空字符串
			hit = currentValue >= tier.Threshold
		}

		if !hit {
			continue
		}

		// 从代理专属阶梯列表中按 threshold 查找对应金额
		for _, agentTier := range agentTiers {
			if agentTier.Threshold == tier.Threshold && agentTier.Amount > matchedAmount {
				matchedAmount = agentTier.Amount
				break
			}
		}
	}

	return matchedAmount, nil
}

func (s *Service) creditCommissionInTx(ctx context.Context, tx *gorm.DB, record *model.CommissionRecord) error {
	// 获取店铺的分佣钱包
	var wallet model.AgentWallet
	if err := tx.Where("shop_id = ? AND wallet_type = ?", record.ShopID, "commission").First(&wallet).Error; err != nil {
		return errors.Wrap(errors.CodeDatabaseError, err, "获取店铺分佣钱包失败")
	}

	balanceBefore := wallet.Balance

	// 使用 AgentWalletStore 的方法增加余额（带事务）
	if err := s.agentWalletStore.AddBalanceWithTx(ctx, tx, wallet.ID, record.Amount); err != nil {
		return errors.Wrap(errors.CodeInternalError, err, "更新钱包余额失败")
	}

	// 更新佣金记录状态
	now := time.Now()
	if err := tx.Model(record).Updates(map[string]any{
		"balance_after": balanceBefore + record.Amount,
		"status":        constants.CommissionStatusReleased,
		"released_at":   now,
	}).Error; err != nil {
		return errors.Wrap(errors.CodeDatabaseError, err, "更新佣金记录失败")
	}

	// 创建代理钱包交易记录
	remark := "佣金入账"
	transaction := &model.AgentWalletTransaction{
		AgentWalletID:   wallet.ID,
		ShopID:          record.ShopID,
		UserID:          record.Creator,
		TransactionType: "commission",
		Amount:          record.Amount,
		BalanceBefore:   balanceBefore,
		BalanceAfter:    balanceBefore + record.Amount,
		Status:          1,
		ReferenceType:   stringPtr("commission"),
		ReferenceID:     &record.ID,
		Remark:          &remark,
		Creator:         record.Creator,
		ShopIDTag:       record.ShopID,
	}
	if err := s.agentWalletTransactionStore.CreateWithTx(ctx, tx, transaction); err != nil {
		return errors.Wrap(errors.CodeDatabaseError, err, "创建钱包交易记录失败")
	}

	return nil
}

func (s *Service) persistCommissionRecordsInTx(ctx context.Context, tx *gorm.DB, records []*model.CommissionRecord) error {
	for _, record := range records {
		if err := tx.Create(record).Error; err != nil {
			return errors.Wrap(errors.CodeDatabaseError, err, "创建佣金记录失败")
		}
		if record.Status == constants.CommissionStatusPendingReview {
			continue
		}
		if err := s.creditCommissionInTx(ctx, tx, record); err != nil {
			return errors.Wrap(errors.CodeInternalError, err, "佣金入账失败")
		}
	}

	return nil
}

func (s *Service) resolveOrderCommissionOutcomeInTx(tx *gorm.DB, orderID uint) (int, int, error) {
	var pendingReviewCount int64
	if err := tx.Model(&model.CommissionRecord{}).
		Where("order_id = ? AND status = ?", orderID, constants.CommissionStatusPendingReview).
		Count(&pendingReviewCount).Error; err != nil {
		return 0, 0, errors.Wrap(errors.CodeDatabaseError, err, "统计待人工处理佣金记录失败")
	}

	if pendingReviewCount > 0 {
		return model.CommissionStatusPendingReview, model.CommissionResultChainBroken, nil
	}

	var releasedCount int64
	if err := tx.Model(&model.CommissionRecord{}).
		Where("order_id = ? AND status = ? AND amount > 0", orderID, constants.CommissionStatusReleased).
		Count(&releasedCount).Error; err != nil {
		return 0, 0, errors.Wrap(errors.CodeDatabaseError, err, "统计已发放佣金记录失败")
	}

	if releasedCount > 0 {
		return model.CommissionStatusCompleted, model.CommissionResultHasAmount, nil
	}

	return model.CommissionStatusCompleted, model.CommissionResultNoAmount, nil
}

func (s *Service) CreditCommission(ctx context.Context, record *model.CommissionRecord) error {
	return s.db.Transaction(func(tx *gorm.DB) error {
		return s.creditCommissionInTx(ctx, tx, record)
	})
}

func stringPtr(s string) *string {
	return &s
}
