<?php

use App\Enums\ConsultationStatus;
use App\Enums\ConsultationType;
use App\Enums\PaymentStatus;
use App\Models\Consultation;
use App\Models\User;
use Livewire\Volt\Volt;

// Access Control Tests
test('unauthenticated user is redirected to login', function () {
    $this->get(route('client.consultations.index'))
        ->assertRedirect(route('login'));
});

test('client can view their consultations page', function () {
    $user = User::factory()->individual()->create();

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

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

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

test('user sees only their own 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.consultations.index')
        ->assertSee('9:00 AM')
        ->assertDontSee('2:00 PM');
});

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

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee('10:00 AM')
        ->assertSee(__('booking.type_free'));
});

test('upcoming section is sorted by date ascending', function () {
    $user = User::factory()->individual()->create();

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

    $this->actingAs($user);

    $component = Volt::test('client.consultations.index');

    // The earlier date should appear first in upcoming
    $html = $component->html();
    $pos1 = strpos($html, '9:00 AM');
    $pos2 = strpos($html, '11:00 AM');

    expect($pos1)->toBeLessThan($pos2);
});

test('upcoming section displays consultation type correctly', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->approved()->free()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(2),
    ]);
    Consultation::factory()->approved()->paid()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(3),
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(__('booking.type_free'))
        ->assertSee(__('booking.type_paid'));
});

test('upcoming section shows payment status for paid consultations', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->approved()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(2),
        'consultation_type' => ConsultationType::Paid,
        'payment_status' => PaymentStatus::Pending,
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(__('booking.payment_pending'));
});

test('upcoming section shows payment received badge when payment is received', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->approved()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(2),
        'consultation_type' => ConsultationType::Paid,
        'payment_status' => PaymentStatus::Received,
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(__('booking.payment_received'));
});

test('calendar download button is available for upcoming approved consultations', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->approved()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(2),
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(__('booking.add_to_calendar'));
});

// Pending Section Tests
test('pending section shows consultations with pending status', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->pending()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(5),
        'problem_summary' => 'This is my pending consultation request',
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee('This is my pending consultation')
        ->assertSee(__('booking.pending_review'));
});

test('pending section shows submission date', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->pending()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(5),
        'created_at' => now(),
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(__('booking.submitted_on'));
});

test('pending section truncates long problem summary', function () {
    $user = User::factory()->individual()->create();

    $longSummary = str_repeat('This is a very long problem summary. ', 20);
    Consultation::factory()->pending()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(5),
        'problem_summary' => $longSummary,
    ]);

    $this->actingAs($user);

    // The summary should be truncated (not show full text)
    Volt::test('client.consultations.index')
        ->assertDontSee($longSummary);
});

// Past Section Tests
test('past section shows completed consultations', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->completed()->create([
        'user_id' => $user->id,
        'booking_date' => today()->subDays(5),
        'booking_time' => '14:00:00',
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee('2:00 PM');
});

test('past section shows cancelled consultations', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->cancelled()->create([
        'user_id' => $user->id,
        'booking_date' => today()->subDays(3),
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(ConsultationStatus::Cancelled->label());
});

test('past section shows no-show consultations', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->noShow()->create([
        'user_id' => $user->id,
        'booking_date' => today()->subDays(3),
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(ConsultationStatus::NoShow->label());
});

test('past section shows approved consultations with past date', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->approved()->create([
        'user_id' => $user->id,
        'booking_date' => today()->subDays(2),
        'booking_time' => '16:00:00',
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee('4:00 PM');
});

test('past section is sorted by date descending', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->completed()->create([
        'user_id' => $user->id,
        'booking_date' => today()->subDays(10),
        'booking_time' => '09:00:00',
    ]);
    Consultation::factory()->completed()->create([
        'user_id' => $user->id,
        'booking_date' => today()->subDays(2),
        'booking_time' => '15:00:00',
    ]);

    $this->actingAs($user);

    $component = Volt::test('client.consultations.index');
    $html = $component->html();

    // The more recent date should appear first in past section
    $pos1 = strpos($html, '3:00 PM');
    $pos2 = strpos($html, '9:00 AM');

    expect($pos1)->toBeLessThan($pos2);
});

test('past section paginates correctly', function () {
    $user = User::factory()->individual()->create();

    // Create 15 completed consultations with unique times for identification
    for ($i = 1; $i <= 15; $i++) {
        Consultation::factory()->completed()->create([
            'user_id' => $user->id,
            'booking_date' => today()->subDays($i),
            'booking_time' => sprintf('%02d:00:00', $i),
        ]);
    }

    $this->actingAs($user);

    // First page should show 10 items, ordered by booking_date desc
    // So items with booking_date subDays(1) through subDays(10) should appear
    // Items with subDays(11) through subDays(15) should NOT appear on first page
    $component = Volt::test('client.consultations.index');

    // The 11th, 12th, 13th, 14th, 15th items (oldest) should NOT be on the first page
    // booking_time 11:00, 12:00, 13:00, 14:00, 15:00 correspond to the oldest items
    $component->assertDontSee('11:00 AM')
        ->assertDontSee('12:00 PM')
        ->assertDontSee('1:00 PM')
        ->assertDontSee('2:00 PM')
        ->assertDontSee('3:00 PM');
});

// Empty States Tests
test('empty upcoming shows appropriate message with link to book', function () {
    $user = User::factory()->individual()->create();

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(__('booking.no_upcoming_consultations'))
        ->assertSee(__('booking.book_consultation'));
});

test('empty pending shows appropriate message', function () {
    $user = User::factory()->individual()->create();

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(__('booking.no_pending_requests'));
});

test('empty past shows appropriate message', function () {
    $user = User::factory()->individual()->create();

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(__('booking.no_past_consultations'));
});

// Read-only Tests
test('consultations page is read only with no edit capabilities', function () {
    $user = User::factory()->individual()->create();

    Consultation::factory()->approved()->create([
        'user_id' => $user->id,
        'booking_date' => today()->addDays(3),
    ]);

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertDontSee('Edit')
        ->assertDontSee('Cancel')
        ->assertDontSee('Delete');
});

// Section Heading Tests
test('page displays all section headings', function () {
    $user = User::factory()->individual()->create();

    $this->actingAs($user);

    Volt::test('client.consultations.index')
        ->assertSee(__('booking.my_consultations'))
        ->assertSee(__('booking.upcoming_consultations'))
        ->assertSee(__('booking.pending_requests'))
        ->assertSee(__('booking.past_consultations'));
});

// Company Client Tests
test('company client can view consultations page', function () {
    $user = User::factory()->company()->create();

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