<?php

namespace Tests\Tenant\Controllers;

use Mtc\MercuryDataModels\PropertyCategory;
use Mtc\MercuryDataModels\PropertyCategoryField;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class PropertyCategoryControllerTest extends TenantTestCase
{
    use UserForTenant;

    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testIndex()
    {
        PropertyCategory::factory(5)->create();
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.property-categories.index'));

        $response->assertStatus(200);
        $this->assertCount(5, $response->json());
    }

    public function testStore()
    {
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.property-categories.store'), [
                'name' => 'foo',
            ]);

        $response->assertStatus(201);
        $this->assertEquals('foo', $response->json('name'));
        $this->assertTrue(PropertyCategory::query()->where('name', 'foo')->exists());

    }

    public function testShow()
    {
        $category = PropertyCategory::factory()->create([
            'name' => 'foo',
            'active' => true,
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.property-categories.show', $category));

        $response->assertStatus(200);
        $this->assertEquals('foo', $response->json('name'));
        $this->assertTrue($response->json('active'));
    }

    public function testUpdate()
    {
        $category = PropertyCategory::factory()->create([
            'name' => 'foo',
            'active' => false,
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->putJson(route('tenant.property-categories.update', $category), [
                'name' => 'baz',
                'active' => true,
                'fields' => [
                    [
                        'id' => 'abc123',
                        'name' => 'lorem',
                        'field_type' => 'text',
                    ]
                ]
            ]);

        $category->refresh();
        $response->assertStatus(200);
        $this->assertEquals('baz', $response->json('name'));
        $this->assertTrue($response->json('active'));
        $this->assertTrue($category->fields()->where('name', 'lorem')->where('type', 'text')->exists());
    }

    public function testShowReturnsFieldMetaOptions()
    {
        $category = PropertyCategory::factory()->create();
        PropertyCategoryField::factory()->create([
            'category_id' => $category->id,
            'name' => 'Dealership',
            'type' => 'select',
            'data' => [
                'meta' => [
                    'content' => '',
                    'options' => [
                        'source' => 'dealerships',
                        'items' => [['value' => '1', 'name' => 'test1']],
                        'multiSelect' => false,
                        'required' => false,
                    ],
                ],
            ],
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.property-categories.show', $category));

        $response->assertStatus(200);
        $this->assertEquals('dealerships', $response->json('fields.0.meta.options.source'));
        $this->assertEquals('test1', $response->json('fields.0.meta.options.items.0.name'));
    }

    public function testUpdateRoundTripsFieldMetaOptions()
    {
        $category = PropertyCategory::factory()->create(['active' => false]);

        $payload = [
            'name' => 'baz',
            'active' => true,
            'fields' => [
                [
                    'id' => 'abc123',
                    'name' => 'Dealership',
                    'field_type' => 'select',
                    'meta' => [
                        'content' => '',
                        'options' => [
                            'source' => 'dealerships',
                            'items' => [],
                            'multiSelect' => false,
                            'required' => false,
                        ],
                    ],
                ],
            ],
        ];

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->putJson(route('tenant.property-categories.update', $category), $payload);

        $response->assertStatus(200);
        $this->assertEquals('dealerships', $response->json('fields.0.meta.options.source'));

        // Config must survive a subsequent reload (GET) so the Options dialog can restore it.
        $show = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.property-categories.show', $category));

        $show->assertStatus(200);
        $this->assertEquals('dealerships', $show->json('fields.0.meta.options.source'));
    }

    public function testDestroy()
    {
        $category = PropertyCategory::factory()->create();
        $field = PropertyCategoryField::factory()->create(['category_id' => $category->id]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->deleteJson(route('tenant.property-categories.destroy', $category));

        $response->assertStatus(200);
        $this->assertFalse(PropertyCategory::query()->where('id', $category->id)->exists());
        $this->assertFalse(PropertyCategoryField::query()->where('id', $field->id)->exists());
    }
}
