package handlers

import (
	"context"
	"net/http"
	"strconv"
	"time"

	"go.mongodb.org/mongo-driver/v2/bson"
	"go.mongodb.org/mongo-driver/v2/mongo/options"

	"yh_web/server/config"
	"yh_web/server/models"

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

// 预定义角色（与 users.role_id 对应）
var roleMeta = []struct {
	RoleID   int    `json:"role_id"`
	RoleName string `json:"role_name"`
}{
	{models.RoleIDSuperAdmin, "超级管理员"},
	{models.RoleIDSuperUser, "超级用户"},
	{models.RoleIDUser, "普通用户"},
}

// GetRolePermissionsList 返回所有角色及其权限（用于角色权限管理页）
func GetRolePermissionsList(c *gin.Context) {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	coll := config.GetDB(config.DBName).Collection("role_permissions")
	cursor, err := coll.Find(ctx, bson.M{})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer cursor.Close(ctx)

	var docs []models.RolePermissionsDoc
	if err = cursor.All(ctx, &docs); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	permMap := make(map[int][]string)
	for _, d := range docs {
		permMap[d.RoleID] = d.Permissions
	}

	list := make([]gin.H, 0, len(roleMeta))
	for _, r := range roleMeta {
		perms := permMap[r.RoleID]
		if perms == nil {
			perms = []string{}
		}
		if r.RoleID == models.RoleIDSuperAdmin {
			perms = allPermissionKeys()
		}
		list = append(list, gin.H{
			"role_id":     r.RoleID,
			"role_name":   r.RoleName,
			"permissions": perms,
		})
	}
	c.JSON(http.StatusOK, gin.H{
		"list":            list,
		"all_permissions": models.AllPermissions,
	})
}

// UpdateRolePermissionsInput 更新某角色权限
type UpdateRolePermissionsInput struct {
	Permissions []string `json:"permissions"`
}

// UpdateRolePermissions 更新指定角色的权限
func UpdateRolePermissions(c *gin.Context) {
	roleIDStr := c.Param("role_id")
	roleID, err := strconv.Atoi(roleIDStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 role_id"})
		return
	}
	if roleID == models.RoleIDSuperAdmin {
		c.JSON(http.StatusBadRequest, gin.H{"error": "超级管理员权限不可修改"})
		return
	}

	var input UpdateRolePermissionsInput
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	coll := config.GetDB(config.DBName).Collection("role_permissions")
	filter := bson.M{"role_id": roleID}
	update := bson.M{"$set": bson.M{"role_id": roleID, "permissions": input.Permissions}}
	opts := options.UpdateOne().SetUpsert(true)
	_, err = coll.UpdateOne(ctx, filter, update, opts)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "保存成功", "role_id": roleID, "permissions": input.Permissions})
}
