<?php

use App\Livewire\Auth\OperatorLogin;
use App\Models\Operator;
use App\Models\User;
use App\Support\AdminArea;
use Illuminate\Support\Facades\Auth;
use Livewire\Livewire;

it('offers no way to register — an operator account is not self-served', function () {
    $this->get(route('admin.login'))->assertOk()
        ->assertDontSee(route('register'))
        ->assertDontSee(__('auth.sign_up'));
});

it('sends an already signed-in operator back to the console instead of the portal', function () {
    // Codex + whole-branch review (M1), independently: guest:operator's
    // authenticated-user redirect had no console-aware override, so it fell
    // to Laravel's own default — the named 'dashboard' route, the PORTAL.
    // The web guard is usually unauthenticated there, so an operator
    // revisiting admin.login bounced straight to the portal's OWN login. In
    // exclusive mode it is worse: dashboard is not a console route at all,
    // so RestrictAdminHost 404s it on the console host.
    $operator = Operator::factory()->role('Owner')->create();

    $this->actingAs($operator, 'operator')
        ->get(route('admin.login'))
        ->assertRedirect(route('admin.overview'));
});

it('signs an operator in on the operator guard', function () {
    $operator = Operator::factory()->role('Owner')->create(['password' => 'richtig-langes-pw']);

    Livewire::test(OperatorLogin::class)
        ->set('email', $operator->email)
        ->set('password', 'richtig-langes-pw')
        ->call('authenticate')
        ->assertRedirect(AdminArea::home());

    expect(Auth::guard('operator')->check())->toBeTrue()
        ->and(Auth::guard('web')->check())->toBeFalse();
});

it('refuses a portal account at the console door', function () {
    $user = User::factory()->create(['email' => 'kunde@clupilot.test', 'password' => 'kunden-passwort']);

    Livewire::test(OperatorLogin::class)
        ->set('email', 'kunde@clupilot.test')
        ->set('password', 'kunden-passwort')
        ->call('authenticate')
        ->assertHasErrors('email');

    expect(Auth::guard('operator')->check())->toBeFalse();
});

it('refuses a disabled operator', function () {
    $operator = Operator::factory()->role('Owner')->create([
        'password' => 'richtig-langes-pw', 'disabled_at' => now(),
    ]);

    Livewire::test(OperatorLogin::class)
        ->set('email', $operator->email)
        ->set('password', 'richtig-langes-pw')
        ->call('authenticate')
        ->assertHasErrors('email');

    expect(Auth::guard('operator')->check())->toBeFalse();
});

it('sends an operator with confirmed two-factor to the challenge instead of the console', function () {
    $operator = Operator::factory()->role('Owner')->create([
        'password' => 'richtig-langes-pw',
        'two_factor_secret' => encrypt('JBSWY3DPEHPK3PXP'),
        'two_factor_confirmed_at' => now(),
    ]);

    Livewire::test(OperatorLogin::class)
        ->set('email', $operator->email)
        ->set('password', 'richtig-langes-pw')
        ->call('authenticate')
        ->assertRedirect(route('admin.two-factor'));

    // Not signed in yet — the challenge is not decoration.
    expect(Auth::guard('operator')->check())->toBeFalse();
});

it('throttles repeated failures', function () {
    $operator = Operator::factory()->role('Owner')->create(['password' => 'richtig-langes-pw']);

    $component = Livewire::test(OperatorLogin::class)->set('email', $operator->email)->set('password', 'falsch');

    foreach (range(1, 5) as $ignored) {
        $component->call('authenticate');
    }

    $component->call('authenticate')->assertHasErrors('email');
    expect(session()->has('login.id'))->toBeFalse();
});

it('refuses to complete a login for an operator who no longer qualifies', function () {
    // completeLogin() is the one place both the direct exit and the
    // two-factor challenge complete a sign-in — re-checked here so a
    // revocation in the window between the password step and a pending
    // two-factor code cannot slip through the challenge, which only ever
    // confirmed the row still existed.
    $disabled = Operator::factory()->role('Owner')->create(['disabled_at' => now()]);
    $roleless = Operator::factory()->create(); // no role synced at all

    expect(OperatorLogin::completeLogin($disabled, false))->toBeFalse()
        ->and(Auth::guard('operator')->check())->toBeFalse();

    expect(OperatorLogin::completeLogin($roleless, false))->toBeFalse()
        ->and(Auth::guard('operator')->check())->toBeFalse();
});

it('records when the operator last signed in', function () {
    $operator = Operator::factory()->role('Owner')->create(['password' => 'richtig-langes-pw']);

    Livewire::test(OperatorLogin::class)
        ->set('email', $operator->email)->set('password', 'richtig-langes-pw')
        ->call('authenticate');

    expect($operator->fresh()->last_login_at)->not->toBeNull();
});
