<?php

namespace Tests\Feature\Auth;

use App\Models\User;
use App\Services\AddonService\IAddonService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Route;
use Spatie\Permission\Models\Role;
use Tests\TestCase;
use Tests\Traits\CreatesUsers;

class WebLoginRedirectTest extends TestCase
{
    use CreatesUsers;
    use RefreshDatabase;

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

        $this->ensureSettingsExist();

        // Register a stub route for multitenancycore.tenant.dashboard
        // in case the MultiTenancyCore module is not loaded in the test environment
        if (! Route::has('multitenancycore.tenant.dashboard')) {
            Route::get('/tenant/dashboard', fn () => 'tenant dashboard')
                ->name('multitenancycore.tenant.dashboard');

            // Refresh route name lookups so route() helper can resolve the name
            app('router')->getRoutes()->refreshNameLookups();
        }
    }

    /**
     * Helper to mock the AddonService for login tests.
     */
    private function mockAddonService(bool $multiTenancyEnabled = false): void
    {
        $addonService = $this->mock(IAddonService::class);
        $addonService->shouldReceive('isAddonEnabled')
            ->andReturnUsing(function (string $name) use ($multiTenancyEnabled) {
                return $name === 'MultiTenancyCore' && $multiTenancyEnabled;
            });
    }

    public function test_tenant_user_redirects_to_tenant_dashboard_on_central_domain(): void
    {
        Role::create([
            'name' => 'tenant',
            'guard_name' => 'web',
            'is_web_access_enabled' => true,
        ]);

        $user = User::factory()->withPassword('password123')->create();
        $user->assignRole('tenant');

        $this->mockAddonService(multiTenancyEnabled: true);

        $response = $this->post(route('auth.loginPost'), [
            'email' => $user->email,
            'password' => 'password123',
        ]);

        $response->assertRedirect('/tenant/dashboard');
    }

    public function test_tenant_user_redirects_to_tenant_dashboard_after_logout_and_relogin(): void
    {
        Role::create([
            'name' => 'tenant',
            'guard_name' => 'web',
            'is_web_access_enabled' => true,
        ]);

        $user = User::factory()->withPassword('password123')->create();
        $user->assignRole('tenant');

        $this->mockAddonService(multiTenancyEnabled: true);

        // First login
        $this->post(route('auth.loginPost'), [
            'email' => $user->email,
            'password' => 'password123',
        ]);

        // Logout (session should be invalidated)
        $this->post(route('auth.logout'));

        // Re-login should still redirect to tenant dashboard
        $response = $this->post(route('auth.loginPost'), [
            'email' => $user->email,
            'password' => 'password123',
        ]);

        $response->assertRedirect('/tenant/dashboard');
    }

    public function test_regular_user_redirects_to_dashboard(): void
    {
        $this->ensureRoleExists('admin');

        $user = User::factory()->withPassword('password123')->create();
        $user->assignRole('admin');

        $this->mockAddonService(multiTenancyEnabled: false);

        $response = $this->post(route('auth.loginPost'), [
            'email' => $user->email,
            'password' => 'password123',
        ]);

        $response->assertRedirect(route('dashboard'));
    }

    public function test_logout_invalidates_session(): void
    {
        $this->ensureRoleExists('admin');
        $user = $this->createAdmin();

        $this->actingAs($user);

        $response = $this->post(route('auth.logout'));

        $response->assertRedirect('auth/login');
        $this->assertGuest();
    }

    public function test_tenant_user_not_blocked_by_web_access_check(): void
    {
        // Create tenant role with web access DISABLED
        Role::create([
            'name' => 'tenant',
            'guard_name' => 'web',
            'is_web_access_enabled' => false,
        ]);

        $user = User::factory()->withPassword('password123')->create();
        $user->assignRole('tenant');

        $this->mockAddonService(multiTenancyEnabled: true);

        // Tenant user should still be able to login even with web access disabled
        $response = $this->post(route('auth.loginPost'), [
            'email' => $user->email,
            'password' => 'password123',
        ]);

        $response->assertRedirect('/tenant/dashboard');
    }
}
