package middleware

import (
	"strings"
	"system-altrak/internal/dto"

	"github.com/gofiber/fiber/v2"
)

const (
	roleAdmin      = "admin"
	roleUser       = "user"
	roleSuperadmin = "superadmin"
)

var adminCreateEditModules = map[string]struct{}{
	"customer-profile": {},
	"customer_profile": {},
	"iom":              {},
	"isr":              {},
	"sr":               {},
}

func RoleRequired(roles ...string) fiber.Handler {
	return func(c *fiber.Ctx) error {
		userRole, ok := c.Locals("role").(string)
		if !ok || userRole == "" {
			return c.Status(fiber.StatusUnauthorized).JSON(dto.APIResponse{
				Success: false,
				Message: "Autentikasi diperlukan",
			})
		}
		userRole = normalizeRole(userRole)
		if userRole == roleSuperadmin {
			return c.Next()
		}

		roleMap := make(map[string]bool)
		for _, r := range roles {
			normalizedRole := normalizeRole(r)
			if normalizedRole == "" {
				continue
			}
			roleMap[normalizedRole] = true
		}

		if !roleMap[userRole] {
			return c.Status(fiber.StatusForbidden).JSON(dto.APIResponse{
				Success: false,
				Message: "Anda tidak memiliki akses ke fitur ini",
			})
		}

		return c.Next()
	}
}

func normalizeRole(role string) string {
	normalized := strings.ToLower(strings.TrimSpace(role))
	switch normalized {
	case "manager":
		return roleAdmin
	case "staff":
		return roleUser
	default:
		return normalized
	}
}

// ViewExportRequired allows read/export operations for user/admin/superadmin roles.
func ViewExportRequired() fiber.Handler {
	return RoleRequired(roleUser, roleAdmin)
}

// ViewAuthorizeImportExportRequired allows authorize/import/verification operations for admin/superadmin only.
func ViewAuthorizeImportExportRequired() fiber.Handler {
	return RoleRequired(roleAdmin)
}

// SuperadminRequired allows only superadmin operations.
func SuperadminRequired() fiber.Handler {
	return RoleRequired(roleSuperadmin)
}

// CreateEditModuleRequired allows admin create/edit only for selected modules.
func CreateEditModuleRequired(module string) fiber.Handler {
	normalizedModule := strings.ToLower(strings.TrimSpace(module))
	if _, ok := adminCreateEditModules[normalizedModule]; ok {
		return RoleRequired(roleAdmin)
	}

	return RoleRequired(roleSuperadmin)
}
