package agent

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

	"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 GenerateInviteCodeLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

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

func (l *GenerateInviteCodeLogic) GenerateInviteCode(req *types.GenerateInviteCodeReq) (resp *types.GenerateInviteCodeResp, err error) {
	// 1. 获取当前代理信息
	userID, err := ctxdata.GetUidFromCtx(l.ctx)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err)
	}

	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)
	}

	// 2. 验证生成数量
	if req.Count <= 0 || req.Count > 100 {
		return nil, errors.Wrapf(xerr.NewErrMsg("生成数量必须在1-100之间"), "")
	}

	// 3. 生成邀请码
	codes := make([]string, 0, req.Count)
	var expireTime sql.NullTime
	if req.ExpireDays > 0 {
		expireTime = sql.NullTime{
			Time:  time.Now().AddDate(0, 0, int(req.ExpireDays)),
			Valid: true,
		}
	}

	err = l.svcCtx.AgentInviteCodeModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
		for i := int64(0); i < req.Count; i++ {
			// 生成8位随机邀请码（大小写字母+数字）
			var code string
			maxRetries := 10 // 最大重试次数
			for retry := 0; retry < maxRetries; retry++ {
				code = tool.Krand(8, tool.KC_RAND_KIND_ALL)
				// 检查邀请码是否已存在
				_, err := l.svcCtx.AgentInviteCodeModel.FindOneByCode(transCtx, code)
				if err != nil {
					if errors.Is(err, model.ErrNotFound) {
						// 邀请码不存在，可以使用
						break
					}
					return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "检查邀请码失败, %v", err)
				}
				// 邀请码已存在，继续生成
				if retry == maxRetries-1 {
					return errors.Wrapf(xerr.NewErrMsg("生成邀请码失败，请重试"), "")
				}
			}

			// 创建邀请码记录
			inviteCode := &model.AgentInviteCode{
				Code:        code,
				AgentId:     sql.NullString{String: agent.Id, Valid: true},
				TargetLevel: 1, // 代理发放的邀请码，目标等级为白银代理
				Status:      0, // 未使用
				ExpireTime:  expireTime,
				Remark:      sql.NullString{String: req.Remark, Valid: req.Remark != ""},
			}

			_, err := l.svcCtx.AgentInviteCodeModel.Insert(transCtx, session, inviteCode)
			if err != nil {
				return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建邀请码失败, %v", err)
			}

			codes = append(codes, code)
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	return &types.GenerateInviteCodeResp{
		Codes: codes,
	}, nil
}
