package controllers

import (
	"fmt"
	"net/http"
	"strings"
	"xugu_license/internal/global"
	middlewares "xugu_license/internal/middleware"
	"xugu_license/internal/models"

	"github.com/gin-gonic/gin"
)

func InitRolesCache() error {
	return refreshRolesCache()
}

// 获取角色信息,如果请求角色名为空则查询所有角色
func GetRoles(c *gin.Context) {
	var newRole struct {
		Name string `json:"name" binding:"required"`
	}

	if err := c.ShouldBindJSON(&newRole); err != nil {
		global.Logger.Errorln("解析请求失败 ", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("解析请求失败: ", err.Error())})
		return
	}

	if newRole.Name != " " {
		if role, exists :=
			middlewares.Roles[newRole.Name]; exists {
			c.JSON(http.StatusOK, gin.H{"message": "ok", "data": role})
			return
		}
		c.JSON(http.StatusNotFound, gin.H{"error": "未找到该角色"})
		return
	} else {
		c.JSON(http.StatusOK, gin.H{"message": "ok", "data": middlewares.Roles})
		return
	}

}

// 刷新角色缓存
func refreshRolesCache() error {
	rIS, err := models.GetRoleInfo("")
	if err != nil {

		return err
	}
	fmt.Println("rIS", rIS)
	var rolesTmp = map[string]middlewares.Role{
		"admin":       middlewares.AdminRole,
		"supportRole": middlewares.SupportRole,
		"guest":       middlewares.GuestRole,
	}

	for _, role := range rIS {
		result := strings.Split(role.Permissions, ",")
		Perm, err := middlewares.StringsToPermissions(result)
		if err != nil {
			global.Logger.Errorln(" 将字符串数组转换为 Permission 数组失败 ", err.Error())
			return err
		}
		rolesTmp[role.Name] = middlewares.Role{
			Id:          role.Id,
			Name:        role.Name,
			Permissions: Perm,
		}
	}

	middlewares.Roles = rolesTmp
	return nil
}

func CreateRole(c *gin.Context) {
	var newRole struct {
		Name        string                   `json:"name" binding:"required"`
		Permissions []middlewares.Permission `json:"permissions"`
	}

	if err := c.ShouldBindJSON(&newRole); err != nil {
		global.Logger.Errorln("解析请求失败 ", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("解析请求失败: ", err.Error())})
		return
	}

	//检测角色是否已经存在
	roleTmp, err := models.GetRoleInfo(newRole.Name)
	if err != nil {
		global.Logger.Errorln("查询角色失败 ", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	if roleTmp != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "角色已存在"})
		return
	}

	result := strings.Trim(fmt.Sprint(newRole.Permissions), "[]")
	result = strings.ReplaceAll(result, " ", ",")
	err = models.CreateRole(&models.RoleInfo{
		Name:        newRole.Name,
		Permissions: result,
	})
	if err != nil {
		global.Logger.Errorln("创建角色失败 ", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("创建角色失败: ", err.Error())})
		return
	}

	// if _, exists := roles[newRole.Name]; exists {
	// 	c.JSON(http.StatusConflict, gin.H{"error": "role already exists"})
	// 	return
	// }

	// roles[newRole.Name] = middlewares.Role{
	// 	Name:        newRole.Name,
	// 	Permissions: newRole.Permissions,
	// }

	//刷新角色缓存
	err = refreshRolesCache()
	if err != nil {
		global.Logger.Errorln("刷新角色缓存  %s", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("刷新角色缓存: ", err.Error())})
	}

	// fmt.Printf("roles: %#v\n",
	// 	middlewares.Roles)

	c.JSON(http.StatusOK, gin.H{"success": true, "message": "Role created successfully"})
}

func UpdateRole(c *gin.Context) {
	var updateRole struct {
		Id          int      `json:"id" binding:"required"`
		Name        string   `json:"name" binding:"required"`
		Permissions []string `json:"permissions" binding:"required"`
	}

	if err := c.ShouldBindJSON(&updateRole); err != nil {
		global.Logger.Errorln("解析请求失败  ", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("解析请求失败: ", err.Error())})
		return
	}
	result := strings.Trim(fmt.Sprint(updateRole.Permissions), "[]")
	result = strings.ReplaceAll(result, " ", ",")

	err := models.UpdateRole(&models.RoleInfo{
		Id:          updateRole.Id,
		Name:        updateRole.Name,
		Permissions: result,
	})
	if err != nil {
		global.Logger.Errorln("更新角色失败 ", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("更新角色失败: ", err.Error())})
		return
	}

	err = refreshRolesCache()
	if err != nil {
		global.Logger.Errorln("刷新角色缓存失败 ", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("刷新角色缓存失败: ", err.Error())})
	}

	// fmt.Printf("roles: %#v\n",
	// 	middlewares.Roles)
	// role, exists := roles[updateRole.Name]
	// if !exists {
	// 	c.JSON(http.StatusNotFound, gin.H{"error": "role not found"})
	// 	return
	// }

	// role.Permissions = updateRole.Permissions
	// roles[updateRole.Name] = role

	c.JSON(http.StatusOK, gin.H{"success": true, "message": "Role permissions updated successfully"})
	return
}

// 删除角色
func DeleteRole(c *gin.Context) {
	var deleteRole struct {
		Name string `json:"name" binding:"required"`
	}

	if err := c.ShouldBindJSON(&deleteRole); err != nil {
		global.Logger.Errorln("解析请求失败 ", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("解析请求失败: ", err.Error())})
		return
	}

	// if _, exists := roles[deleteRole.Name]; !exists {
	// 	c.JSON(http.StatusNotFound, gin.H{"error": "role not found"})
	// 	return
	// }

	// 防止删除 admin 角色
	if deleteRole.Name == "admin" {
		global.Logger.Errorln("禁止删除admin ")
		c.JSON(http.StatusForbidden, gin.H{"error": "禁止删除admin角色"})
		return
	}

	err := models.DeleteRole(deleteRole.Name)
	if err != nil {
		global.Logger.Errorln("数据库删除角色失败  ", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("数据库删除角色失败: ", err.Error())})
		return
	}

	//delete(roles, deleteRole.Name)
	err = refreshRolesCache()
	if err != nil {
		global.Logger.Errorln("刷新角色失败  ", err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintln("刷新角色失败: ", err.Error())})
	}
	// fmt.Printf("roles: %#v\n",
	// 	middlewares.Roles)

	c.JSON(http.StatusOK, gin.H{"success": true, "message": "Role deleted successfully"})
}

func GetRoleNames(c *gin.Context) {
	names := make([]string, 0, len(
		middlewares.Roles))
	for name := range middlewares.Roles {
		names = append(names, name)
	}
	c.JSON(http.StatusOK, gin.H{"roles": names})
}