<?php

namespace Database\Factories;

use App\Models\OperationRun;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Models\Workspace;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OperationRunType;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends Factory<OperationRun>
 */
class OperationRunFactory extends Factory
{
    protected $model = OperationRun::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;
            },
            'user_id' => null,
            'initiator_name' => 'System',
            'type' => fake()->randomElement(OperationRunType::values()),
            'status' => OperationRunStatus::Queued->value,
            'outcome' => OperationRunOutcome::Pending->value,
            'run_identity_hash' => fake()->sha256(),
            'summary_counts' => [],
            'failure_summary' => [],
            'context' => [],
            'started_at' => null,
            'completed_at' => null,
        ];
    }

    public function minimal(): static
    {
        return $this->state(fn (): array => [
            'user_id' => null,
            'initiator_name' => 'System',
        ]);
    }

    public function withUser(?User $user = null): static
    {
        return $this->state(fn (): array => [
            'user_id' => $user?->getKey() ?? User::factory(),
            'initiator_name' => $user?->name ?? fake()->name(),
        ]);
    }

    public function forTenant(ManagedEnvironment $tenant): static
    {
        return $this->state(fn (): array => [
            'managed_environment_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
        ]);
    }

    public function tenantlessForWorkspace(Workspace $workspace): static
    {
        return $this->state(fn (): array => [
            'managed_environment_id' => null,
            'workspace_id' => (int) $workspace->getKey(),
        ]);
    }

    public function queued(): static
    {
        return $this->state(fn (): array => [
            'status' => OperationRunStatus::Queued->value,
            'outcome' => OperationRunOutcome::Pending->value,
        ]);
    }
}
