<?php

namespace Tests\Feature;

use App\Models\Organization;
use App\Models\Role;
use App\Models\User;
use App\Models\UserAssignment;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;

class FoundationTest extends TestCase
{
    use RefreshDatabase;

    public function test_guest_is_redirected_to_login(): void
    {
        $this->get('/painel')->assertRedirect('/entrar');
        $this->get('/entrar')->assertOk()->assertSee('Bem-vindo ao NESTAB OPS');
    }

    public function test_first_login_requires_password_change(): void
    {
        $user = User::query()->create([
            'name' => 'Utilizador Inicial',
            'username' => 'utilizador.inicial',
            'email' => 'utilizador@nestab.test',
            'password' => Hash::make('Nestab2026'),
            'is_active' => true,
            'must_change_password' => true,
        ]);

        $this->post('/entrar', [
            'identity' => $user->username,
            'password' => 'Nestab2026',
        ])->assertRedirect('/painel');

        $this->assertAuthenticatedAs($user);
        $this->assertEquals('operation', session('operating_mode'));
        $this->get('/painel')->assertRedirect('/palavra-passe');

        $this->put('/palavra-passe', [
            'current_password' => 'Nestab2026',
            'password' => 'NovaNestab2026',
            'password_confirmation' => 'NovaNestab2026',
        ])->assertRedirect('/painel');

        $this->assertFalse($user->fresh()->must_change_password);
    }

    public function test_account_is_locked_after_five_failed_attempts(): void
    {
        $user = User::query()->create([
            'name' => 'Utilizador Teste',
            'email' => 'bloqueio@nestab.test',
            'password' => Hash::make('Nestab2026'),
            'is_active' => true,
            'must_change_password' => false,
        ]);

        for ($attempt = 1; $attempt <= 5; $attempt++) {
            $this->post('/entrar', ['identity' => $user->email, 'password' => 'Invalida2026']);
        }

        $this->assertNotNull($user->fresh()->locked_until);
        $this->post('/entrar', ['identity' => $user->email, 'password' => 'Nestab2026'])
            ->assertSessionHasErrors('identity');
        $this->assertGuest();
    }

    public function test_superadministrator_can_enter_administration_mode_without_reentering_password(): void
    {
        $user = User::query()->create([
            'name' => 'Superadministrador',
            'email' => 'superadmin@nestab.test',
            'password' => Hash::make('Nestab2026'),
            'is_active' => true,
            'must_change_password' => false,
        ]);
        $organization = Organization::query()->create(['code' => 'TEST', 'name' => 'NESTAB Teste']);
        $role = Role::query()->create([
            'code' => 'superadministrador', 'name' => 'Superadministrador',
            'is_privileged' => true, 'is_system' => true, 'is_active' => true,
        ]);
        UserAssignment::query()->create([
            'user_id' => $user->id, 'organization_id' => $organization->id,
            'role_id' => $role->id, 'is_primary' => true, 'is_active' => true,
        ]);

        $this->actingAs($user)->withSession(['operating_mode' => 'operation'])
            ->post('/modo-de-trabalho', ['mode' => 'administration'])
            ->assertSessionHas('success');

        $this->assertEquals('administration', session('operating_mode'));
        $this->assertNotNull(session('administration_mode_started_at'));
    }
}
