package admin_agent

import (
	"context"
	"errors"

	"tydata-server/app/main/api/internal/svc"
	"tydata-server/app/main/api/internal/types"
	"tydata-server/app/main/model"
	"tydata-server/common/xerr"

	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

type AdminUpdateAgentCommissionStatusLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewAdminUpdateAgentCommissionStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminUpdateAgentCommissionStatusLogic {
	return &AdminUpdateAgentCommissionStatusLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *AdminUpdateAgentCommissionStatusLogic) AdminUpdateAgentCommissionStatus(req *types.AdminUpdateAgentCommissionStatusReq) (resp *types.AdminUpdateAgentCommissionStatusResp, err error) {
	// 验证状态值：不允许手动设置为2（已取消），只能设置为0或1
	if req.Status != 0 && req.Status != 1 {
		return nil, xerr.NewErrMsg("无效的状态值，状态必须为0(已结算)或1(冻结中)")
	}
	commission, err := l.svcCtx.AgentCommissionModel.FindOne(l.ctx, req.Id)
	if err != nil {
		if errors.Is(err, model.ErrNotFound) {
			return nil, xerr.NewErrMsg("佣金记录不存在")
		}
		return nil, err
	}

	// 检查状态转换是否合法
	// 0(已结算) <-> 1(冻结中)：允许冻结和解冻相互转换
	// 2(已取消)：已取消的状态无法转换到其他状态（由订单退款自动触发）
	if commission.Status == req.Status {
		return nil, xerr.NewErrMsg("状态未发生变化")
	}

	// 已取消的状态不能再转换
	if commission.Status == 2 {
		return nil, xerr.NewErrMsg("已取消的佣金状态不能转换")
	}

	// 开始事务
	err = l.svcCtx.AgentCommissionModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
		// 保存原始状态用于判断
		originalStatus := commission.Status

		// 更新佣金状态
		commission.Status = req.Status
		err = l.svcCtx.AgentCommissionModel.UpdateWithVersion(ctx, session, commission)
		if err != nil {
			return err
		}

		// 查询代理钱包
		wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(ctx, commission.AgentId)
		if err != nil {
			return err
		}

		// 根据状态转换更新钱包
		if originalStatus == 0 && req.Status == 1 {
			// 已结算 -> 冻结中：增加冻结金额，减少钱包余额
			// 检查钱包余额是否足够
			if wallet.Balance < commission.Amount {
				return xerr.NewErrMsg("钱包余额不足，无法冻结")
			}
			wallet.FrozenBalance += commission.Amount
			wallet.Balance -= commission.Amount

		} else if originalStatus == 1 && req.Status == 0 {
			// 冻结中 -> 已结算：减少冻结金额，增加钱包余额
			// 检查冻结余额是否足够
			if wallet.FrozenBalance < commission.Amount {
				return xerr.NewErrMsg("冻结余额不足，无法解冻")
			}
			wallet.FrozenBalance -= commission.Amount
			wallet.Balance += commission.Amount
		}

		err = l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet)
		if err != nil {
			return err
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	resp = &types.AdminUpdateAgentCommissionStatusResp{
		Success: true,
	}
	return
}
