<?php

namespace Tests\Feature\V3\AzmayeshType;

use App\Models\AzmayeshSample;
use App\Models\AzmayeshType;
use App\Models\Permission;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class UpdateTest extends TestCase
{
    use RefreshDatabase, WithFaker;
    /**
     * A basic feature test example.
     */
    public function test_user_should_have_azmayesh_management_permission(): void
    {
        $user = User::factory()->create();
        $azmayeshType = AzmayeshType::factory()->create();

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

        $response->assertForbidden();
    }

    public function test_name_attribute_is_required(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

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

        $response->assertUnprocessable()
            ->assertInvalid([
                'name' => __('validation.required', ['attribute' => "نام"])
            ]);
    }

    public function test_name_attribute_should_be_string(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

        $response = $this->actingAs($user)->postJson(route('v3.azmayesh_types.update', [$azmayeshType->id]), [
            'name' => $this->faker->numberBetween(1, 10)
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'name' => __('validation.string', ['attribute' => "نام"])
            ]);
    }

    public function test_fields_attribute_is_required(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

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

        $response->assertUnprocessable()
            ->assertInvalid([
                'fields' => __('validation.required', ['attribute' => 'فیلد ها'])
            ]);
    }

    public function test_fields_attribute_should_be_array(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

        $response = $this->actingAs($user)->postJson(route('v3.azmayesh_types.update', [$azmayeshType->id]), [
            'fields' => $this->faker->numberBetween(1, 10)
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'fields' => __('validation.array', ['attribute' => 'فیلد ها'])
            ]);
    }

    public function test_field_name_is_required(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

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

        $response->assertUnprocessable()
            ->assertInvalid([
                'fields.0.name' => __('validation.required', ['attribute' => 'نام فیلد'])
            ]);
    }

    public function test_field_name_should_be_string(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

        $response = $this->actingAs($user)->postJson(route('v3.azmayesh_types.update', [$azmayeshType->id]), [
            'fields' => [
                ['name' => $this->faker->numberBetween(1, 10)]
            ]
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'fields.0.name' => __('validation.string', ['attribute' => 'نام فیلد'])
            ]);
    }

    public function test_field_unit_should_be_string(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

        $response = $this->actingAs($user)->postJson(route('v3.azmayesh_types.update', [$azmayeshType->id]), [
            'fields' => [
                ['unit' => $this->faker->numberBetween(1, 10)]
            ]
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'fields.0.unit' => __('validation.string', ['attribute' => 'واحد فیلد'])
            ]);
    }

    public function test_field_type_is_required(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

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

        $response->assertUnprocessable()
            ->assertInvalid([
                'fields.0.type' => __('validation.required', ['attribute' => 'نوع فیلد'])
            ]);
    }

    public function test_field_type_should_be_string(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

        $response = $this->actingAs($user)->postJson(route('v3.azmayesh_types.update', [$azmayeshType->id]), [
            'fields' => [
                ['type' => $this->faker->numberBetween(1, 10)]
            ]
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'fields.0.type' => __('validation.string', ['attribute' => 'نوع فیلد'])
            ]);
    }

    public function test_field_option_should_be_string(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

        $response = $this->actingAs($user)->postJson(route('v3.azmayesh_types.update', [$azmayeshType->id]), [
            'fields' => [
                ['option' => $this->faker->numberBetween(1, 10)]
            ]
        ]);

        $response->assertUnprocessable()
            ->assertInvalid([
                'fields.0.option' => __('validation.string', ['attribute' => 'گزینه های فیلد'])
            ]);
    }

    public function test_user_can_update_fields_for_an_azmayesh_type(): void
    {
        $user = User::factory()
            ->has(Permission::factory([
                'name' => 'azmayesh-type-management'
            ]))
            ->create();
        $azmayeshType = AzmayeshType::factory()->create();

        $data = [
            'name' => $this->faker->name,
            'fields' => [
                [
                    'name' => $this->faker->name,
                    'type' => $this->faker->randomElement(['input', 'select', 'date']),
                    'unit' => $this->faker->name,
                    'option' => json_encode(['test']),
                ],
                [
                    'name' => $this->faker->name,
                    'type' => $this->faker->randomElement(['input', 'select', 'date']),
                    'unit' => $this->faker->name,
                ],
            ]
        ];

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

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

        $this->assertDatabaseHas('azmayesh_fields', [
            'name' => $data['fields'][0]['name'],
            'type' => $data['fields'][0]['type'],
            'unit' => $data['fields'][0]['unit'],
        ]);

        $this->assertDatabaseHas('azmayesh_fields', [
            'name' => $data['fields'][1]['name'],
            'type' => $data['fields'][1]['type'],
            'unit' => $data['fields'][1]['unit'],
        ]);

        $this->assertDatabaseHas('azmayesh_types', [
            'name' => $data['name'],
        ]);
    }
}
