<?php

use App\Enums\ConsultationStatus;
use App\Enums\PostStatus;
use App\Enums\TimelineStatus;
use App\Enums\UserStatus;
use App\Enums\UserType;
use App\Models\AdminLog;
use App\Models\BlockedTime;
use App\Models\Consultation;
use App\Models\Notification;
use App\Models\Post;
use App\Models\Timeline;
use App\Models\TimelineUpdate;
use App\Models\User;
use App\Models\WorkingHour;

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

    expect($user)->toBeInstanceOf(User::class)
        ->and($user->user_type)->toBeInstanceOf(UserType::class)
        ->and($user->status)->toBeInstanceOf(UserStatus::class)
        ->and($user->full_name)->toBeString()
        ->and($user->email)->toBeString()
        ->and($user->phone)->toBeString();
});

test('user factory admin state creates admin user', function () {
    $user = User::factory()->admin()->create();

    expect($user->user_type)->toBe(UserType::Admin);
});

test('user factory individual state creates individual user', function () {
    $user = User::factory()->individual()->create();

    expect($user->user_type)->toBe(UserType::Individual);
});

test('user factory company state creates company user', function () {
    $user = User::factory()->company()->create();

    expect($user->user_type)->toBe(UserType::Company)
        ->and($user->company_name)->toBeString()
        ->and($user->company_cert_number)->toBeString();
});

test('consultation factory creates valid consultation', function () {
    $consultation = Consultation::factory()->create();

    expect($consultation)->toBeInstanceOf(Consultation::class)
        ->and($consultation->user)->toBeInstanceOf(User::class)
        ->and($consultation->status)->toBeInstanceOf(ConsultationStatus::class)
        ->and($consultation->booking_date)->toBeInstanceOf(\Illuminate\Support\Carbon::class);
});

test('timeline factory creates valid timeline', function () {
    $timeline = Timeline::factory()->create();

    expect($timeline)->toBeInstanceOf(Timeline::class)
        ->and($timeline->user)->toBeInstanceOf(User::class)
        ->and($timeline->status)->toBeInstanceOf(TimelineStatus::class)
        ->and($timeline->case_name)->toBeString();
});

test('timeline update factory creates valid timeline update', function () {
    $update = TimelineUpdate::factory()->create();

    expect($update)->toBeInstanceOf(TimelineUpdate::class)
        ->and($update->timeline)->toBeInstanceOf(Timeline::class)
        ->and($update->admin)->toBeInstanceOf(User::class)
        ->and($update->update_text)->toBeString();
});

test('post factory creates valid post', function () {
    $post = Post::factory()->create();

    expect($post)->toBeInstanceOf(Post::class)
        ->and($post->status)->toBeInstanceOf(PostStatus::class)
        ->and($post->title)->toBeArray()
        ->and($post->body)->toBeArray()
        ->and($post->title)->toHaveKeys(['ar', 'en'])
        ->and($post->body)->toHaveKeys(['ar', 'en']);
});

test('working hour factory creates valid working hour', function () {
    $workingHour = WorkingHour::factory()->create();

    expect($workingHour)->toBeInstanceOf(WorkingHour::class)
        ->and($workingHour->day_of_week)->toBeInt()
        ->and($workingHour->day_of_week)->toBeBetween(0, 6)
        ->and($workingHour->is_active)->toBeBool();
});

test('blocked time factory creates valid blocked time', function () {
    $blockedTime = BlockedTime::factory()->create();

    expect($blockedTime)->toBeInstanceOf(BlockedTime::class)
        ->and($blockedTime->block_date)->toBeInstanceOf(\Illuminate\Support\Carbon::class);
});

test('notification factory creates valid notification', function () {
    $notification = Notification::factory()->create();

    expect($notification)->toBeInstanceOf(Notification::class)
        ->and($notification->user)->toBeInstanceOf(User::class)
        ->and($notification->type)->toBeString()
        ->and($notification->data)->toBeArray();
});

test('admin log factory creates valid admin log', function () {
    $log = AdminLog::factory()->create();

    expect($log)->toBeInstanceOf(AdminLog::class)
        ->and($log->admin)->toBeInstanceOf(User::class)
        ->and($log->action)->toBeString()
        ->and($log->ip_address)->toBeString();
});
