<?php

namespace Tests\Tenant;

use Mtc\MercuryDataModels\BodyStyleType;
use Mtc\MercuryDataModels\DrivetrainType;
use Mtc\MercuryDataModels\FuelType;
use Mtc\MercuryDataModels\TransmissionType;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class VehicleTaxonomyControllerTest extends TenantTestCase
{
    use UserForTenant;

    public function testMakeIndex()
    {
        VehicleMake::query()->delete();

        VehicleMake::factory(15)->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/makes');


        $response->assertStatus(200);
        $this->assertCount(15, $response->json('data'));
    }

    public function testMakeShow()
    {
        $model = VehicleMake::factory()->create(['name' => 'BMW']);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/makes/' . $model->id);

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

    public function testModelsIndex()
    {
        $make = VehicleMake::factory()->create();
        VehicleModel::factory(14)->create(['make_id' => $make->id]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/makes/' . $make->id . '/models');

        $response->assertStatus(200);
        $this->assertCount(14, $response->json('data'));
    }

    public function testModelsIndexCampervanTypeReturnsMotorhomeModels()
    {
        $make = VehicleMake::factory()->create();

        VehicleModel::factory()->create([
            'make_id' => $make->id,
            'name' => 'California',
            'type' => 'motorhome',
        ]);
        VehicleModel::factory()->create([
            'make_id' => $make->id,
            'name' => 'Grand California',
            'type' => 'car-motorhome',
        ]);
        VehicleModel::factory()->create([
            'make_id' => $make->id,
            'name' => 'Marco Polo',
            'type' => 'campervan',
        ]);
        VehicleModel::factory()->create([
            'make_id' => $make->id,
            'name' => 'Golf',
            'type' => 'car',
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/makes/' . $make->id . '/models?type=campervan');

        $response->assertStatus(200);
        $names = collect($response->json('data'))->pluck('name')->all();
        $this->assertEqualsCanonicalizing(
            ['California', 'Grand California', 'Marco Polo'],
            $names
        );
    }

    public function testModelsIndexMotorhomeTypeReturnsCampervanModels()
    {
        $make = VehicleMake::factory()->create();

        VehicleModel::factory()->create([
            'make_id' => $make->id,
            'name' => 'California',
            'type' => 'motorhome',
        ]);
        VehicleModel::factory()->create([
            'make_id' => $make->id,
            'name' => 'Grand California',
            'type' => 'car-motorhome',
        ]);
        VehicleModel::factory()->create([
            'make_id' => $make->id,
            'name' => 'Marco Polo',
            'type' => 'campervan',
        ]);
        VehicleModel::factory()->create([
            'make_id' => $make->id,
            'name' => 'Golf',
            'type' => 'car',
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/makes/' . $make->id . '/models?type=motorhome');

        $response->assertStatus(200);
        $names = collect($response->json('data'))->pluck('name')->all();
        $this->assertEqualsCanonicalizing(
            ['California', 'Grand California', 'Marco Polo'],
            $names
        );
    }

    public function testModelsShow()
    {
        $model = VehicleModel::factory()->create(['name' => '3.series']);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/models/' . $model->id);

        $response->assertStatus(200);
        $this->assertEquals('3.series', $response->json('name'));
    }

    public function testDrivetrainIndex()
    {
        DrivetrainType::query()->delete();

        DrivetrainType::factory(13)->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/drivetrains');


        $response->assertStatus(200);
        $this->assertEquals(13, $response->json('total'));
    }

    public function testDrivetrainShow()
    {
        $model = DrivetrainType::factory()->create(['name' => 'foo']);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/drivetrains/' . $model->id);

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

    public function testTransmissionIndex()
    {
        TransmissionType::query()->delete();

        TransmissionType::factory(12)->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/transmissions');

        $response->assertStatus(200);
        $this->assertEquals(12, $response->json('total'));
    }

    public function testTransmissionShow()
    {
        $model = TransmissionType::factory()->create(['name' => 'foo']);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/transmissions/' . $model->id);

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

    public function testFuelTypeIndex()
    {
        FuelType::query()->delete();

        FuelType::factory(11)->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/fuel-types');

        $response->assertStatus(200);
        $this->assertEquals(11, $response->json('total'));
    }

    public function testFuelTypeShow()
    {
        $fuel_type = FuelType::factory()->create(['name' => 'foo']);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/fuel-types/' . $fuel_type->id);

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

    public function testBodyStyleSIndex()
    {
        BodyStyleType::query()->delete();

        BodyStyleType::factory(10)->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/body-styles');

        $response->assertStatus(200);
        $this->assertEquals(10, $response->json('total'));
    }

    public function testBodyStyleShow()
    {
        $body_style = BodyStyleType::factory()->create(['name' => 'foo']);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson('/api/vehicle-taxonomies/body-styles/' . $body_style->id);

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

    public function testUnableToAccessWithoutAuth()
    {
        // Make
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/makes/');
        $response->assertStatus(401);

        $make = VehicleMake::factory()->create(['name' => 'foo']);
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/makes/' . $make->id);
        $response->assertStatus(401);

        // Model
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/makes/' . $make->id . '/models');
        $response->assertStatus(401);

        $model = VehicleModel::factory()->create(['make_id' => $make->id]);
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/models/' . $model->id);
        $response->assertStatus(401);

        // Transmission
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/transmissions/');
        $response->assertStatus(401);

        $model = TransmissionType::factory()->create(['name' => 'foo']);
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/transmissions/' . $model->id);
        $response->assertStatus(401);

        // Drivetrain
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/drivetrains/');
        $response->assertStatus(401);

        $model = DrivetrainType::factory()->create(['name' => 'foo']);
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/drivetrains/' . $model->id);
        $response->assertStatus(401);

        // Fuel Type
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/fuel-types/');
        $response->assertStatus(401);

        $model = FuelType::factory()->create(['name' => 'foo']);
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/fuel-types/' . $model->id);
        $response->assertStatus(401);

        // Body style
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/body-styles/');
        $response->assertStatus(401);

        $body_style = BodyStyleType::factory()->create(['name' => 'foo']);
        $response = $this->withHeaders(['X-Tenant' => tenant('id')])
            ->getJson('/api/vehicle-taxonomies/body-styles/' . $body_style->id);
        $response->assertStatus(401);
    }
}
