package auth

import (
	"context"
	"github.com/suyuan32/simple-admin-common/config"
	"github.com/suyuan32/simple-admin-common/enum/common"
	"github.com/suyuan32/simple-admin-common/i18n"
	"github.com/suyuan32/simple-admin-common/msg/errormsg"
	"github.com/suyuan32/simple-admin-common/utils/jwt"
	"github.com/suyuan32/simple-admin-common/utils/pointy"
	"github.com/suyuan32/simple-admin-core/rpc/types/core"
	"github.com/zeromicro/go-zero/core/errorx"
	"net/http"
	"strings"
	"time"
	"wechat-api/internal/logic/fastgpt"
	"wechat-api/internal/svc"
	"wechat-api/internal/types"

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

type LoginBySmsLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
	w      http.ResponseWriter
}

func NewLoginBySmsLogic(ctx context.Context, svcCtx *svc.ServiceContext, w http.ResponseWriter) *LoginBySmsLogic {
	return &LoginBySmsLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
		w:      w,
	}
}

func (l *LoginBySmsLogic) LoginBySms(req *types.LoginBySmsReq) (resp *types.LoginResp, err error) {
	if l.svcCtx.Config.LoginConf.LoginVerify != "sms" && l.svcCtx.Config.LoginConf.LoginVerify != "sms_or_email" &&
		l.svcCtx.Config.LoginConf.LoginVerify != "all" {
		return nil, errorx.NewCodeAbortedError("login.loginTypeForbidden")
	}

	captchaData, err := l.svcCtx.Rds.Get(l.ctx, config.RedisCaptchaPrefix+req.PhoneNumber).Result()
	if err != nil {
		logx.Errorw("failed to get captcha data in redis for email validation", logx.Field("detail", err),
			logx.Field("data", req))
		return nil, errorx.NewCodeInvalidArgumentError(i18n.Failed)
	}

	if captchaData != req.Captcha {
		return nil, errorx.NewCodeInvalidArgumentError("login.wrongCaptcha")
	}
	userData, err := l.svcCtx.CoreRpc.GetUserList(l.ctx, &core.UserListReq{
		Page:     1,
		PageSize: 1,
		Mobile:   &req.PhoneNumber,
	})
	if err != nil {
		return nil, err
	}
	if userData.Total == 0 {
		return nil, errorx.NewCodeInvalidArgumentError("login.userNotExist")
	}
	token, err := jwt.NewJwtToken(l.svcCtx.Config.Auth.AccessSecret, time.Now().Unix(),
		l.svcCtx.Config.Auth.AccessExpire, jwt.WithOption("userId", userData.Data[0].Id), jwt.WithOption("roleId",
			strings.Join(userData.Data[0].RoleCodes, ",")), jwt.WithOption("deptId", userData.Data[0].DepartmentId))
	if err != nil {
		return nil, err
	}

	// add token into database
	expiredAt := time.Now().Add(time.Second * time.Duration(l.svcCtx.Config.Auth.AccessExpire)).UnixMilli()
	_, err = l.svcCtx.CoreRpc.CreateToken(l.ctx, &core.TokenInfo{
		Uuid:      userData.Data[0].Id,
		Token:     pointy.GetPointer(token),
		Source:    pointy.GetPointer("core_user"),
		Status:    pointy.GetPointer(uint32(common.StatusNormal)),
		Username:  userData.Data[0].Username,
		ExpiredAt: pointy.GetPointer(expiredAt),
	})
	if err != nil {
		return nil, err
	}
	err = l.svcCtx.Rds.Del(l.ctx, config.RedisCaptchaPrefix+req.PhoneNumber).Err()
	if err != nil {
		logx.Errorw("failed to delete captcha in redis", logx.Field("detail", err))
	}

	//注册cookie 到fastgpt
	fastgptLogic := fastgpt.NewSetTokenLogic(l.ctx, l.svcCtx, l.w)
	_, err = fastgptLogic.SetTokenByUserId(*userData.Data[0].Id)
	if err != nil {
		return nil, err
	}

	resp = &types.LoginResp{
		BaseDataInfo: types.BaseDataInfo{Msg: errormsg.Success},
		Data: types.LoginInfo{
			UserId: *userData.Data[0].Id,
			Token:  token,
			Expire: uint64(expiredAt),
		},
	}
	return resp, nil
}
