<?php

namespace App\Filament\Resources\ProviderConnectionResource\Pages;

use App\Filament\Resources\ProviderConnectionResource;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Services\Intune\AuditLogger;
use App\Support\Providers\ProviderConnectionType;
use App\Support\Providers\ProviderConsentStatus;
use App\Support\Providers\ProviderReasonCodes;
use App\Support\Providers\TargetScope\ProviderConnectionTargetScopeDescriptor;
use App\Support\Providers\TargetScope\ProviderConnectionTargetScopeNormalizer;
use App\Support\Providers\ProviderVerificationStatus;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Validation\ValidationException;

class CreateProviderConnection extends CreateRecord
{
    protected static string $resource = ProviderConnectionResource::class;

    protected bool $shouldMakeDefault = false;

    protected function mutateFormDataBeforeCreate(array $data): array
    {
        $tenant = $this->currentTenant();

        if (! $tenant instanceof ManagedEnvironment) {
            abort(404);
        }

        $this->shouldMakeDefault = (bool) ($data['is_default'] ?? false);
        $targetScope = app(ProviderConnectionTargetScopeNormalizer::class)->normalizeInput(
            provider: 'microsoft',
            scopeKind: ProviderConnectionTargetScopeDescriptor::SCOPE_KIND_TENANT,
            scopeIdentifier: (string) ($data['entra_tenant_id'] ?? ''),
            scopeDisplayName: (string) ($data['display_name'] ?? ''),
            providerSpecificIdentity: [
                'microsoft_tenant_id' => (string) ($data['entra_tenant_id'] ?? ''),
            ],
        );

        if ($targetScope['status'] !== ProviderConnectionTargetScopeNormalizer::STATUS_NORMALIZED) {
            throw ValidationException::withMessages([
                'entra_tenant_id' => $targetScope['message'],
            ]);
        }

        return [
            'workspace_id' => (int) $tenant->workspace_id,
            'managed_environment_id' => $tenant->getKey(),
            'provider' => 'microsoft',
            'entra_tenant_id' => $data['entra_tenant_id'],
            'display_name' => $data['display_name'],
            'is_enabled' => true,
            'connection_type' => ProviderConnectionType::Platform->value,
            'consent_status' => ProviderConsentStatus::Required->value,
            'consent_granted_at' => null,
            'consent_last_checked_at' => null,
            'consent_error_code' => null,
            'consent_error_message' => null,
            'verification_status' => ProviderVerificationStatus::Unknown->value,
            'migration_review_required' => false,
            'migration_reviewed_at' => null,
            'last_error_reason_code' => ProviderReasonCodes::ProviderConsentMissing,
            'last_error_message' => null,
            'is_default' => false,
        ];
    }

    protected function afterCreate(): void
    {
        $tenant = $this->currentTenant();

        if (! $tenant instanceof ManagedEnvironment) {
            abort(404);
        }

        $record = $this->getRecord();

        $user = auth()->user();
        $actorId = $user instanceof User ? (int) $user->getKey() : null;
        $actorEmail = $user instanceof User ? $user->email : null;
        $actorName = $user instanceof User ? $user->name : null;

        app(AuditLogger::class)->log(
            tenant: $tenant,
            action: 'provider_connection.created',
            context: [
                'metadata' => ProviderConnectionResource::targetScopeAuditMetadata($record, [
                    'connection_type' => $record->connection_type->value,
                ]),
            ],
            actorId: $actorId,
            actorEmail: $actorEmail,
            actorName: $actorName,
            resourceType: 'provider_connection',
            resourceId: (string) $record->getKey(),
            status: 'success',
        );

        $hasDefault = $tenant->providerConnections()
            ->where('provider', $record->provider)
            ->where('is_default', true)
            ->exists();

        if ($this->shouldMakeDefault || ! $hasDefault) {
            $record->makeDefault();
        }

        Notification::make()
            ->title('Provider connection created')
            ->success()
            ->send();
    }

    private function currentTenant(): ?ManagedEnvironment
    {
        $tenant = ProviderConnectionResource::resolveTenantForCreate();

        if ($tenant instanceof ManagedEnvironment) {
            return $tenant;
        }

        return null;
    }
}
