<?php

namespace Tests\Tenant;

use App\Facades\Feature;
use Illuminate\Support\Facades\Queue;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Franchise;
use Mtc\MercuryDataModels\Media;
use Mtc\MercuryDataModels\MediaUse;
use Mtc\MercuryDataModels\OfferType;
use Mtc\MercuryDataModels\Page;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Mtc\MercuryDataModels\VehicleOffer;
use Tests\TenantTestCase;

class FranchiseDataTest extends TenantTestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        Queue::fake();
    }

    public function testFranchiseData()
    {
        Feature::setEnabled(tenant(), ['franchises']);
        tenant()->update(['tier' => 'pro']);

        $make = VehicleMake::factory()->create(['slug' => 'foo']);
        $franchise = Franchise::factory()->create([
            'name' => 'foo',
            'slug' => 'baz',
            'make_id' => $make->id,
        ]);

        $page = Page::factory()->create([
            'status' => 'published',
            'franchise_id' => $franchise->id,
        ]);
        $response = $this
            ->getJson(route('pages.show', $page->slug));

        $response->assertStatus(200);
        $this->assertTrue($response->json('isFranchise'));
        $this->assertEquals($make->id, $response->json('franchise.make_id'));
        $this->assertEquals('foo', $response->json('franchise.make_slug'));
    }

    public function testDealershipFranchise()
    {
        $franchise = Franchise::factory()->create([
            'name' => 'foo'
        ]);

        $dealership = Dealership::factory()->create([
            'franchise_id' => $franchise->id
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealership->id
        ]);

        $this->assertEquals($franchise->name, $vehicle->dealership->franchise->name);
    }

    public function testGetFranchiseEnpoint()
    {
        tenant()->update(['tier' => 'pro']);
        $franchise = Franchise::factory()->create([
            'name' => 'foo',
            'slug' => 'baz'
        ]);

        $response = $this
            ->getJson(route('franchises.show', $franchise->slug));

        $response->assertStatus(200);
        $this->assertArrayHasKey('name', $response->json());
        $this->assertArrayHasKey('slug', $response->json());
        $this->assertArrayHasKey('logo', $response->json());
        $this->assertArrayHasKey('primary_colour', $response->json());
        $this->assertArrayHasKey('secondary_colour', $response->json());
        $this->assertArrayHasKey('menus', $response->json());
    }

    public function testGetFranchiseOffersEndpoint()
    {
        tenant()->update(['tier' => 'pro']);
        $make = VehicleMake::factory()->create();
        $model = VehicleModel::factory()->create(['make_id' => $make->id]);
        $franchise = Franchise::factory()->create([
            'name' => 'foo',
            'slug' => 'baz',
            'make_id' => $make->id,
        ]);

        $type = OfferType::factory()->create();
        VehicleOffer::factory(5)->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'featured' => 0,
            'type_id' => $type->id,
        ]);
        VehicleOffer::factory(5)->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'featured' => 1,
            'type_id' => $type->id,
        ]);

        $response = $this
            ->getJson(route('franchises.offers', $franchise->slug));

        $response->assertStatus(200);
        $this->assertArrayHasKey('featured', $response->json());
        $this->assertArrayHasKey('models', $response->json());
        $this->assertArrayHasKey($model->slug, $response->json('models'));
        $this->assertCount(5, $response->json('featured'));
        $this->assertArrayHasKey('slug', $response->json('featured.0'));
        $this->assertArrayHasKey('name', $response->json('featured.0'));
    }

    public function testSiteFranchiseData()
    {
        Feature::setEnabled(tenant(), ['franchises']);
        $make = VehicleMake::factory()->create(['slug' => 'foo']);

        $franchise = Franchise::factory()->create([
            'name' => 'foo',
            'slug' => 'baz',
            'make_id' => $make->id,
            'primary_colour' => 'red',
            'secondary_colour' => 'blue',
        ]);

        $media_item = Media::factory()->create();
        MediaUse::factory()->create([
            'media_id' => $media_item->id,
            'owner_type' => 'franchise',
            'owner_id' => $franchise->id,
            'primary' => true,
        ]);

        $response = $this
            ->getJson(route('get-site'));

        $response->assertStatus(200);
        $this->assertArrayHasKey('franchises', $response->json());

        $this->assertArrayHasKey('id', $response->json('franchises.0'));
        $this->assertArrayHasKey('name', $response->json('franchises.0'));
        $this->assertArrayHasKey('slug', $response->json('franchises.0'));
        $this->assertArrayHasKey('make_id', $response->json('franchises.0'));
        $this->assertArrayHasKey('make_slug', $response->json('franchises.0'));
        $this->assertArrayHasKey('menus', $response->json('franchises.0'));
        $this->assertArrayHasKey('primary_colour', $response->json('franchises.0'));
        $this->assertArrayHasKey('secondary_colour', $response->json('franchises.0'));

        $this->assertEquals($franchise->id, $response->json('franchises.0.id'));
        $this->assertEquals($franchise->name, $response->json('franchises.0.name'));
        $this->assertEquals($franchise->slug, $response->json('franchises.0.slug'));
        $this->assertEquals($make->id, $response->json('franchises.0.make_id'));
        $this->assertEquals($make->slug, $response->json('franchises.0.make_slug'));
        $this->assertEquals([], $response->json('franchises.0.menus'));
        $this->assertEquals($franchise->primary_colour, $response->json('franchises.0.primary_colour'));
        $this->assertEquals($franchise->secondary_colour, $response->json('franchises.0.secondary_colour'));
        $this->assertNotEmpty($response->json('franchises.0.logo'));
    }

    public function testSiteFranchiseFaviconWhenFeatureEnabled()
    {
        Feature::setEnabled(tenant(), ['franchises', 'franchise-specific-favicons']);
        tenant()->update(['tier' => 'pro']);

        $path = tenant('id') . '/assets/favicon.ico';
        Franchise::factory()->create([
            'name' => 'foo',
            'slug' => 'baz',
            'favicon' => $path,
        ]);

        $response = $this->getJson(route('get-site'));

        $response->assertStatus(200);
        $this->assertEquals($path, $response->json('franchises.0.favicon.path'));
        $this->assertNotEmpty($response->json('franchises.0.favicon.url'));
    }

    public function testSiteFranchiseFaviconIsNullWhenFeatureDisabled()
    {
        Feature::setEnabled(tenant(), ['franchises']);
        tenant()->update(['tier' => 'pro']);

        Franchise::factory()->create([
            'name' => 'foo',
            'slug' => 'baz',
            'favicon' => tenant('id') . '/assets/favicon.ico',
        ]);

        $response = $this->getJson(route('get-site'));

        $response->assertStatus(200);
        $this->assertNull($response->json('franchises.0.favicon'));
    }
}
