<?php

namespace Tests\Tenant;

use App\Filter\FilterIndex;
use App\Jobs\AssignFilterFeatures;
use Mtc\MercuryDataModels\FilterFeature;
use Mtc\MercuryDataModels\VehicleStandardEquipment;
use Tests\TenantTestCase;

class AssignFilterFeaturesTest extends TenantTestCase
{
    public function testSingleFeature()
    {
        $feature = FilterFeature::factory()->create(['terms' => ['blue', 'white', 'green']]);

        VehicleStandardEquipment::factory(5)->create();
        $blue = VehicleStandardEquipment::factory()->create(['description' => 'blue', 'feature_id' => null]);
        $bluefer = VehicleStandardEquipment::factory()->create(['description' => 'bluefer', 'feature_id' => null]);
        $white = VehicleStandardEquipment::factory()->create(['description' => 'baz white', 'feature_id' => null]);
        $green = VehicleStandardEquipment::factory()->create(['description' => 'bazgreen', 'feature_id' => null]);

        new AssignFilterFeatures($feature)->handle();

        $this->assertEquals($feature->id, $blue->refresh()->feature_id);
        $this->assertEquals($feature->id, $bluefer->refresh()->feature_id);
        $this->assertEquals($feature->id, $white->refresh()->feature_id);
        $this->assertEquals($feature->id, $green->refresh()->feature_id);
        $this->assertEquals(4, VehicleStandardEquipment::query()->where('feature_id', $feature->id)->count());

    }

    public function testAllFeatures()
    {
        $feature = FilterFeature::factory()->create(['terms' => ['blue', 'green']]);
        $feature2 = FilterFeature::factory()->create(['terms' => ['white']]);

        VehicleStandardEquipment::factory(5)->create(['feature_id' => null]);
        $blue = VehicleStandardEquipment::factory()->create(['description' => 'blue', 'feature_id' => null]);
        $bluefer = VehicleStandardEquipment::factory()->create(['description' => 'bluefer', 'feature_id' => null]);
        $white = VehicleStandardEquipment::factory()->create(['description' => 'baz white', 'feature_id' => null]);
        $green = VehicleStandardEquipment::factory()->create(['description' => 'bazgreen', 'feature_id' => null]);

        new AssignFilterFeatures()->handle();

        $this->assertEquals($feature->id, $blue->refresh()->feature_id);
        $this->assertEquals($feature->id, $bluefer->refresh()->feature_id);
        $this->assertEquals($feature2->id, $white->refresh()->feature_id);
        $this->assertEquals($feature->id, $green->refresh()->feature_id);
        $this->assertEquals(3, VehicleStandardEquipment::query()->where('feature_id', $feature->id)->count());
        $this->assertEquals(1, VehicleStandardEquipment::query()->where('feature_id', $feature2->id)->count());
    }

    public function testLeatherFree()
    {
        $feature = FilterFeature::factory()->create(['terms' => ['leather']]);
        VehicleStandardEquipment::factory()->create(['description' => 'leather-free', 'feature_id' => null]);

        new AssignFilterFeatures()->handle();

        $this->assertEquals(0, VehicleStandardEquipment::query()->where('feature_id', $feature->id)->count());
    }

    public function testExactMatchOnlyMatchesFullDescription()
    {
        $feature = FilterFeature::factory()->create([
            'terms' => ['leather'],
            'exact_match' => true,
        ]);

        $exact = VehicleStandardEquipment::factory()->create(['description' => 'leather', 'feature_id' => null]);
        $partial = VehicleStandardEquipment::factory()->create(['description' => 'leather seats', 'feature_id' => null]);
        $substring = VehicleStandardEquipment::factory()->create(['description' => 'full leather upholstery', 'feature_id' => null]);

        new AssignFilterFeatures($feature)->handle();

        $this->assertEquals($feature->id, $exact->refresh()->feature_id);
        $this->assertNull($partial->refresh()->feature_id);
        $this->assertNull($substring->refresh()->feature_id);
    }

    public function testExactMatchDoesNotRequireLeatherFreeExclusion()
    {
        $feature = FilterFeature::factory()->create([
            'terms' => ['leather'],
            'exact_match' => true,
        ]);

        $leatherFree = VehicleStandardEquipment::factory()->create(['description' => 'leather-free', 'feature_id' => null]);

        new AssignFilterFeatures($feature)->handle();

        $this->assertNull($leatherFree->refresh()->feature_id);
    }

    public function testFuzzyMatchStillWorksWhenExactMatchIsFalse()
    {
        $feature = FilterFeature::factory()->create([
            'terms' => ['leather'],
            'exact_match' => false,
        ]);

        $exact = VehicleStandardEquipment::factory()->create(['description' => 'leather', 'feature_id' => null]);
        $partial = VehicleStandardEquipment::factory()->create(['description' => 'leather seats', 'feature_id' => null]);

        new AssignFilterFeatures($feature)->handle();

        $this->assertEquals($feature->id, $exact->refresh()->feature_id);
        $this->assertEquals($feature->id, $partial->refresh()->feature_id);
    }

    public function testFilterIndexRefresh()
    {
        $feature = FilterFeature::factory()->create([
            'slug' => 'blue',
            'terms' => ['blue', 'white', 'green'],
            'name' => 'foo',
        ]);

        $filter_index = FilterIndex::query()->create([
            'filter_type' => 'features',
            'filter_id' => $feature->id,
            'slug' => 'blue',
            'name' => 'bar',
        ]);

        (new AssignFilterFeatures($feature))->handle();

        $this->assertEquals('foo', $filter_index->refresh()->name);
    }
}
