package api

import (
	"context"
	"encoding/base64"
	"entrance-grpc/iam"
	"gadmin/config"
	"gadmin/internal/admin/consts"
	"gadmin/internal/admin/forms"
	"gadmin/internal/admin/service"
	"gadmin/utility/serializer"
	"gadmin/utility/token"
	"github.com/gin-gonic/gin"
	jsoniter "github.com/json-iterator/go"
	"github.com/sirupsen/logrus"
	"strconv"
	"time"
)

func UserLogin(c *gin.Context) {
	ip := c.ClientIP()
	var req forms.UserLoginReq
	if err := c.ShouldBind(&req); err == nil {
		res := service.User.Login(req, ip)
		c.JSON(200, res)
	} else {
		c.JSON(200, ErrorResponse(err))
	}
}

func UserLogout(c *gin.Context) {
	encodeToken := token.GetAuthorization(c)
	if encodeToken == "" {
		c.JSON(200, serializer.CheckLogin())
		return
	}
	bytesT, err := base64.URLEncoding.DecodeString(encodeToken)
	if err != nil {
		logrus.Warningf("middleware base64.URLEncoding.DecodeString:%+v", err.Error())
		c.JSON(200, serializer.CheckLogin())
		return
	}
	t := string(bytesT)

	err = service.User.Logout(t)
	if err != nil {
		logrus.Warningf("middleware UserLogout:%+v", err.Error())
		c.JSON(200, serializer.CheckLogin())
		return
	}
	c.JSON(200, serializer.Suc(nil, "退出成功"))
}

//func UserMe(c *gin.Context) {
//	var (
//		user = token.CurrentUser(c)
//	)
//	permissions := make([]forms.UserLoginPermissions, 0)
//	permissions = append(permissions, forms.UserLoginPermissions{
//		Label: "控制台",
//		Value: "value",
//	})
//	//获取用户角色权限
//	roleInfo, err := service.AdminRole.GetRole(c, forms.AdminRoleReq{ID: user.RoleId})
//	if err != nil || roleInfo == nil {
//		c.JSON(200, ErrorResponse(err))
//		return
//	}
//	if roleInfo.Key == "super" {
//		for k, _ := range config.AuthMenuMap {
//			permissions = append(permissions, forms.UserLoginPermissions{
//				Label: config.AuthNameMap[k],
//				Value: config.AuthMenuMap[k],
//			})
//		}
//	} else {
//		rpdb := query.Use(config.AdminDB).AdminRolePermission
//		rolePermission := make([]int, 0)
//		err = rpdb.Where(rpdb.SystemID.Eq(user.SystemId)).Pluck(rpdb.PermissionID, &rolePermission)
//		//err = json.Unmarshal([]byte(roleInfo.Permissions), &rolePermission)
//		if err != nil {
//			c.JSON(200, ErrorResponse(err))
//			return
//		}
//		for _, v := range rolePermission {
//			if _, ok := config.AuthMenuMap[v]; ok {
//				permissions = append(permissions, forms.UserLoginPermissions{
//					Label: config.AuthNameMap[v],
//					Value: config.AuthMenuMap[v],
//				})
//			}
//		}
//	}
//
//	//将权限赋值给permission
//
//	info := forms.UserMeReq{
//		ID:          user.ID,
//		UserName:    user.UserName,
//		RoleId:      user.RoleId,
//		Avatar:      user.Avatar,
//		Nickname:    user.Nickname,
//		Permissions: permissions,
//		IsSuper:     user.UserName == "admin",
//	}
//
//	c.JSON(200, serializer.Suc(info, "获取成功"))
//}

func AdminUserList(c *gin.Context) {
	var req forms.AdminUserListReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}
	if err := forms.ParseParams(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	c.JSON(200, service.User.List(c, req))
}

func AdminUserEdit(c *gin.Context) {
	var req forms.AdminUserEditReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}
	if err := forms.ParseParams(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	c.JSON(200, service.User.Edit(c, req))
}

func RolePermission(c *gin.Context) {
	is, err := service.User.GetUserRolePermission(c)
	if err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}
	c.JSON(200, serializer.Suc(is, "获取成功"))
}

type AdminIamServer struct {
	iam.UnimplementedIamServer
}

