<?php

namespace Tests\Feature;

use App\Filament\Pages\ProjectOverview;
use App\Filament\Resources\ProjectDecisions\ProjectDecisionResource;
use App\Filament\Resources\ProjectPhases\ProjectPhaseResource;
use App\Filament\Resources\Projects\ProjectResource;
use App\Filament\Resources\RequirementQuestions\RequirementQuestionResource;
use App\Models\Project;
use App\Models\ProjectDecision;
use App\Models\RequirementQuestion;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ProjectHubTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();

        $this->withoutVite();
        $this->seed(DatabaseSeeder::class);
    }

    public function test_public_home_is_available_without_authentication(): void
    {
        $this->get(route('home'))
            ->assertOk()
            ->assertSee('One Check')
            ->assertSee('Sistema em desenvolvimento')
            ->assertSee('Acessar sistema')
            ->assertSee(url('/admin'));
    }

    public function test_guest_is_redirected_to_login_when_accessing_the_admin(): void
    {
        $this->get(route('filament.admin.pages.project-overview'))
            ->assertRedirect(route('filament.admin.auth.login'));
    }

    public function test_login_uses_the_one_check_branding_without_replacing_filament_authentication(): void
    {
        $this->get(route('filament.admin.auth.login'))
            ->assertOk()
            ->assertSee('Bem-vindo ao One Check')
            ->assertSee('One Check — Rhodia')
            ->assertSee('images/brand/one-check-login-1280.webp')
            ->assertSee('© 2026 Katoen Natie do Brasil.')
            ->assertSee('wire:submit="authenticate"', false);
    }

    public function test_authenticated_user_can_access_the_project_overview(): void
    {
        $response = $this->actingAs(User::factory()->create())
            ->get(route('filament.admin.pages.project-overview'));

        $response
            ->assertOk()
            ->assertSee('One Check')
            ->assertSee('One Check — Rhodia')
            ->assertSee('Cliente')
            ->assertSee('Rhodia')
            ->assertSee('Fluig')
            ->assertSee('250857')
            ->assertSee('Em desenvolvimento')
            ->assertSee('Discovery')
            ->assertSee('Disponibilizar uma ferramenta centralizada e parametrizável')
            ->assertSee('© 2026 Katoen Natie do Brasil.')
            ->assertSee('project-overview__scrollable', false)
            ->assertSeeInOrder([
                'project-overview__objective',
                'project-overview__phases',
                'project-overview__questions',
                'project-overview__narrative-grid',
                'project-overview__decisions',
            ], false);
    }

    public function test_project_phases_are_displayed_in_the_configured_order(): void
    {
        $this->actingAs(User::factory()->create())
            ->get(route('filament.admin.pages.project-overview'))
            ->assertOk()
            ->assertSeeInOrder([
                'Discovery',
                'Requisitos',
                'Modelagem',
                'MVP',
                'Homologação',
                'Produção',
            ]);
    }

    public function test_only_open_questions_appear_in_the_open_questions_section(): void
    {
        $project = Project::query()->sole();

        RequirementQuestion::query()->create([
            'project_id' => $project->id,
            'question' => 'Qual campo identifica o tipo de operação?',
            'status' => 'open',
        ]);

        RequirementQuestion::query()->create([
            'project_id' => $project->id,
            'question' => 'A combinação Cliente + Item foi confirmada?',
            'answer' => 'Sim.',
            'status' => 'answered',
            'answered_by' => 'Planning',
            'answered_at' => now(),
        ]);

        $this->actingAs(User::factory()->create())
            ->get(route('filament.admin.pages.project-overview'))
            ->assertOk()
            ->assertSee('Qual campo identifica o tipo de operação?')
            ->assertDontSee('A combinação Cliente + Item foi confirmada?');
    }

    public function test_registered_decision_appears_in_the_project_overview(): void
    {
        $project = Project::query()->sole();

        ProjectDecision::query()->create([
            'project_id' => $project->id,
            'title' => 'Validar cenário operacional no Discovery',
            'description' => 'A composição final do cenário será validada com o time de Planning.',
            'decided_by' => 'Equipe do projeto',
            'decided_at' => now(),
        ]);

        $this->actingAs(User::factory()->create())
            ->get(route('filament.admin.pages.project-overview'))
            ->assertOk()
            ->assertSee('Validar cenário operacional no Discovery')
            ->assertSee('Equipe do projeto');
    }

    public function test_project_hub_resources_are_available_in_filament(): void
    {
        $user = User::factory()->create();

        foreach ([
            'filament.admin.resources.project-phases.index',
            'filament.admin.resources.requirement-questions.index',
            'filament.admin.resources.project-decisions.index',
        ] as $route) {
            $this->actingAs($user)
                ->get(route($route))
                ->assertOk();
        }
    }

    public function test_project_resource_is_not_registered_in_navigation(): void
    {
        $this->assertFalse(ProjectResource::shouldRegisterNavigation());
    }

    public function test_project_management_navigation_is_grouped_and_ordered(): void
    {
        $navigation = [
            ProjectOverview::class => ['Visão Geral', 1],
            ProjectPhaseResource::class => ['Fases', 2],
            RequirementQuestionResource::class => ['Perguntas de Requisitos', 3],
            ProjectDecisionResource::class => ['Decisões', 4],
        ];

        foreach ($navigation as $item => [$label, $sort]) {
            $this->assertSame('Gestão do Projeto', $item::getNavigationGroup());
            $this->assertSame($label, $item::getNavigationLabel());
            $this->assertSame($sort, $item::getNavigationSort());
        }
    }
}
