package service

import (
	"fmt"

	"metazone.cc/metalab/internal/common"
	"metazone.cc/metalab/internal/model"
)

// AdminAdjust 后台调整用户域能
// mode: "admin_transfer"（受公户余额约束）| "system_operation"（不受约束，不碰公户）
func (s *EnergyService) AdminAdjust(operatorUID uint, userIDs []uint, amount int, description string, mode string) error {
	if mode == "" {
		mode = model.FundTypeAdminTransfer
	}

	return s.repo.Transaction(func(txRepo EnergyStore, txFundRepo FundStore) error {
		// admin_transfer：公户出账需检查余额（行锁防 TOCTOU 竞态）
		isAdminTransfer := mode == model.FundTypeAdminTransfer
		if isAdminTransfer && amount > 0 && txFundRepo != nil {
			totalCost := amount * len(userIDs)
			balance, err := txFundRepo.LockAndGetBalance()
			if err != nil {
				return fmt.Errorf("查询公户余额失败: %w", err)
			}
			if balance < totalCost {
				return common.ErrInsufficientFund
			}
		}

		for _, uid := range userIDs {
			if err := txRepo.AddEnergy(uid, amount); err != nil {
				return fmt.Errorf("调整用户 %d 域能失败: %w", uid, err)
			}

			opUID := operatorUID
			energyLog := &model.EnergyLog{
				UserID:      uid,
				Amount:      amount,
				Type:        model.EnergyTypeAdminAdjust,
				Description: description,
				OperatorUID: &opUID,
			}
			if err := txRepo.CreateEnergyLog(energyLog); err != nil {
				return fmt.Errorf("创建调整流水失败: %w", err)
			}
		}

		// admin_transfer：公户扣款 + 公户流水（system_operation 不碰公户）
		if isAdminTransfer && txFundRepo != nil {
			totalCost := amount * len(userIDs)
			if err := txFundRepo.IncrBalance(-totalCost); err != nil {
				return fmt.Errorf("公户余额调整失败: %w", err)
			}

			totalDisplay := float64(totalCost) / 10
			fundLog := &model.FundLog{
				Amount:      -totalCost,
				Type:        mode,
				OperatorUID: &operatorUID,
				Description: fmt.Sprintf("%s：调整 %d 名用户域能 %.1f，说明：%s", getFundModeName(mode), len(userIDs), totalDisplay, description),
			}
			if len(userIDs) > 0 {
				fundLog.RelatedType = "user"
				fundLog.RelatedID = userIDs[0]
			}
			if err := txFundRepo.CreateLog(fundLog); err != nil {
				return fmt.Errorf("创建公户流水失败: %w", err)
			}
		}

		return nil
	})
}

// getFundModeName 返回操作模式中文名
func getFundModeName(mode string) string {
	switch mode {
	case model.FundTypeAdminTransfer:
		return "管理转出"
	case model.FundTypeSystemOperation:
		return "系统操作"
	default:
		return "后台调整"
	}
}
