package agent

import (
	"context"
	"database/sql"
	"bdqr-server/app/main/model"
	"bdqr-server/common/ctxdata"
	"bdqr-server/common/xerr"

	"github.com/google/uuid"
	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/stores/sqlx"

	"bdqr-server/app/main/api/internal/svc"
	"bdqr-server/app/main/api/internal/types"

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

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

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

func (l *ApplyUpgradeLogic) ApplyUpgrade(req *types.ApplyUpgradeReq) (resp *types.ApplyUpgradeResp, err error) {
	userID, err := ctxdata.GetUidFromCtx(l.ctx)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err)
	}

	// 1. 获取代理信息
	agent, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
	if err != nil {
		if errors.Is(err, model.ErrNotFound) {
			return nil, errors.Wrapf(xerr.NewErrMsg("您不是代理"), "")
		}
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败, %v", err)
	}

	fromLevel := agent.Level
	toLevel := req.ToLevel

	// 2. 验证升级条件
	if !l.canUpgrade(agent.Level, toLevel, 1) {
		return nil, errors.Wrapf(xerr.NewErrMsg("升级条件不满足"), "")
	}

	// 3. 计算升级费用和返佣
	upgradeFee, err := l.svcCtx.AgentService.GetUpgradeFee(l.ctx, fromLevel, toLevel)
	if err != nil {
		return nil, errors.Wrapf(err, "获取升级费用失败")
	}
	rebateAmount, err := l.svcCtx.AgentService.GetUpgradeRebate(l.ctx, fromLevel, toLevel)
	if err != nil {
		return nil, errors.Wrapf(err, "获取升级返佣金额失败")
	}

	// 4. 查找原直接上级（用于返佣）
	var rebateAgentId string
	parent, err := l.svcCtx.AgentService.FindDirectParent(l.ctx, agent.Id)
	if err != nil && !errors.Is(err, model.ErrNotFound) {
		return nil, errors.Wrapf(err, "查找直接上级失败")
	}
	if parent != nil {
		rebateAgentId = parent.Id
	}

	// 5. 创建升级记录（待支付状态）
	var upgradeId string
	err = l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
		// 5.1 创建升级记录（状态为待支付）
		upgradeRecord := &model.AgentUpgrade{
			Id:           uuid.NewString(),
			AgentId:      agent.Id,
			FromLevel:    fromLevel,
			ToLevel:      toLevel,
			UpgradeType:  1, // 自主付费
			UpgradeFee:   upgradeFee,
			RebateAmount: rebateAmount,
			Status:       1, // 待支付（1=待支付，2=已支付，3=已完成，4=已取消）
		}
		if rebateAgentId != "" {
			upgradeRecord.RebateAgentId = sql.NullString{String: rebateAgentId, Valid: true}
		}

		_, err := l.svcCtx.AgentUpgradeModel.Insert(transCtx, session, upgradeRecord)
		if err != nil {
			return errors.Wrapf(err, "创建升级记录失败")
		}
		// 注意：升级操作将在支付成功后通过支付回调完成
		upgradeId = upgradeRecord.Id
		return nil
	})

	if err != nil {
		return nil, err
	}

	// 返回响应（订单号将在支付接口中生成）
	return &types.ApplyUpgradeResp{
		UpgradeId: upgradeId,
		OrderNo:   "", // 将在支付接口中生成
	}, nil
}

// canUpgrade 检查是否可以升级
func (l *ApplyUpgradeLogic) canUpgrade(fromLevel, toLevel int64, upgradeType int64) bool {
	if upgradeType == 1 { // 自主付费
		if fromLevel == 1 { // 普通
			return toLevel == 2 || toLevel == 3 // 可以升级为黄金或钻石
		} else if fromLevel == 2 { // 黄金
			return toLevel == 3 // 可以升级为钻石
		}
	}
	return false
}
