<?php

namespace Database\Factories;

use App\Models\ProviderConnection;
use App\Models\ProviderCredential;
use App\Models\ManagedEnvironment;
use App\Models\Workspace;
use App\Support\Providers\ProviderConnectionType;
use App\Support\Providers\ProviderConsentStatus;
use App\Support\Providers\ProviderCredentialKind;
use App\Support\Providers\ProviderCredentialSource;
use App\Support\Providers\ProviderVerificationStatus;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends Factory<ProviderConnection>
 */
class ProviderConnectionFactory extends Factory
{
    protected $model = ProviderConnection::class;

    public function definition(): array
    {
        return [
            'managed_environment_id' => ManagedEnvironment::factory()->for(Workspace::factory()),
            'workspace_id' => function (array $attributes): int {
                $tenantId = $attributes['managed_environment_id'] ?? null;

                if (! is_numeric($tenantId)) {
                    return (int) Workspace::factory()->create()->getKey();
                }

                $tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->first();

                if (! $tenant instanceof ManagedEnvironment) {
                    return (int) Workspace::factory()->create()->getKey();
                }

                if ($tenant->workspace_id === null) {
                    $workspaceId = (int) Workspace::factory()->create()->getKey();
                    $tenant->forceFill(['workspace_id' => $workspaceId])->save();

                    return $workspaceId;
                }

                return (int) $tenant->workspace_id;
            },
            'provider' => 'microsoft',
            'entra_tenant_id' => fake()->uuid(),
            'display_name' => fake()->company(),
            'is_default' => false,
            '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,
            'scopes_granted' => [],
            'last_health_check_at' => null,
            'last_error_reason_code' => null,
            'last_error_message' => null,
            'metadata' => [],
        ];
    }

    public function platform(): static
    {
        return $this->state(fn (): array => [
            'connection_type' => ProviderConnectionType::Platform->value,
        ]);
    }

    public function minimal(): static
    {
        return $this->platform()->state(fn (): array => [
            'is_default' => false,
            'verification_status' => ProviderVerificationStatus::Unknown->value,
        ]);
    }

    public function dedicated(): static
    {
        return $this->state(fn (): array => [
            'connection_type' => ProviderConnectionType::Dedicated->value,
        ]);
    }

    public function standard(): static
    {
        return $this->dedicated()
            ->verifiedHealthy()
            ->state(fn (): array => [
                'is_default' => true,
            ]);
    }

    public function consentGranted(): static
    {
        return $this->state(fn (): array => [
            'is_enabled' => true,
            'consent_status' => ProviderConsentStatus::Granted->value,
            'consent_granted_at' => now(),
            'consent_last_checked_at' => now(),
        ]);
    }

    public function verifiedHealthy(): static
    {
        return $this->state(fn (): array => [
            'is_enabled' => true,
            'consent_status' => ProviderConsentStatus::Granted->value,
            'consent_granted_at' => now(),
            'consent_last_checked_at' => now(),
            'verification_status' => ProviderVerificationStatus::Healthy->value,
            'last_health_check_at' => now(),
        ]);
    }

    public function disabled(): static
    {
        return $this->state(fn (): array => [
            'is_enabled' => false,
        ]);
    }

    public function withCredential(): static
    {
        return $this->dedicated()
            ->verifiedHealthy()
            ->state(fn (): array => [
                'is_default' => true,
            ])
            ->afterCreating(function (ProviderConnection $connection): void {
                if ($connection->credential()->exists()) {
                    return;
                }

                ProviderCredential::factory()->create([
                    'provider_connection_id' => (int) $connection->getKey(),
                    'type' => ProviderCredentialKind::ClientSecret->value,
                    'credential_kind' => ProviderCredentialKind::ClientSecret->value,
                    'source' => ProviderCredentialSource::DedicatedManual->value,
                    'last_rotated_at' => now(),
                    'expires_at' => now()->addYear(),
                    'payload' => [
                        'client_id' => fake()->uuid(),
                        'client_secret' => fake()->sha1(),
                    ],
                ]);

                $connection->refresh();
            });
    }

    public function full(): static
    {
        return $this->withCredential();
    }
}
