<?php

use App\Enums\AccountStatus;
use App\Enums\AccountType;
use App\Enums\Currency;
use App\Enums\UserStatus;
use App\Enums\UserType;
use App\Models\Account;
use App\Models\AppSetting;
use App\Models\User;

beforeEach(function () {
    AppSetting::set('otp_enabled', 'false');
    AppSetting::set('maintenance_mode', 'false');
});

test('login page renders', function () {
    $this->get('/login')->assertOk();
});

test('register page renders', function () {
    $this->get('/register')->assertOk();
});

test('user can login with valid credentials', function () {
    $user = User::factory()->create([
        'status' => UserStatus::Active,
        'type' => UserType::User,
        'password' => 'password',
    ]);

    Account::create([
        'user_id' => $user->id,
        'account_number' => Account::generateAccountNumber(),
        'account_type' => AccountType::Checking,
        'currency' => Currency::USD,
        'balance' => 1000,
        'status' => AccountStatus::Active,
    ]);

    $this->post('/login', [
        'email' => $user->email,
        'password' => 'password',
    ])->assertRedirect('/dashboard');

    $this->assertAuthenticatedAs($user);
});

test('user cannot login with invalid credentials', function () {
    User::factory()->create(['password' => 'password']);

    $this->post('/login', [
        'email' => 'wrong@example.com',
        'password' => 'wrongpassword',
    ])->assertSessionHasErrors('email');

    $this->assertGuest();
});

test('admin is redirected to admin dashboard on login', function () {
    $admin = User::factory()->create([
        'status' => UserStatus::Active,
        'type' => UserType::Admin,
        'password' => 'password',
    ]);

    $this->post('/login', [
        'email' => $admin->email,
        'password' => 'password',
    ])->assertRedirect(route('admin.dashboard'));
});

test('pending user is redirected to pending page on login', function () {
    $user = User::factory()->create([
        'status' => UserStatus::Pending,
        'type' => UserType::User,
        'password' => 'password',
    ]);

    $this->post('/login', [
        'email' => $user->email,
        'password' => 'password',
    ])->assertRedirect(route('pending'));
});

test('user can register', function () {
    $this->post('/register', [
        'first_name' => 'John',
        'last_name' => 'Doe',
        'email' => 'john@example.com',
        'phone' => '+1234567890',
        'password' => 'Password123!',
        'password_confirmation' => 'Password123!',
        'address' => '123 Main St',
        'country' => 'US',
        'dob' => '1990-01-01',
    ])->assertRedirect(route('pending'));

    $this->assertDatabaseHas('users', ['email' => 'john@example.com']);
    $this->assertDatabaseHas('accounts', [
        'account_type' => 'checking',
    ]);
});

test('user can logout', function () {
    $user = User::factory()->create();

    $this->actingAs($user)
        ->post('/logout')
        ->assertRedirect(route('login'));

    $this->assertGuest();
});

test('pending page renders for pending user', function () {
    $user = User::factory()->create([
        'status' => UserStatus::Pending,
        'type' => UserType::User,
    ]);

    $this->actingAs($user)
        ->get('/pending')
        ->assertOk();
});

test('otp page renders when otp enabled', function () {
    AppSetting::set('otp_enabled', 'true');

    $user = User::factory()->create([
        'status' => UserStatus::Active,
        'type' => UserType::User,
    ]);

    $this->actingAs($user)
        ->get('/otp')
        ->assertOk();
});

test('otp redirects to dashboard on successful verification', function () {
    AppSetting::set('otp_enabled', 'true');

    $user = User::factory()->create([
        'status' => UserStatus::Active,
        'type' => UserType::User,
    ]);

    Account::create([
        'user_id' => $user->id,
        'account_number' => Account::generateAccountNumber(),
        'account_type' => AccountType::Checking,
        'currency' => Currency::USD,
        'balance' => 1000,
        'status' => AccountStatus::Active,
    ]);

    $code = \App\Models\OtpCode::create([
        'user_id' => $user->id,
        'code' => '123456',
        'expires_at' => now()->addMinutes(5),
    ]);

    $this->actingAs($user)
        ->post('/otp/verify', ['code' => '123456'])
        ->assertRedirect(route('dashboard'));
});
