<?php

declare(strict_types=1);

namespace App\Services\EntraAdminRoles;

final class HighPrivilegeRoleCatalog
{
    /**
     * Template ID → severity mapping.
     *
     * @var array<string, string>
     */
    private const CATALOG = [
        '62e90394-69f5-4237-9190-012177145e10' => 'critical', // Global Administrator
        'e8611ab8-c189-46e8-94e1-60213ab1f814' => 'high',     // Privileged Role Administrator
        '194ae4cb-b126-40b2-bd5b-6091b380977d' => 'high',     // Security Administrator
        'b1be1c3e-b65d-4f19-8427-f6fa0d97feb9' => 'high',     // Conditional Access Administrator
        '29232cdf-9323-42fd-ade2-1d097af3e4de' => 'high',     // Exchange Administrator
        'c4e39bd9-1100-46d3-8c65-fb160da0071f' => 'high',     // Authentication Administrator
    ];

    /**
     * Display name fallback (case-insensitive) for roles without template_id match.
     *
     * @var array<string, string>
     */
    private const DISPLAY_NAME_FALLBACK = [
        'global administrator' => 'critical',
        'privileged role administrator' => 'high',
        'security administrator' => 'high',
        'conditional access administrator' => 'high',
        'exchange administrator' => 'high',
        'authentication administrator' => 'high',
    ];

    /**
     * Classify a role by template_id (preferred) or display_name (fallback).
     *
     * @return string|null Severity ('critical'|'high') or null if not high-privilege
     */
    public function classify(string $templateIdOrId, ?string $displayName = null): ?string
    {
        if (isset(self::CATALOG[$templateIdOrId])) {
            return self::CATALOG[$templateIdOrId];
        }

        if ($displayName !== null) {
            $normalized = strtolower(trim($displayName));

            if (isset(self::DISPLAY_NAME_FALLBACK[$normalized])) {
                return self::DISPLAY_NAME_FALLBACK[$normalized];
            }
        }

        return null;
    }

    public function isHighPrivilege(string $templateIdOrId, ?string $displayName = null): bool
    {
        return $this->classify($templateIdOrId, $displayName) !== null;
    }

    public function isGlobalAdministrator(string $templateIdOrId, ?string $displayName = null): bool
    {
        return $this->classify($templateIdOrId, $displayName) === 'critical';
    }

    /**
     * @return array<string, string> All template_id → severity mappings
     */
    public function allTemplateIds(): array
    {
        return self::CATALOG;
    }
}
