<?php

namespace Tests\Feature;

use App\Models\InvestmentSetting;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class MaintenanceModeTest extends TestCase
{
    use RefreshDatabase;

    private function enableMaintenance(): void
    {
        InvestmentSetting::current()->update(['maintenance_mode_enabled' => true]);
    }

    public function test_guest_is_redirected_to_maintenance_page_when_enabled(): void
    {
        $this->enableMaintenance();

        $this->get(route('dashboard'))
            ->assertRedirect(route('maintenance'));

        $this->get(route('maintenance'))
            ->assertOk()
            ->assertInertia(fn ($page) => $page->component('maintenance'));
    }

    public function test_home_redirects_to_maintenance_for_guests(): void
    {
        $this->enableMaintenance();

        $this->get(route('home'))
            ->assertRedirect(route('maintenance'));
    }

    public function test_non_admin_cannot_login_during_maintenance(): void
    {
        $this->enableMaintenance();

        $user = User::factory()->create();

        $this->post(route('login.store'), [
            'email' => $user->email,
            'password' => 'password',
        ])->assertSessionHasErrors('email');

        $this->assertGuest();
    }

    public function test_admin_can_login_during_maintenance(): void
    {
        $this->enableMaintenance();

        $admin = User::factory()->admin()->create();

        $this->post(route('login.store'), [
            'email' => $admin->email,
            'password' => 'password',
        ])->assertRedirect(route('admin.home', absolute: false));

        $this->assertAuthenticatedAs($admin);
    }

    public function test_unverified_admin_can_login_during_maintenance(): void
    {
        $this->enableMaintenance();

        $admin = User::factory()->admin()->unverified()->create();

        $this->post(route('login.store'), [
            'email' => $admin->email,
            'password' => 'password',
        ])->assertRedirect(route('admin.home', absolute: false));

        $this->assertAuthenticatedAs($admin);
    }

    public function test_authenticated_investor_is_logged_out_and_redirected(): void
    {
        $this->enableMaintenance();

        $investor = User::factory()->create();

        $this->actingAs($investor)
            ->get(route('dashboard'))
            ->assertRedirect(route('maintenance'));

        $this->assertGuest();
    }

    public function test_authenticated_investor_is_logged_out_when_visiting_maintenance_page(): void
    {
        $this->enableMaintenance();

        $investor = User::factory()->create();

        $this->actingAs($investor)
            ->get(route('maintenance'))
            ->assertOk()
            ->assertInertia(fn ($page) => $page->component('maintenance'));

        $this->assertGuest();
    }

    public function test_authenticated_admin_visiting_maintenance_is_redirected_to_admin(): void
    {
        $this->enableMaintenance();

        $admin = User::factory()->admin()->create();

        $this->actingAs($admin)
            ->get(route('maintenance'))
            ->assertRedirect(route('admin.home'));
    }

    public function test_authenticated_admin_can_access_dashboard_during_maintenance(): void
    {
        $this->enableMaintenance();

        $admin = User::factory()->admin()->create();

        $this->actingAs($admin)
            ->get(route('dashboard'))
            ->assertOk();
    }

    public function test_login_page_shows_maintenance_notice(): void
    {
        $this->enableMaintenance();

        $this->get(route('login'))
            ->assertOk()
            ->assertInertia(fn ($page) => $page
                ->component('auth/login')
                ->where('maintenanceMode', true)
                ->where('canRegister', false));
    }

    public function test_register_is_blocked_during_maintenance(): void
    {
        $this->enableMaintenance();

        $this->get('/register')
            ->assertRedirect(route('maintenance'));
    }
}
