<?php

namespace App\Support;

use App\Support\Governance\PlatformVocabularyGlossary;
use App\Support\ReasonTranslation\NextStepOption;
use App\Support\ReasonTranslation\PlatformReasonFamily;
use App\Support\ReasonTranslation\ReasonOwnershipDescriptor;
use App\Support\ReasonTranslation\ReasonResolutionEnvelope;

enum RbacReason: string
{
    case MissingArtifacts = 'missing_artifacts';
    case ServicePrincipalMissing = 'sp_missing';
    case GroupMissing = 'group_missing';
    case ServicePrincipalNotMember = 'sp_not_member';
    case AssignmentMissing = 'assignment_missing';
    case RoleMismatch = 'role_mismatch';
    case ScopeMismatch = 'scope_mismatch';
    case CanaryFailed = 'canary_failed';
    case ManualAssignmentRequired = 'manual_assignment_required';
    case UnsupportedApi = 'unsupported_api';

    public function operatorLabel(): string
    {
        return match ($this) {
            self::MissingArtifacts => 'RBAC setup incomplete',
            self::ServicePrincipalMissing => 'Service principal missing',
            self::GroupMissing => 'RBAC group missing',
            self::ServicePrincipalNotMember => 'Service principal not in RBAC group',
            self::AssignmentMissing => 'RBAC assignment missing',
            self::RoleMismatch => 'RBAC role mismatch',
            self::ScopeMismatch => 'RBAC scope mismatch',
            self::CanaryFailed => 'RBAC validation needs review',
            self::ManualAssignmentRequired => 'Manual role assignment required',
            self::UnsupportedApi => 'RBAC API unsupported',
        };
    }

    public function shortExplanation(): string
    {
        return match ($this) {
            self::MissingArtifacts => 'TenantPilot could not find the RBAC artifacts required for this tenant.',
            self::ServicePrincipalMissing => 'The provider app service principal could not be resolved in Microsoft Graph.',
            self::GroupMissing => 'The configured Intune RBAC group could not be found.',
            self::ServicePrincipalNotMember => 'The provider app service principal is not currently a member of the configured RBAC group.',
            self::AssignmentMissing => 'No matching Intune RBAC assignment could be confirmed for this tenant.',
            self::RoleMismatch => 'The existing Intune RBAC assignment uses a different role than expected.',
            self::ScopeMismatch => 'The existing Intune RBAC assignment targets a different scope than expected.',
            self::CanaryFailed => 'The RBAC canary checks reported a mismatch after setup completed.',
            self::ManualAssignmentRequired => 'This tenant requires a manual Intune RBAC role assignment outside the automated API path.',
            self::UnsupportedApi => 'This account type does not support the required Intune RBAC API path.',
        };
    }

    public function actionability(): string
    {
        return match ($this) {
            self::CanaryFailed => 'retryable_transient',
            self::ManualAssignmentRequired => 'prerequisite_missing',
            self::UnsupportedApi => 'non_actionable',
            default => 'prerequisite_missing',
        };
    }

    public function ownerLayer(): string
    {
        return PlatformVocabularyGlossary::OWNER_DOMAIN_OWNED;
    }

    public function ownerNamespace(): string
    {
        return 'rbac.intune';
    }

    public function platformReasonFamily(): PlatformReasonFamily
    {
        return PlatformReasonFamily::Authorization;
    }

    public function boundaryClassification(): string
    {
        return PlatformVocabularyGlossary::BOUNDARY_INTUNE_SPECIFIC;
    }

    /**
     * @return array<int, NextStepOption>
     */
    public function nextSteps(): array
    {
        return match ($this) {
            self::UnsupportedApi => [],
            self::ManualAssignmentRequired => [
                NextStepOption::instruction('Complete the Intune role assignment manually, then refresh RBAC status.', scope: 'tenant'),
            ],
            self::CanaryFailed => [
                NextStepOption::instruction('Review the RBAC canary checks and rerun the health check.', scope: 'tenant'),
            ],
            default => [
                NextStepOption::instruction('Review the RBAC setup and refresh the tenant RBAC status.', scope: 'tenant'),
            ],
        };
    }

    /**
     * @param  array<string, mixed>  $context
     */
    public function toReasonResolutionEnvelope(string $surface = 'detail', array $context = []): ReasonResolutionEnvelope
    {
        return new ReasonResolutionEnvelope(
            internalCode: $this->value,
            operatorLabel: $this->operatorLabel(),
            shortExplanation: $this->shortExplanation(),
            actionability: $this->actionability(),
            nextSteps: $this->nextSteps(),
            showNoActionNeeded: $this->actionability() === 'non_actionable',
            diagnosticCodeLabel: $this->value,
            reasonOwnership: new ReasonOwnershipDescriptor(
                ownerLayer: $this->ownerLayer(),
                ownerNamespace: $this->ownerNamespace(),
                reasonCode: $this->value,
                platformReasonFamily: $this->platformReasonFamily(),
            ),
        );
    }
}
