<?php

use App\Models\Consultation;
use App\Models\Timeline;
use App\Models\TimelineUpdate;
use App\Models\User;
use Livewire\Volt\Volt;

// Authorization Tests
test('client can view their dashboard', function () {
    $user = User::factory()->individual()->create();

    $this->actingAs($user)
        ->get(route('client.dashboard'))
        ->assertOk();
});

test('company client can view dashboard', function () {
    $user = User::factory()->company()->create();

    $this->actingAs($user)
        ->get(route('client.dashboard'))
        ->assertOk();
});

test('unauthenticated user cannot access dashboard', function () {
    $this->get(route('client.dashboard'))
        ->assertRedirect(route('login'));
});

test('admin cannot access client dashboard', function () {
    $admin = User::factory()->admin()->create();

    $this->actingAs($admin)
        ->get(route('client.dashboard'))
        ->assertForbidden();
});

// Welcome Section Tests
test('dashboard shows welcome message with user name', function () {
    $user = User::factory()->individual()->create(['full_name' => 'John Doe']);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee('John Doe');
});

// Upcoming Consultation Widget Tests
test('dashboard shows upcoming approved consultation', function () {
    $user = User::factory()->individual()->create();
    $consultation = Consultation::factory()->approved()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(3),
        'booking_time' => '10:00:00',
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee('10:00 AM');
});

test('dashboard shows only authenticated user consultations', function () {
    $user = User::factory()->individual()->create();
    $otherUser = User::factory()->individual()->create();

    Consultation::factory()->approved()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(3),
        'booking_time' => '09:00:00',
    ]);
    Consultation::factory()->approved()->create([
        'user_id' => $otherUser->id,
        'booking_date' => today()->addDays(2),
        'booking_time' => '14:00:00',
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee('9:00 AM')
        ->assertDontSee('2:00 PM');
});

test('dashboard shows no upcoming consultations when none exist', function () {
    $user = User::factory()->individual()->create();

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.no_upcoming'));
});

test('dashboard does not show past approved consultations', function () {
    $user = User::factory()->individual()->create();
    Consultation::factory()->approved()->create([
        'user_id' => $user->id,
        'booking_date' => today()->subDay(),
        'booking_time' => '10:00:00',
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.no_upcoming'));
});

test('dashboard does not show pending consultations as upcoming', function () {
    $user = User::factory()->individual()->create();
    Consultation::factory()->pending()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(3),
        'booking_time' => '11:00:00',
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.no_upcoming'));
});

// Active Cases Widget Tests
test('dashboard shows correct active timelines count', function () {
    $user = User::factory()->individual()->create();
    Timeline::factory()->active()->count(3)->create(['user_id' => $user->id]);
    Timeline::factory()->archived()->count(2)->create(['user_id' => $user->id]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee('3');
});

test('dashboard shows no cases empty state when user has no timelines', function () {
    $user = User::factory()->individual()->create();

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.no_cases'));
});

test('dashboard shows latest update preview for active cases', function () {
    $user = User::factory()->individual()->create();
    $timeline = Timeline::factory()->active()->create(['user_id' => $user->id]);
    TimelineUpdate::factory()->create([
        'timeline_id' => $timeline->id,
        'update_text' => 'This is the latest case update for testing purposes.',
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee('This is the latest case update');
});

// Recent Updates Widget Tests
test('dashboard shows last 3 timeline updates', function () {
    $user = User::factory()->individual()->create();
    $timeline = Timeline::factory()->create(['user_id' => $user->id]);

    TimelineUpdate::factory()->create([
        'timeline_id' => $timeline->id,
        'update_text' => 'Update One',
        'created_at' => now()->subDays(4),
    ]);
    TimelineUpdate::factory()->create([
        'timeline_id' => $timeline->id,
        'update_text' => 'Update Two',
        'created_at' => now()->subDays(3),
    ]);
    TimelineUpdate::factory()->create([
        'timeline_id' => $timeline->id,
        'update_text' => 'Update Three',
        'created_at' => now()->subDays(2),
    ]);
    TimelineUpdate::factory()->create([
        'timeline_id' => $timeline->id,
        'update_text' => 'Update Four',
        'created_at' => now()->subDay(),
    ]);
    TimelineUpdate::factory()->create([
        'timeline_id' => $timeline->id,
        'update_text' => 'Update Five',
        'created_at' => now(),
    ]);

    $this->actingAs($user);

    // Should see the 3 most recent updates, not the older ones
    Volt::test('client.dashboard')
        ->assertSee('Update Five')
        ->assertSee('Update Four')
        ->assertSee('Update Three')
        ->assertDontSee('Update Two')
        ->assertDontSee('Update One');
});

test('dashboard shows no updates empty state when user has no timeline updates', function () {
    $user = User::factory()->individual()->create();

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.no_updates'));
});

// Booking Status Widget Tests
test('canBookToday is false when user has approved booking today', function () {
    $user = User::factory()->individual()->create();
    Consultation::factory()->approved()->create([
        'user_id' => $user->id,
        'booking_date' => today(),
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.cannot_book'));
});

test('canBookToday is false when user has pending booking today', function () {
    $user = User::factory()->individual()->create();
    Consultation::factory()->pending()->create([
        'user_id' => $user->id,
        'booking_date' => today(),
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.cannot_book'));
});

test('canBookToday is true when user has no booking today', function () {
    $user = User::factory()->individual()->create();

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.can_book'));
});

test('canBookToday is true when user has only rejected booking today', function () {
    $user = User::factory()->individual()->create();
    Consultation::factory()->rejected()->create([
        'user_id' => $user->id,
        'booking_date' => today(),
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.can_book'));
});

test('canBookToday is true when user has only cancelled booking today', function () {
    $user = User::factory()->individual()->create();
    Consultation::factory()->cancelled()->create([
        'user_id' => $user->id,
        'booking_date' => today(),
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.can_book'));
});

test('dashboard shows pending bookings count', function () {
    $user = User::factory()->individual()->create();
    Consultation::factory()->pending()->count(3)->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(5),
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee('3');
});

// Empty State Tests
test('dashboard handles empty state gracefully', function () {
    $user = User::factory()->individual()->create();

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertSee(__('client.dashboard.no_upcoming'))
        ->assertSee(__('client.dashboard.no_cases'))
        ->assertSee(__('client.dashboard.no_updates'))
        ->assertSee(__('client.dashboard.can_book'));
});

// Data Isolation Tests
test('dashboard does not show other users timeline updates', function () {
    $user = User::factory()->individual()->create();
    $otherUser = User::factory()->individual()->create();

    $otherTimeline = Timeline::factory()->create(['user_id' => $otherUser->id]);
    TimelineUpdate::factory()->create([
        'timeline_id' => $otherTimeline->id,
        'update_text' => 'Other user secret update',
    ]);

    $this->actingAs($user);

    Volt::test('client.dashboard')
        ->assertDontSee('Other user secret update');
});

test('dashboard does not count other users active timelines', function () {
    $user = User::factory()->individual()->create();
    $otherUser = User::factory()->individual()->create();

    Timeline::factory()->active()->create(['user_id' => $user->id]);
    Timeline::factory()->active()->count(5)->create(['user_id' => $otherUser->id]);

    $this->actingAs($user);

    // User should only see their 1 active timeline, not the 5 from other user
    Volt::test('client.dashboard')
        ->assertSee('1');
});
