<?php

namespace Tests\Feature\V3\RoadItemsProject;

use App\Models\City;
use App\Models\CMMSMachine;
use App\Models\EdarateShahri;
use App\Models\InfoItem;
use App\Models\LogList;
use App\Models\Permission;
use App\Models\Province;
use App\Models\Rahdaran;
use App\Models\RoadItemsProject;
use App\Models\User;
use App\Models\UserActivityLog;
use App\Services\NominatimService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Mockery\MockInterface;
use Tests\TestCase;

class UpdateTest extends TestCase
{
    use RefreshDatabase, WithFaker;

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

        $road_item = RoadItemsProject::factory()->create([
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route("v3.road_items.update", [$road_item->id]));

        $response->assertForbidden();
    }

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

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 3
        ]);

        $response = $this->actingAs($user)->postJson(route("v3.road_items.update", [$road_item->id]));

        $response->assertForbidden();
    }

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

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route("v3.road_items.update", [$road_item->id]));

        $response->assertUnprocessable()
            ->assertInvalid([
                'start_point' => __('validation.required', ['attribute' => 'start point'])
            ]);
    }

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

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]));

        $response->assertUnprocessable()
            ->assertInvalid([
                'amount' => __('validation.required', ['attribute' => 'amount'])
            ]);
    }

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

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]), [
            'amount' => $this->faker->name
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'amount' => __('validation.numeric', ['attribute' => 'amount'])
            ]);
    }

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

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]), [
            'before_image' => $this->faker->name
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'before_image' => __('validation.image', ['attribute' => 'before image'])
            ]);
    }

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

        $image = UploadedFile::fake()->create('image.jpg', 5096);
        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]), [
            'before_image' => $image
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'before_image' => __('validation.max.file', ['attribute' => 'before image', 'max' => 4096])
            ]);
    }

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

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]), [
            'after_image' => $this->faker->randomNumber()
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'after_image' => __('validation.image', ['attribute' => 'after image'])
            ]);
    }

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

        $image = UploadedFile::fake()->create('image.jpg', 5096);
        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]), [
            'after_image' => $image
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'after_image' => __('validation.max.file', ['attribute' => 'after image', 'max' => 4096])
            ]);
    }

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

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]));

        $response->assertUnprocessable()
            ->assertInvalid([
                'cmms_machine_id' => __('validation.required', ['attribute' => 'کد یکتا ماشین'])
            ]);
    }

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

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]), [
            'cmms_machine_id' => $this->faker->numberBetween(10, 100)
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'cmms_machine_id' => __('validation.exists', ['attribute' => 'کد یکتا ماشین'])
            ]);
    }

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

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]));

        $response->assertUnprocessable()
            ->assertInvalid([
                'rahdar_id' => __('validation.required', ['attribute' => 'rahdar id'])
            ]);
    }

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

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]), [
            'rahdar_id' => $this->faker->numberBetween(10, 100)
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'rahdar_id' => __('validation.exists', ['attribute' => 'rahdar id'])
            ]);
    }

    public function test_can_update_the_road_item_project(): void
    {
        $cmmsMachine = CMMSMachine::factory()->create();
        $rahdar = Rahdaran::factory()->create();

        LogList::factory()->create([
            'log_unique_code' => 1155
        ]);
        UserActivityLog::factory()->create();

        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'create-road-item'
            ]))
            ->create();

        $road_item = RoadItemsProject::factory()->create([
            'user_id' => $user->id,
            'status' => 2,
            'item' => $this->faker->numberBetween(1, 10),
            'sub_item' => $this->faker->numberBetween(1, 10),
        ]);

        Storage::fake('public');

        $data = [
            'start_point' => '12,12',
            'amount' => $this->faker->numberBetween(1, 10),
            'cmms_machine_id' => $cmmsMachine->id,
            'rahdar_id' => $rahdar->id,
        ];

        $infoItem = InfoItem::factory()->create([
            'item' => $road_item ->item,
            'sub_item' => $road_item ->sub_item,
        ]);

        $response = $this->actingAs($user)->postJson(route('v3.road_items.update', [$road_item->id]), $data);

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

        $this->assertDatabaseHas('road_items_projects', [
            'start_lat' => 12,
            'start_lng' => 12,
            'cmms_machine_id' => $cmmsMachine->id,
            'cmms_machine_code' => $cmmsMachine->machine_code,
            'rahdar_id' => $rahdar->id,
            'rahdar_code' => $rahdar->code
        ]);

        $this->assertDatabaseHas('user_activity_logs', [
            'user_id' => $user->id,
            'username' => $user->username,
            'log_unique_code' => 1155,
        ]);
    }
}
