<?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 AuthTwoFactorTest extends TestCase
{
    use RefreshDatabase;

    public function test_api_login_returns_challenge_when_two_factor_enabled(): void
    {
        $user = User::factory()->create([
            'email' => '2fa@example.com',
            'password' => bcrypt('password'),
            'allow_login' => true,
        ]);

        app(TwoFactorService::class)->enableEmail($user);

        $login = $this->postJson('/api/auth/login', [
            'email' => '2fa@example.com',
            'password' => 'password',
        ]);

        $login->assertOk();
        $login->assertJsonPath('requires_two_factor', true);
        $login->assertJsonPath('method', 'email');
        $login->assertJsonStructure(['challenge_token']);

        $code = Cache::get('two_factor_login:'.$user->id);
        $this->assertNotEmpty($code);

        $verify = $this->postJson('/api/auth/two-factor/verify', [
            'challenge_token' => $login->json('challenge_token'),
            'code' => $code,
        ]);

        $verify->assertOk();
        $verify->assertJsonStructure(['token', 'user']);
    }

    public function test_api_login_blocks_totp_enrollment_until_web_setup(): void
    {
        $user = User::factory()->create([
            'company_id' => 42,
            'email' => 'enroll@example.com',
            'password' => bcrypt('password'),
            'allow_login' => true,
        ]);

        CompanySetting::create([
            'company_id' => 42,
            'key' => TwoFactorService::SETTING_POLICY,
            'value' => TwoFactorService::POLICY_REQUIRED,
        ]);
        CompanySetting::create([
            'company_id' => 42,
            'key' => TwoFactorService::SETTING_DEFAULT_METHOD,
            'value' => TwoFactorService::METHOD_TOTP,
        ]);

        $response = $this->postJson('/api/auth/login', [
            'email' => 'enroll@example.com',
            'password' => 'password',
        ]);

        $response->assertStatus(403);
        $response->assertJsonPath('error', 'two_factor_enrollment_required');
    }

    public function test_face_login_is_disabled_by_default(): void
    {
        $response = $this->postJson('/api/face/login', [
            'face_data' => 'data:image/png;base64,abc',
        ]);

        $response->assertStatus(403);
        $response->assertJsonPath('error', 'face_login_disabled');
    }

    public function test_disable_for_company_clears_two_factor(): void
    {
        $user = User::factory()->create([
            'company_id' => 99,
            'allow_login' => true,
        ]);

        $twoFactor = app(TwoFactorService::class);
        $twoFactor->enableEmail($user);
        $this->assertTrue($user->fresh()->two_factor_enabled);

        $twoFactor->disableForCompany(99);

        $this->assertFalse($user->fresh()->two_factor_enabled);
    }
}
