<?php

namespace Tests\Feature\Call;

use App\Models\Event;
use App\Models\User;
use App\Enums\CallEvents;
use App\Services\Notification\NotificationService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Mockery\MockInterface;
use Tests\TestCase;

class StoreTest extends TestCase
{
    use RefreshDatabase, WithFaker;

    public function test_validation_fails_when_required_fields_are_missing(): void
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)->postJson(route('calls.store'));

        $response->assertUnprocessable()
            ->assertInvalid([
                'extension' => __('validation.required', ['attribute' => 'کد تلفن']),
                'caller_id' => __('validation.required', ['attribute' => 'شماره تماس‌گیرنده']),
            ]);
    }

    public function test_extension_must_be_string(): void
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)->postJson(route('calls.store'), [
            'extension' => $this->faker->numberBetween(1000, 9999),
            'caller_id' => $this->faker->randomNumber(),
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'extension' => __('validation.string', ['attribute' => 'کد تلفن']),
            ]);
    }

    public function test_extension_must_exist_in_users_table(): void
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)->postJson(route('calls.store'), [
            'extension' => $this->faker->uuid,
            'caller_id' => $this->faker->randomNumber(),
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'extension' => __('validation.exists', ['attribute' => 'کد تلفن']),
            ]);
    }

    public function test_caller_id_must_be_numeric(): void
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)->postJson(route('calls.store'), [
            'extension' => $user->telephone_id,
            'caller_id' => $this->faker->word(),
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'caller_id' => __('validation.numeric', ['attribute' => 'شماره تماس‌گیرنده']),
            ]);
    }

    public function test_can_create_a_call(): void
    {
        $operator = User::factory()->create([
            'telephone_id' => $this->faker->unique()->numerify('###'),
        ]);

        $this->artisan('db:seed --class=EventSeeder');

        $this->mock(NotificationService::class, function (MockInterface $mock) {
            $mock->shouldReceive('deliverDataToNotificationServer');
        });

        $callerId = $this->faker->numerify('09#########');

        $response = $this->postJson(route('calls.store'), [
            'extension' => $operator->telephone_id,
            'caller_id' => $callerId,
        ]);

        $response->assertStatus(200)
            ->assertExactJson([
                'message' => __('messages.successful'),
            ]);

        $this->assertDatabaseHas('calls', [
            'caller_phone_number' => $callerId,
            'telephone_id' => $operator->telephone_id,
            'operator_id' => $operator->id,
            'operator_username' => $operator->username,
            'operator_full_name' => $operator->full_name,
        ]);

        $event = Event::query()->where('id', CallEvents::CALL_CREATED)->first();

        $this->assertDatabaseHas('call_histories', [
            'event_name' => $event->name,
            'event_id' => $event->id,
            'caller_phone_number' => $callerId,
            'telephone_id' => $operator->telephone_id,
        ]);
    }

}
