<?php

namespace Tests\Tenant;

use Mtc\MercuryDataModels\ContentElement;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Form;
use Mtc\MercuryDataModels\Franchise;
use Mtc\MercuryDataModels\Label;
use Mtc\MercuryDataModels\Page;
use Mtc\MercuryDataModels\PropertyCategory;
use Mtc\MercuryDataModels\Template;
use Mtc\MercuryDataModels\Setting;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleOffer;
use App\Models\ImportMap;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class OptionListTest extends TenantTestCase
{
    use UserForTenant;


    public function testDealerships()
    {
        $model = Dealership::factory()->create(['name' => 'foo']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'dealerships'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testFranchises()
    {
        $model = Franchise::factory()->create(['name' => 'foo']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'franchises'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testMakes()
    {
        VehicleMake::query()->delete();

        $model = VehicleMake::factory()->create(['name' => 'foo']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'makes'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testPages()
    {
        Page::query()->delete();

        $model = Page::factory()->create(['title' => 'foo', 'status' => 'published']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'pages'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testTemplates()
    {
        Template::query()->delete();

        $model = Template::factory()->create(['name' => 'foo', 'status' => 'published']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'templates'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testElements()
    {
        ContentElement::query()->delete();

        $model = ContentElement::factory()->create(['title' => 'foo']);
        $model2 = ContentElement::factory()->create(['title' => 'foo', 'category' => 'baz']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'elements'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testForms()
    {
        Form::query()->delete();

        $model = Form::factory()->create(['name' => 'foo', 'is_active' => true]);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'forms'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testBlogPages()
    {
        $model = Page::factory()->create(['title' => 'foo', 'category' => 'blog']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'blog-pages'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testNewsPages()
    {
        $model = Page::factory()->create(['title' => 'foo', 'category' => 'news']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'news-pages'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testOffers()
    {
        $model = VehicleOffer::factory()->create(['name' => 'foo']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'offers'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testVehicles()
    {
        $model = Vehicle::factory()->create();
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'vehicles'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
    }
    public function testTaxonomies()
    {
        $model = PropertyCategory::factory()->create(['name' => 'foo', 'active' => 1]);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'taxonomies'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }
    public function testLabels()
    {
        Label::query()->delete();

        $model = Label::factory()->create(['name' => 'foo']);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'labels'));
        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertArrayHasKey('id', $response->json('0'));
        $this->assertArrayHasKey('name', $response->json('0'));
        $this->assertEquals($model->id, $response->json('0.id'));
        $this->assertEquals('foo', $response->json('0.name'));
    }

    public function testStockProviders()
    {
        Vehicle::query()->delete();

        $importMap = ImportMap::factory()->create(['name' => 'My CSV Feed']);

        Vehicle::factory()->create(['stock_provider' => 'auto-trader']);
        Vehicle::factory()->create(['stock_provider' => 'import-map-' . $importMap->id]);
        Vehicle::factory()->create(['stock_provider' => 'unknown-provider']);
        Vehicle::factory()->create(['stock_provider' => '']);
        Vehicle::factory()->create(['stock_provider' => null]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'stock-providers'));

        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertCount(4, $response->json());

        $this->assertEquals('default', $response->json('0.value'));
        $this->assertEquals('Default (no stock provider)', $response->json('0.name'));

        $providers = collect($response->json())->keyBy('value');

        $this->assertEquals('AutoTrader', $providers->get('auto-trader')['name']);

        $importMapValue = 'import-map-' . $importMap->id;
        $this->assertEquals('My CSV Feed', $providers->get($importMapValue)['name']);

        $this->assertEquals('unknown-provider', $providers->get('unknown-provider')['name']);
    }

    public function testStockProvidersEmptyForListingSite()
    {
        tenant()->type = 'listing';

        Vehicle::factory()->create(['stock_provider' => 'auto-trader']);
        Vehicle::factory()->create(['stock_provider' => 'unknown-provider']);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'stock-providers'));

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

    public function testSortOptions()
    {
        Setting::query()->where('config_key', 'like', 'automotive-vehicle-sorting-%')->delete();

        Setting::query()->create([
            'tab' => 'Automotive',
            'section' => 'Filter',
            'group' => 'Sorting',
            'name' => 'New Additions',
            'config_key' => 'automotive-vehicle-sorting-latest',
            'type' => 'boolean',
            'value' => true,
            'order' => 1,
        ]);
        Setting::query()->create([
            'tab' => 'Automotive',
            'section' => 'Filter',
            'group' => 'Sorting',
            'name' => 'Price (High > Low)',
            'config_key' => 'automotive-vehicle-sorting-price-desc',
            'type' => 'boolean',
            'value' => true,
            'order' => 2,
        ]);
        Setting::query()->create([
            'tab' => 'Automotive',
            'section' => 'Filter',
            'group' => 'Sorting',
            'name' => 'Mileage (Low > High)',
            'config_key' => 'automotive-vehicle-sorting-mileage-asc',
            'type' => 'boolean',
            'value' => false,
            'order' => 3,
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'sort-options'));

        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertCount(3, $response->json());

        $values = collect($response->json())->pluck('value')->toArray();
        $this->assertContains('latest', $values);
        $this->assertContains('price-desc', $values);
        $this->assertContains('mileage-asc', $values);
    }

    public function testEnabledVehicleTypes()
    {
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.data-list', 'enabled-vehicle-types'));

        $response->assertStatus(200);
        $this->assertIsArray($response->json());
        $this->assertCount(2, $response->json());

        $types = collect($response->json())->keyBy('value');
        $this->assertEquals('Car', $types->get('car')['name']);
        $this->assertEquals('LCV', $types->get('lcv')['name']);
    }
}
