package api

import (
	"copter-train/log"
	"copter-train/utils"
	"errors"
	"time"

	"copter-train/db/model"
	"copter-train/db/repo"

	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

type UserLoginPasswordReq struct {
	LoginName string `json:"loginName"`
	Password  string `json:"password"`
	Role      string `json:"role"`
}

func UserLoginPassword(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	var form UserLoginPasswordReq
	err := c.ShouldBindJSON(&form)
	if err != nil {
		return nil, err
	}

	// 查找用户:根据longinName/password/role是否在roles中
	user := &model.User{}
	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		CollectName: repo.CollectionUser,
		Query: repo.Map{
			"loginName": form.LoginName,
			"password":  utils.UtilMd5(form.Password),
			"roles":     bson.M{"$elemMatch": bson.M{"$eq": form.Role}},
		},
	}, user)
	if err != nil {
		return nil, err
	}
	if !found {
		return nil, errors.New("账号/密码/角色不正确")
	}

	jwtU := &JWTUser{ID: user.GetID()}
	token, _, err := apictx.Svc.JWT.JwtCreateToken(jwtU)
	if err != nil {
		return nil, err
	}

	// 前端返回处理
	user.Password = ""
	out := map[string]interface{}{
		"token": token,
		"user":  user,
	}
	return out, nil
}

func CreateUser(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	// 验证是否为管理员
	isAdmin, err := IsAdmin(c, apictx)
	if err != nil {
		return nil, err
	}
	if !isAdmin {
		return nil, errors.New("没有权限")
	}

	user := &model.User{}
	err = c.ShouldBindJSON(&user)
	if err != nil {
		log.Error(err)
		return nil, err
	}
	// student,teacher,admin
	if len(user.Roles) < 1 {
		user.Roles = []string{"student"}
	}
	user.CreateTime = time.Now()
	user.UpdateTime = time.Now()
	return repo.RepoAddDoc(apictx.CreateRepoCtx(), repo.CollectionUser, &user)
}

func DeleteUser(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	// 验证是否为管理员
	isAdmin, err := IsAdmin(c, apictx)
	if err != nil {
		return nil, err
	}
	if !isAdmin {
		return nil, errors.New("没有权限")
	}
	_id := c.Param("id")
	id, _ := primitive.ObjectIDFromHex(_id)
	if id.IsZero() {
		return nil, errors.New("id错误")
	}
	return repo.RepoDeleteDoc(apictx.CreateRepoCtx(), repo.CollectionUser, _id)
}

func UserList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	// 验证是否为管理员
	isAdmin, err := IsAdmin(c, apictx)
	if err != nil {
		return nil, err
	}
	if !isAdmin {
		return nil, errors.New("没有权限")
	}
	page, size, query := UtilQueryPageSize(c)
	return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
		CollectName: repo.CollectionUser,
		Page:        page,
		Size:        size,
		Query:       query,
		Project:     []string{"nickName", "loginName", "avatar", "roles", "createTime", "updateTime"},
	})

}

func UserDetail(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	// 验证是否为管理员
	isAdmin, err := IsAdmin(c, apictx)
	if err != nil {
		return nil, err
	}
	if !isAdmin {
		return nil, errors.New("没有权限")
	}
	_id := c.Param("id")
	id, _ := primitive.ObjectIDFromHex(_id)
	if id.IsZero() {
		return nil, errors.New("id错误")
	}
	return GetUserById(apictx, _id)
}

func UpdateUser(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	// 验证是否为管理员
	isAdmin, err := IsAdmin(c, apictx)
	if err != nil {
		return nil, err
	}
	if !isAdmin {
		return nil, errors.New("没有权限")
	}
	user := &model.User{}
	err = c.ShouldBindJSON(&user)
	if err != nil {
		log.Error(err)
		return nil, err
	}
	if user.Id.IsZero() {
		return nil, errors.New("id错误")
	}
	return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionUser, user.Id.Hex(), user)
}

// 获取自己的信息
func UserProfile(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	return GetUserById(apictx, apictx.User.ID)
}

// 根据id获取用户信息
func GetUserById(apictx *ApiSession, id string) (*model.User, error) {
	user := &model.User{}
	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		CollectName: repo.CollectionUser,
		Query:       repo.Map{"_id": id},
	}, user)
	if err != nil {
		log.Error(err)
		return nil, err
	}

	if !found {
		return nil, errors.New("未找到该数据")
	}
	user.Password = ""
	return user, nil
}

// 是否是管理员
func IsAdmin(c *gin.Context, apictx *ApiSession) (bool, error) {
	user, err := GetUserById(apictx, apictx.User.ID)
	if err != nil {
		return false, err
	}
	for _, v := range user.Roles {
		if v == "admin" {
			return true, nil
		}
	}
	return false, nil
}

// 是否是老师
func IsTeacher(c *gin.Context, apictx *ApiSession) (bool, error) {
	user, err := GetUserById(apictx, apictx.User.ID)
	if err != nil {
		return false, err
	}
	for _, v := range user.Roles {
		if v == "teacher" {
			return true, nil
		}
	}
	return false, nil
}

// 是否是学生
func IsStudent(c *gin.Context, apictx *ApiSession) (bool, error) {
	user, err := GetUserById(apictx, apictx.User.ID)
	if err != nil {
		return false, err
	}
	for _, v := range user.Roles {
		if v == "student" {
			return true, nil
		}
	}
	return false, nil
}
