<?php

namespace Tests\Feature;

use App\Models\CompanySetting;
use App\Models\User;
use App\Services\TwoFactorService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;

class WebTwoFactorTest extends TestCase
{
    use RefreshDatabase;

    public function test_login_redirects_to_two_factor_challenge_when_enabled(): void
    {
        $user = User::factory()->create([
            'email' => 'web-2fa@example.com',
            'password' => bcrypt('password'),
            'allow_login' => true,
        ]);

        app(TwoFactorService::class)->enableEmail($user);

        $response = $this->post('/login', [
            'email' => 'web-2fa@example.com',
            'password' => 'password',
        ]);

        $response->assertRedirect(route('two-factor.challenge'));
        $this->assertGuest();
        $this->assertSame($user->id, session('login.id'));
    }

    public function test_two_factor_verify_authenticates_user(): void
    {
        $user = User::factory()->create([
            'email' => 'verify-2fa@example.com',
            'password' => bcrypt('password'),
            'allow_login' => true,
        ]);

        $twoFactor = app(TwoFactorService::class);
        $twoFactor->enableEmail($user);
        $twoFactor->sendLoginCode($user);
        $code = Cache::get('two_factor_login:'.$user->id);

        $response = $this->withSession([
            'login.id' => $user->id,
            'login.remember' => false,
        ])->post(route('two-factor.verify'), [
            'code' => $code,
        ]);

        $response->assertRedirect();
        $this->assertAuthenticatedAs($user);
    }

    public function test_login_without_two_factor_authenticates_immediately(): void
    {
        $user = User::factory()->create([
            'email' => 'plain@example.com',
            'password' => bcrypt('password'),
            'allow_login' => true,
        ]);

        $response = $this->post('/login', [
            'email' => 'plain@example.com',
            'password' => 'password',
        ]);

        $response->assertRedirect();
        $this->assertAuthenticatedAs($user);
    }

    public function test_required_policy_redirects_unenrolled_user_to_profile_security(): void
    {
        $user = User::factory()->create([
            'company_id' => 12,
            'user_type' => User::USER_TYPE_ADMIN,
            'allow_login' => true,
        ]);

        CompanySetting::create([
            'company_id' => 12,
            'key' => TwoFactorService::SETTING_POLICY,
            'value' => TwoFactorService::POLICY_REQUIRED,
        ]);

        $this->actingAs($user);

        $response = $this->get(route('dashboard.self'));

        $response->assertRedirect(route('settings.profile').'#security');
    }
}
