<?php

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

test('consultation has correct consultation type cast', function () {
    $consultation = Consultation::factory()->create(['consultation_type' => 'free']);

    expect($consultation->consultation_type)->toBeInstanceOf(ConsultationType::class)
        ->and($consultation->consultation_type)->toBe(ConsultationType::Free);
});

test('consultation has correct status cast', function () {
    $consultation = Consultation::factory()->create(['status' => 'pending']);

    expect($consultation->status)->toBeInstanceOf(ConsultationStatus::class)
        ->and($consultation->status)->toBe(ConsultationStatus::Pending);
});

test('consultation has correct payment status cast', function () {
    $consultation = Consultation::factory()->create(['payment_status' => 'na']);

    expect($consultation->payment_status)->toBeInstanceOf(PaymentStatus::class)
        ->and($consultation->payment_status)->toBe(PaymentStatus::NotApplicable);
});

test('consultation belongs to user', function () {
    $user = User::factory()->create();
    $consultation = Consultation::factory()->create(['user_id' => $user->id]);

    expect($consultation->user)->toBeInstanceOf(User::class)
        ->and($consultation->user->id)->toBe($user->id);
});

test('consultation has booking date cast as date', function () {
    $consultation = Consultation::factory()->create();

    expect($consultation->booking_date)->toBeInstanceOf(\Illuminate\Support\Carbon::class);
});

test('consultation can be created as guest', function () {
    $consultation = Consultation::factory()->guest()->create();

    expect($consultation->isGuest())->toBeTrue();
    expect($consultation->user_id)->toBeNull();
    expect($consultation->guest_name)->not->toBeNull();
    expect($consultation->guest_email)->not->toBeNull();
    expect($consultation->guest_phone)->not->toBeNull();
});

test('consultation can be created for client', function () {
    $user = User::factory()->client()->create();
    $consultation = Consultation::factory()->create(['user_id' => $user->id]);

    expect($consultation->isGuest())->toBeFalse();
    expect($consultation->user_id)->toBe($user->id);
});

test('getClientName returns guest name for guest consultation', function () {
    $consultation = Consultation::factory()->guest()->create([
        'guest_name' => 'John Doe',
    ]);

    expect($consultation->getClientName())->toBe('John Doe');
});

test('getClientName returns user name for client consultation', function () {
    $user = User::factory()->client()->create(['full_name' => 'Jane Smith']);
    $consultation = Consultation::factory()->create(['user_id' => $user->id]);

    expect($consultation->getClientName())->toBe('Jane Smith');
});

test('getClientEmail returns guest email for guest consultation', function () {
    $consultation = Consultation::factory()->guest()->create([
        'guest_email' => 'guest@example.com',
    ]);

    expect($consultation->getClientEmail())->toBe('guest@example.com');
});

test('getClientEmail returns user email for client consultation', function () {
    $user = User::factory()->client()->create(['email' => 'user@example.com']);
    $consultation = Consultation::factory()->create(['user_id' => $user->id]);

    expect($consultation->getClientEmail())->toBe('user@example.com');
});

test('getClientPhone returns guest phone for guest consultation', function () {
    $consultation = Consultation::factory()->guest()->create([
        'guest_phone' => '+1234567890',
    ]);

    expect($consultation->getClientPhone())->toBe('+1234567890');
});

test('getClientPhone returns user phone for client consultation', function () {
    $user = User::factory()->client()->create(['phone' => '+0987654321']);
    $consultation = Consultation::factory()->create(['user_id' => $user->id]);

    expect($consultation->getClientPhone())->toBe('+0987654321');
});

test('existing consultations with user are not affected', function () {
    $user = User::factory()->client()->create();
    $consultation = Consultation::factory()->create(['user_id' => $user->id]);

    expect($consultation->user)->toBeInstanceOf(User::class);
    expect($consultation->isGuest())->toBeFalse();
});

test('guest consultation throws exception without required fields', function () {
    expect(fn () => Consultation::factory()->create([
        'user_id' => null,
        'guest_name' => null,
        'guest_email' => null,
        'guest_phone' => null,
    ]))->toThrow(\InvalidArgumentException::class);
});

test('guests scope returns only guest consultations', function () {
    Consultation::factory()->guest()->count(3)->create();
    Consultation::factory()->count(2)->create();

    expect(Consultation::guests()->count())->toBe(3);
});

test('clients scope returns only client consultations', function () {
    Consultation::factory()->guest()->count(3)->create();
    Consultation::factory()->count(2)->create();

    expect(Consultation::clients()->count())->toBe(2);
});
