<?php

namespace Tests\Tenant;

use App\Services\MeilisearchService;
use Meilisearch\Endpoints\Indexes;
use Mockery\MockInterface;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class MeilisearchFacetingSettingsTest extends TenantTestCase
{
    use UserForTenant;

    public function test_get_faceting_returns_current_value(): void
    {
        $this->mock(MeilisearchService::class, function (MockInterface $mock) {
            $index = \Mockery::mock(Indexes::class);
            $index->shouldReceive('getFaceting')
                ->once()
                ->andReturn(['maxValuesPerFacet' => 100]);

            $mock->shouldReceive('isEnabled')->once()->andReturn(true);
            $mock->shouldReceive('getVehicleIndex')->once()->andReturn($index);
        });

        $response = $this->actingAs($this->getUser())
            ->getJson('/api/meilisearch/faceting');

        $response->assertOk()
            ->assertJson(['maxValuesPerFacet' => 100]);
    }

    public function test_update_faceting_sets_new_value(): void
    {
        $this->mock(MeilisearchService::class, function (MockInterface $mock) {
            $index = \Mockery::mock(Indexes::class);
            $index->shouldReceive('updateFaceting')
                ->once()
                ->with(['maxValuesPerFacet' => 10000]);
            $index->shouldReceive('getFaceting')
                ->once()
                ->andReturn(['maxValuesPerFacet' => 10000]);

            $mock->shouldReceive('isEnabled')->once()->andReturn(true);
            $mock->shouldReceive('getVehicleIndex')->andReturn($index);
        });

        $response = $this->actingAs($this->getUser())
            ->putJson('/api/meilisearch/faceting', [
                'maxValuesPerFacet' => 10000,
            ]);

        $response->assertOk()
            ->assertJson(['maxValuesPerFacet' => 10000]);
    }

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

        $response = $this->actingAs($this->getUser())
            ->getJson('/api/meilisearch/faceting');

        $response->assertStatus(400)
            ->assertJson(['message' => 'Meilisearch is not enabled for this tenant.']);
    }

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

        $response = $this->actingAs($this->getUser())
            ->putJson('/api/meilisearch/faceting', [
                'maxValuesPerFacet' => 500,
            ]);

        $response->assertStatus(400)
            ->assertJson(['message' => 'Meilisearch is not enabled for this tenant.']);
    }

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

        $response = $this->actingAs($this->getUser())
            ->putJson('/api/meilisearch/faceting', []);

        $response->assertUnprocessable()
            ->assertJsonValidationErrors('maxValuesPerFacet');
    }

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

        $response = $this->actingAs($this->getUser())
            ->putJson('/api/meilisearch/faceting', [
                'maxValuesPerFacet' => 99999,
            ]);

        $response->assertUnprocessable()
            ->assertJsonValidationErrors('maxValuesPerFacet');
    }
}
