<?php

declare(strict_types=1);

namespace Database\Factories;

use App\Models\ReviewPack;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Models\Workspace;
use App\Support\ReviewPackStatus;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends Factory<ReviewPack>
 */
class ReviewPackFactory extends Factory
{
    protected $model = ReviewPack::class;

    /**
     * @return array<string, mixed>
     */
    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 || $tenant->workspace_id === null) {
                    return (int) Workspace::factory()->create()->getKey();
                }

                return (int) $tenant->workspace_id;
            },
            'initiated_by_user_id' => User::factory(),
            'evidence_snapshot_id' => null,
            'status' => ReviewPackStatus::Ready->value,
            'fingerprint' => fake()->sha256(),
            'previous_fingerprint' => null,
            'summary' => [
                'finding_count' => fake()->numberBetween(0, 100),
                'report_count' => fake()->numberBetween(0, 10),
            ],
            'options' => [
                'include_pii' => true,
                'include_operations' => true,
            ],
            'file_disk' => 'exports',
            'file_path' => fn () => 'review-packs/'.fake()->uuid().'.zip',
            'file_size' => fake()->numberBetween(1024, 1048576),
            'sha256' => fake()->sha256(),
            'generated_at' => now(),
            'expires_at' => now()->addDays(90),
        ];
    }

    public function queued(): static
    {
        return $this->state(fn (array $attributes): array => [
            'status' => ReviewPackStatus::Queued->value,
            'fingerprint' => null,
            'file_disk' => null,
            'file_path' => null,
            'file_size' => null,
            'sha256' => null,
            'generated_at' => null,
            'expires_at' => null,
        ]);
    }

    public function generating(): static
    {
        return $this->state(fn (array $attributes): array => [
            'status' => ReviewPackStatus::Generating->value,
            'fingerprint' => null,
            'file_disk' => null,
            'file_path' => null,
            'file_size' => null,
            'sha256' => null,
            'generated_at' => null,
            'expires_at' => null,
        ]);
    }

    public function ready(): static
    {
        return $this->state(fn (array $attributes): array => [
            'status' => ReviewPackStatus::Ready->value,
            'fingerprint' => fake()->sha256(),
            'file_disk' => 'exports',
            'file_path' => 'review-packs/'.fake()->uuid().'.zip',
            'file_size' => fake()->numberBetween(1024, 1048576),
            'sha256' => fake()->sha256(),
            'generated_at' => now(),
            'expires_at' => now()->addDays(90),
        ]);
    }

    public function failed(): static
    {
        return $this->state(fn (array $attributes): array => [
            'status' => ReviewPackStatus::Failed->value,
            'fingerprint' => null,
            'file_disk' => null,
            'file_path' => null,
            'file_size' => null,
            'sha256' => null,
            'generated_at' => null,
            'expires_at' => null,
        ]);
    }

    public function expired(): static
    {
        return $this->state(fn (array $attributes): array => [
            'status' => ReviewPackStatus::Expired->value,
            'fingerprint' => fake()->sha256(),
            'file_disk' => null,
            'file_path' => null,
            'file_size' => null,
            'sha256' => null,
            'generated_at' => now()->subDays(91),
            'expires_at' => now()->subDay(),
        ]);
    }
}