func (s *AdminIamServer) CheckToken(ctx context.Context, req *iam.CheckTokenReq) (*iam.CheckTokenResp, error) {
	resp := &iam.CheckTokenResp{}
	tokenKey := config.GetTokenKey(req.GetToken())
	if config.TokenRedis.Exists(tokenKey).Val() == 0 {
		resp.Code = consts.CodeCheckLogin
		resp.Msg = "未登录"
		return resp, nil
	}
	userStr := config.TokenRedis.Get(tokenKey).Val()

	user := new(token.UserClaims)
	if err := jsoniter.UnmarshalFromString(userStr, user); err != nil {
		logrus.Warningf("middleware jsoniter.UnmarshalFromString:%+v", err.Error())
		resp.Code = consts.CodeCheckLogin
		resp.Msg = "未登录"
		return resp, nil
	}
	if user.ID == 0 {
		resp.Code = consts.CodeCheckLogin
		resp.Msg = "未登录"
		return resp, nil
	}

	// 查询登录token是否有效
	now := time.Now()
	key := config.GetUserTokenKey(user.ID)
	tokenCTStr := config.TokenRedis.HGet(key, req.GetToken()).Val()
	tokenCreateTime, err := strconv.Atoi(tokenCTStr)
	if err != nil {
		logrus.Warningf("middleware config.LogRedis.HGet:%+v", err.Error())
		resp.Code = consts.CodeCheckLogin
		resp.Msg = "未登录"
		return resp, nil
	}
	tokenCT := time.Unix(int64(tokenCreateTime), 0)

	if tokenCT.Before(now.Add(-config.TokenExpireTime)) {
		config.TokenRedis.HDel(key, req.GetToken())
		resp.Code = consts.CodeCheckLogin
		resp.Msg = "未登录"
		return resp, nil
	}
	config.TokenRedis.HSet(key, req.GetToken(), now.Unix())
	config.TokenRedis.Expire(key, time.Hour*12)
	config.TokenRedis.Expire(tokenKey, time.Hour*12)

	resp.Data = &iam.AdminUserInfo{
		ID:       user.ID,
		RoleID:   user.RoleId,
		UserName: user.UserName,
		NickName: user.Nickname,
		Avatar:   user.Avatar,
	}
	return resp, nil
}

func (s *AdminIamServer) GetAdminUserByID(ctx context.Context, req *iam.GetAdminUserByIDReq) (*iam.GetAdminUserByIDResp, error) {
	user, err := service.User.GetUserInfoByID(ctx, req.GetUID())
	resp := &iam.GetAdminUserByIDResp{}
	if err != nil {
		resp.Code = 1
		resp.Msg = err.Error()
	}
	resp.Data = user
	return resp, nil
}

func (s *AdminIamServer) BatchGetAdminUser(ctx context.Context, req *iam.BatchGetAdminUserReq) (*iam.BatchGetAdminUserResp, error) {
	users, err := service.User.BatchGetUsers(ctx, req.GetUIds())

	resp := &iam.BatchGetAdminUserResp{}

	if err != nil {
		resp.Code = 1
		resp.Msg = err.Error()
	} else {
		resp.Data = users
	}
	return resp, nil
}

func (s *AdminIamServer) GetAdminUserByNickName(ctx context.Context, req *iam.GetAdminUserByNickNameReq) (*iam.GetAdminUserByNickNameResp, error) {
	resp := &iam.GetAdminUserByNickNameResp{}

	user, err := service.User.GetUserByNickName(ctx, req.GetNickName())
	if err != nil {
		resp.Code = 1
		resp.Msg = err.Error()
	} else {
		resp.Data = user
	}

	return resp, nil
}

func (s *AdminIamServer) GetRoleSystems(ctx context.Context, req *iam.GetRoleSystemsReq) (*iam.GetRoleSystemsResp, error) {
	resp := &iam.GetRoleSystemsResp{}
	systems, err := service.User.GetRoleSystems(ctx, req.GetRoleID())
	if err != nil {
		resp.Code = 1
		resp.Msg = err.Error()
	} else {
		resp.Data = systems
	}
	return resp, nil
}

func (s *AdminIamServer) DeleteToken(ctx context.Context, req *iam.DeleteTokenReq) (*iam.DeleteTokenResp, error) {
	resp := &iam.DeleteTokenResp{}

	err := service.User.Logout(req.GetToken())
	if err != nil {
		resp.Code = 1
		resp.Msg = err.Error()
	}
	return resp, nil
}
