<?php

namespace Tests\Feature;

use App\Events\NewVehicleImported;
use App\Events\StockSyncFinished;
use App\Events\VehicleUpdatedFromImport;
use App\Listeners\IndexVehicleInMeilisearch;
use App\Listeners\SyncVehiclesToMeilisearch;
use App\Services\MeilisearchService;
use Mockery\MockInterface;
use Mtc\MercuryDataModels\Vehicle;
use Tests\TenantTestCase;

class MeilisearchListenerTest extends TenantTestCase
{
    /**
     * Test that StockSyncFinished triggers full reindex for batch providers.
     */
    public function testStockSyncFinishedTriggersReindexForBatchProvider(): void
    {
        $this->mock(MeilisearchService::class, function (MockInterface $mock) {
            $mock->shouldReceive('isEnabled')->once()->andReturn(true);
            $mock->shouldReceive('syncAllVehicles')->once();
        });

        $listener = $this->app->make(SyncVehiclesToMeilisearch::class);
        $event = new StockSyncFinished('motordata');

        $listener->handle($event);
    }

    /**
     * Test that StockSyncFinished does NOT trigger reindex for AutoGrab provider.
     */
    public function testStockSyncFinishedSkipsAutograbProvider(): void
    {
        $this->mock(MeilisearchService::class, function (MockInterface $mock) {
            $mock->shouldReceive('isEnabled')->once()->andReturn(true);
            $mock->shouldNotReceive('syncAllVehicles');
        });

        $listener = $this->app->make(SyncVehiclesToMeilisearch::class);
        $event = new StockSyncFinished('autograb');

        $listener->handle($event);
    }

    /**
     * Test that StockSyncFinished does NOT trigger reindex for AutoTrader Hub provider.
     */
    public function testStockSyncFinishedSkipsAutoTraderHubProvider(): void
    {
        $this->mock(MeilisearchService::class, function (MockInterface $mock) {
            $mock->shouldReceive('isEnabled')->once()->andReturn(true);
            $mock->shouldNotReceive('syncAllVehicles');
        });

        $listener = $this->app->make(SyncVehiclesToMeilisearch::class);
        $event = new StockSyncFinished('auto-trader');

        $listener->handle($event);
    }

    /**
     * Test that StockSyncFinished does nothing when Meilisearch is disabled.
     */
    public function testStockSyncFinishedSkipsWhenMeilisearchDisabled(): void
    {
        $this->mock(MeilisearchService::class, function (MockInterface $mock) {
            $mock->shouldReceive('isEnabled')->once()->andReturn(false);
            $mock->shouldNotReceive('syncAllVehicles');
        });

        $listener = $this->app->make(SyncVehiclesToMeilisearch::class);
        $event = new StockSyncFinished('motordata');

        $listener->handle($event);
    }

    /**
     * Test that NewVehicleImported indexes vehicle for AutoGrab provider.
     */
    public function testNewVehicleImportedIndexesForAutograb(): void
    {
        $vehicle = Vehicle::factory()->create();

        $this->mock(MeilisearchService::class, function (MockInterface $mock) use ($vehicle) {
            $mock->shouldReceive('isEnabled')->once()->andReturn(true);
            $mock->shouldReceive('indexVehicle')
                ->once()
                ->with(\Mockery::on(fn ($v) => $v->id === $vehicle->id));
        });

        $listener = $this->app->make(IndexVehicleInMeilisearch::class);
        $event = new NewVehicleImported($vehicle, [], 'autograb');

        $listener->handle($event);
    }

    /**
     * Test that NewVehicleImported indexes vehicle for AutoTrader Hub provider.
     */
    public function testNewVehicleImportedIndexesForAutoTraderHub(): void
    {
        $vehicle = Vehicle::factory()->create();

        $this->mock(MeilisearchService::class, function (MockInterface $mock) use ($vehicle) {
            $mock->shouldReceive('isEnabled')->once()->andReturn(true);
            $mock->shouldReceive('indexVehicle')
                ->once()
                ->with(\Mockery::on(fn ($v) => $v->id === $vehicle->id));
        });

        $listener = $this->app->make(IndexVehicleInMeilisearch::class);
        $event = new NewVehicleImported($vehicle, [], 'auto-trader');

        $listener->handle($event);
    }

    /**
     * Test that NewVehicleImported does NOT index for batch providers.
     */
    public function testNewVehicleImportedSkipsBatchProviders(): void
    {
        $vehicle = Vehicle::factory()->create();

        $this->mock(MeilisearchService::class, function (MockInterface $mock) {
            $mock->shouldReceive('isEnabled')->once()->andReturn(true);
            $mock->shouldNotReceive('indexVehicle');
        });

        $listener = $this->app->make(IndexVehicleInMeilisearch::class);
        $event = new NewVehicleImported($vehicle, [], 'motordata');

        $listener->handle($event);
    }

    /**
     * Test that NewVehicleImported does nothing when Meilisearch is disabled.
     */
    public function testNewVehicleImportedSkipsWhenMeilisearchDisabled(): void
    {
        $vehicle = Vehicle::factory()->create();

        $this->mock(MeilisearchService::class, function (MockInterface $mock) {
            $mock->shouldReceive('isEnabled')->once()->andReturn(false);
            $mock->shouldNotReceive('indexVehicle');
        });

        $listener = $this->app->make(IndexVehicleInMeilisearch::class);
        $event = new NewVehicleImported($vehicle, [], 'autograb');

        $listener->handle($event);
    }

    /**
     * Test that VehicleUpdatedFromImport indexes vehicle for AutoGrab provider.
     */
    public function testVehicleUpdatedFromImportIndexesForAutograb(): void
    {
        $vehicle = Vehicle::factory()->create();

        $this->mock(MeilisearchService::class, function (MockInterface $mock) use ($vehicle) {
            $mock->shouldReceive('isEnabled')->once()->andReturn(true);
            $mock->shouldReceive('indexVehicle')
                ->once()
                ->with(\Mockery::on(fn ($v) => $v->id === $vehicle->id));
        });

        $listener = $this->app->make(IndexVehicleInMeilisearch::class);
        $event = new VehicleUpdatedFromImport($vehicle, [], 'autograb');

        $listener->handle($event);
    }

    /**
     * Test that VehicleUpdatedFromImport does NOT index for batch providers.
     */
    public function testVehicleUpdatedFromImportSkipsBatchProviders(): void
    {
        $vehicle = Vehicle::factory()->create();

        $this->mock(MeilisearchService::class, function (MockInterface $mock) {
            $mock->shouldReceive('isEnabled')->once()->andReturn(true);
            $mock->shouldNotReceive('indexVehicle');
        });

        $listener = $this->app->make(IndexVehicleInMeilisearch::class);
        $event = new VehicleUpdatedFromImport($vehicle, [], 'motordata');

        $listener->handle($event);
    }
}
