<?php

namespace Tests\Feature;

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

class UserFactorSemanticsTest extends TestCase
{
    use RefreshDatabase;

    private function totpUser(): User
    {
        return User::factory()->create(['two_factor_secret' => 'S', 'two_factor_confirmed_at' => now()]);
    }

    private function keyUser(): User
    {
        $u = User::factory()->create();
        WebauthnCredential::create(['user_id' => $u->id, 'name' => 'k', 'credential_id' => 'cid', 'public_key' => '{}', 'sign_count' => 0]);

        return $u->fresh();
    }

    public function test_has_totp_only_reflects_totp(): void
    {
        $this->assertTrue($this->totpUser()->hasTotp());
        $this->assertFalse($this->keyUser()->hasTotp());
    }

    public function test_has_two_factor_enabled_is_either_factor(): void
    {
        $this->assertTrue($this->totpUser()->hasTwoFactorEnabled());
        $this->assertTrue($this->keyUser()->hasTwoFactorEnabled());
        $this->assertFalse(User::factory()->create()->hasTwoFactorEnabled());
    }

    public function test_security_onboarded_is_password_rotation_only(): void
    {
        $this->assertTrue(User::factory()->create(['must_change_password' => false])->securityOnboarded());
        $this->assertFalse(User::factory()->create(['must_change_password' => true])->securityOnboarded());
    }

    public function test_reset_if_no_factor_clears_codes_only_when_no_factor_remains(): void
    {
        $totp = $this->totpUser();
        $totp->replaceRecoveryCodes();
        $totp->resetIfNoFactor();
        $this->assertTrue($totp->fresh()->hasRecoveryCodes(), 'codes kept while a factor remains');

        $none = User::factory()->create();
        $none->replaceRecoveryCodes();
        $none->resetIfNoFactor();
        $this->assertFalse($none->fresh()->hasRecoveryCodes(), 'codes cleared when no factor remains');
    }
}
