package agent

import (
	"context"
	"database/sql"
	"qnc-server/app/main/model"
	"qnc-server/common/ctxdata"
	"qnc-server/common/globalkey"
	"qnc-server/common/xerr"
	"qnc-server/pkg/lzkit/lzUtils"

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

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

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

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

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

func (l *UpgradeSubordinateLogic) UpgradeSubordinate(req *types.UpgradeSubordinateReq) (resp *types.UpgradeSubordinateResp, err error) {
	operatorUserId, err := ctxdata.GetUidFromCtx(l.ctx)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err)
	}

	// 1. 获取操作者代理信息
	operatorAgent, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, operatorUserId)
	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)
	}

	// 2. 验证权限：必须是钻石代理
	if operatorAgent.Level != 3 {
		return nil, errors.Wrapf(xerr.NewErrMsg("只有钻石代理可以升级下级"), "")
	}

	// 3. 获取被升级的代理信息
	subordinateAgent, err := l.svcCtx.AgentModel.FindOne(l.ctx, req.SubordinateId)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询下级代理信息失败, %v", err)
	}

	// 4. 验证下级等级：只能是普通代理
	if subordinateAgent.Level != 1 {
		return nil, errors.Wrapf(xerr.NewErrMsg("只能升级普通代理为黄金代理"), "")
	}

	// 5. 验证关系：必须是下级（直接或间接）
	isSubordinate := l.isSubordinate(operatorAgent.Id, subordinateAgent.Id)
	if !isSubordinate {
		return nil, errors.Wrapf(xerr.NewErrMsg("该代理不是您的下级"), "")
	}

	// 6. 验证目标等级：只能升级为黄金
	toLevel := req.ToLevel
	if toLevel != 2 {
		return nil, errors.Wrapf(xerr.NewErrMsg("钻石代理只能将普通代理升级为黄金代理"), "")
	}

	// 7. 使用事务处理升级
	err = l.svcCtx.AgentWalletModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
		// 7.1 创建升级记录
		upgradeRecord := &model.AgentUpgrade{
			Id:              uuid.New().String(),
			AgentId:         subordinateAgent.Id,
			FromLevel:       1, // 普通
			ToLevel:         toLevel,
			UpgradeType:     2, // 钻石升级下级
			UpgradeFee:      0, // 免费
			RebateAmount:    0, // 无返佣
			OperatorAgentId: sql.NullString{String: operatorAgent.Id, Valid: true},
			Status:          1, // 待处理
		}

		_, err := l.svcCtx.AgentUpgradeModel.Insert(transCtx, session, upgradeRecord)
		if err != nil {
			return errors.Wrapf(err, "创建升级记录失败")
		}

		// 7.2 执行升级操作
		if err := l.svcCtx.AgentService.ProcessUpgrade(transCtx, subordinateAgent.Id, toLevel, 2, 0, 0, "", operatorAgent.Id); err != nil {
			return errors.Wrapf(err, "执行升级操作失败")
		}

		// 7.3 更新升级记录状态
		upgradeRecord.Status = 2 // 已完成
		upgradeRecord.Remark = lzUtils.StringToNullString("钻石代理升级下级成功")
		if err := l.svcCtx.AgentUpgradeModel.UpdateWithVersion(transCtx, session, upgradeRecord); err != nil {
			return errors.Wrapf(err, "更新升级记录失败")
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	return &types.UpgradeSubordinateResp{
		Success: true,
	}, nil
}

// isSubordinate 递归检查 targetId 是否是 parentId 的下级（直接或间接）
func (l *UpgradeSubordinateLogic) isSubordinate(parentId, targetId string) bool {
	// 查询直接下级
	builder := l.svcCtx.AgentRelationModel.SelectBuilder().
		Where("parent_id = ? AND relation_type = ? AND del_state = ?", parentId, 1, globalkey.DelStateNo)
	relations, err := l.svcCtx.AgentRelationModel.FindAll(l.ctx, builder, "")
	if err != nil {
		return false
	}

	for _, relation := range relations {
		// 如果是直接下级，返回 true
		if relation.ChildId == targetId {
			return true
		}
		// 递归检查间接下级
		if l.isSubordinate(relation.ChildId, targetId) {
			return true
		}
	}

	return false
}
