package controllers

import (
	"lost-and-found/internal/services"
	"lost-and-found/internal/utils"
	"net/http"
	"strconv"

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

type RoleController struct {
	roleService *services.RoleService
}

// NewRoleController initializes the role controller
func NewRoleController(db *gorm.DB) *RoleController {
	return &RoleController{
		roleService: services.NewRoleService(db),
	}
}

// GetRoles gets all roles
// GET /api/admin/roles
func (c *RoleController) GetRoles(ctx *gin.Context) {
	roles, err := c.roleService.GetAllRoles()
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "Failed to get roles", err.Error())
		return
	}

	utils.SuccessResponse(ctx, http.StatusOK, "Roles retrieved", roles)
}

// GetPermissions gets all permissions
// GET /api/admin/permissions
func (c *RoleController) GetPermissions(ctx *gin.Context) {
	permissions, err := c.roleService.GetAllPermissions()
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusInternalServerError, "Failed to get permissions", err.Error())
		return
	}

	utils.SuccessResponse(ctx, http.StatusOK, "Permissions retrieved", permissions)
}

// CreateRole creates a new role
// POST /api/admin/roles
func (c *RoleController) CreateRole(ctx *gin.Context) {
	var req services.CreateRoleRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid request data", err.Error())
		return
	}

	role, err := c.roleService.CreateRole(req)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to create role", err.Error())
		return
	}

	utils.SuccessResponse(ctx, http.StatusCreated, "Role created", role)
}

// UpdateRole updates a role
// PUT /api/admin/roles/:id
func (c *RoleController) UpdateRole(ctx *gin.Context) {
	id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid role ID", err.Error())
		return
	}

	var req services.UpdateRoleRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid request data", err.Error())
		return
	}

	role, err := c.roleService.UpdateRole(uint(id), req)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to update role", err.Error())
		return
	}

	utils.SuccessResponse(ctx, http.StatusOK, "Role updated", role)
}

// DeleteRole deletes a role
// DELETE /api/admin/roles/:id
func (c *RoleController) DeleteRole(ctx *gin.Context) {
	id, err := strconv.ParseUint(ctx.Param("id"), 10, 32)
	if err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid role ID", err.Error())
		return
	}

	if err := c.roleService.DeleteRole(uint(id)); err != nil {
		utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to delete role", err.Error())
		return
	}

	utils.SuccessResponse(ctx, http.StatusOK, "Role deleted", nil)
}