package admin_agent

import (
	"context"
	"strconv"

	"sim-server/app/main/api/internal/svc"
	"sim-server/app/main/api/internal/types"
	"sim-server/common/ctxdata"
	"sim-server/common/xerr"

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

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

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

func (l *AdminAuditAgentWithdrawLogic) AdminAuditAgentWithdraw(req *types.AdminAuditAgentWithdrawReq) (resp *types.AdminAuditAgentWithdrawResp, err error) {
	// 1. 获取当前审核人ID（管理员ID）
	adminUserId, err := ctxdata.GetUidFromCtx(l.ctx)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取审核人信息失败: %v", err)
	}

	// 2. 验证审核状态
	if req.Status != 1 && req.Status != 2 {
		return nil, errors.Wrap(xerr.NewErrCode(xerr.REUQEST_PARAM_ERROR), "审核状态无效，只能通过(1)或拒绝(2)")
	}

	// 3. 如果是拒绝，必须填写审核原因
	if req.Status == 2 && req.AuditRemark == "" {
		return nil, errors.Wrap(xerr.NewErrCode(xerr.REUQEST_PARAM_ERROR), "拒绝提现时必须填写审核原因")
	}

	// 4. 查询提现记录
	withdrawRecord, err := l.svcCtx.AgentWithdrawModel.FindOne(l.ctx, req.WithdrawId)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询提现记录失败: %v", err)
	}

	// 5. 验证提现记录状态
	if withdrawRecord.Status != 0 {
		return nil, errors.Wrap(xerr.NewErrCode(xerr.CUSTOM_ERROR), "该提现记录已被审核，请勿重复操作")
	}

	// 6. 如果是审核通过，从配置表读取税率并计算税费
	var taxAmount float64
	var actualAmount float64
	if req.Status == 1 {
		// 从配置表读取税率
		taxRateConfig, err := l.svcCtx.AgentConfigModel.FindOneByConfigKey(l.ctx, "tax_rate")
		if err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取税率配置失败: %v", err)
		}
		taxRate, _ := strconv.ParseFloat(taxRateConfig.ConfigValue, 64)

		// 计算税费和实际到账金额
		taxAmount = withdrawRecord.WithdrawAmount * taxRate
		actualAmount = withdrawRecord.WithdrawAmount - taxAmount

		logx.Infof("提现审核通过计算税费：提现金额=%.2f，税率=%.4f，税费=%.2f，实际到账=%.2f",
			withdrawRecord.WithdrawAmount, taxRate, taxAmount, actualAmount)
	}

	// 7. 查询代理钱包
	wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, withdrawRecord.AgentId)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询代理钱包失败: %v", err)
	}

	// 8. 开启事务处理审核逻辑
	err = l.svcCtx.AgentWalletModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
		// 7.0 在事务中再次查询提现记录和钱包，确保数据是最新的且未被修改
		withdrawRecord, err = l.svcCtx.AgentWithdrawModel.FindOne(ctx, req.WithdrawId)
		if err != nil {
			return errors.Wrapf(err, "查询提现记录失败")
		}

		// 验证状态未被修改
		if withdrawRecord.Status != 0 {
			return errors.New("该提现记录已被审核，请勿重复操作")
		}

		wallet, err = l.svcCtx.AgentWalletModel.FindOneByAgentId(ctx, withdrawRecord.AgentId)
		if err != nil {
			return errors.Wrapf(err, "查询代理钱包失败")
		}

		// 验证冻结金额是否匹配提现记录
		if wallet.FrozenAmount < withdrawRecord.FrozenAmount {
			return errors.Errorf("钱包冻结金额不足，当前冻结: %.2f，需要: %.2f", wallet.FrozenAmount, withdrawRecord.FrozenAmount)
		}

		if req.Status == 1 {
			// ============ 审核通过 ============
			// 8.1 更新钱包：扣除冻结金额，增加累计提现金额
			wallet.FrozenAmount -= withdrawRecord.FrozenAmount
			wallet.TotalWithdraw += actualAmount // 累计实际到账金额

			err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet)
			if err != nil {
				return errors.Wrapf(err, "更新钱包信息失败")
			}

			// 8.2 更新提现记录状态
			updateSQL := `
				UPDATE agent_withdraw
				SET status = 1,
				    tax_amount = ?,
				    actual_amount = ?,
				    audit_user_id = ?,
				    audit_time = NOW(),
				    audit_remark = ?,
				    version = version + 1
				WHERE id = ? AND version = ?
			`
			_, err = session.Exec(updateSQL, taxAmount, actualAmount, adminUserId, req.AuditRemark, req.WithdrawId, withdrawRecord.Version)
			if err != nil {
				return errors.Wrapf(err, "更新提现记录失败")
			}

			logx.Infof("管理员 %s 审核通过提现记录 %s，代理ID: %s，提现金额: %.2f，实际到账: %.2f",
				adminUserId, req.WithdrawId, withdrawRecord.AgentId, withdrawRecord.WithdrawAmount, actualAmount)

		} else {
			// ============ 审核拒绝 ============
			// 7.1 更新钱包：解冻金额，返回余额
			wallet.FrozenAmount -= withdrawRecord.FrozenAmount
			wallet.Balance += withdrawRecord.FrozenAmount

			err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet)
			if err != nil {
				return errors.Wrapf(err, "更新钱包信息失败")
			}

			// 7.2 更新提现记录状态
			updateSQL := `
				UPDATE agent_withdraw
				SET status = 2,
				    audit_user_id = ?,
				    audit_time = NOW(),
				    audit_remark = ?,
				    version = version + 1
				WHERE id = ? AND version = ?
			`
			_, err = session.Exec(updateSQL, adminUserId, req.AuditRemark, req.WithdrawId, withdrawRecord.Version)
			if err != nil {
				return errors.Wrapf(err, "更新提现记录失败")
			}

			logx.Infof("管理员 %s 拒绝提现记录 %s，代理ID: %s，提现金额: %.2f，原因: %s",
				adminUserId, req.WithdrawId, withdrawRecord.AgentId, withdrawRecord.WithdrawAmount, req.AuditRemark)
		}

		return nil
	})

	if err != nil {
		return nil, errors.Wrap(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), err.Error())
	}

	// 8. 返回成功响应
	message := "审核通过"
	if req.Status == 2 {
		message = "审核拒绝"
	}

	return &types.AdminAuditAgentWithdrawResp{
		Success: true,
		Message: message,
	}, nil
}
