<?php

declare(strict_types=1);

namespace App\Tests\Module\Catalog\Api;

/**
 * Tests du filtre `?typeCode=` sur GET /api/categories (ERP-84).
 *
 * Brique manquante avant le M2 : le filtre n'existait pas en prod (ERP-78 avait
 * unifie sur un type unique CLIENT). Apres implementation :
 *  - `?typeCode=FOURNISSEUR` ne renvoie QUE les categories du type FOURNISSEUR ;
 *  - le filtre n'altere pas l'echappatoire `?pagination=false` ;
 *  - un code inexistant renvoie une liste vide (pas d'erreur).
 *
 * @internal
 */
final class CategoryTypeCodeFilterTest extends AbstractCatalogApiTestCase
{
    public function testTypeCodeFilterReturnsOnlyMatchingType(): void
    {
        $clientType   = $this->createCategoryType('TEST_CLIENT');
        $supplierType = $this->createCategoryType('TEST_FOURNISSEUR');

        $this->createCategory(self::TEST_CATEGORY_PREFIX.'client_one', $clientType);
        $this->createCategory(self::TEST_CATEGORY_PREFIX.'supplier_one', $supplierType);
        $this->createCategory(self::TEST_CATEGORY_PREFIX.'supplier_two', $supplierType);

        $client   = $this->createAdminClient();
        $response = $client->request('GET', '/api/categories?typeCode=TEST_FOURNISSEUR&pagination=false');
        self::assertSame(200, $response->getStatusCode());

        $members  = $response->toArray()['member'];
        $names    = array_map(fn (array $m): string => $m['name'], $members);
        $testOnly = array_values(array_filter(
            $names,
            fn (string $n): bool => str_starts_with($n, self::TEST_CATEGORY_PREFIX),
        ));

        sort($testOnly);
        self::assertSame(
            [
                self::TEST_CATEGORY_PREFIX.'supplier_one',
                self::TEST_CATEGORY_PREFIX.'supplier_two',
            ],
            $testOnly,
            'Le filtre ?typeCode= doit ne renvoyer QUE les categories du type demande.',
        );

        // Chaque categorie remontee doit PORTER le type filtre (multi-types :
        // la collection categoryTypes embarquee contient le code demande).
        foreach ($members as $member) {
            self::assertContains('TEST_FOURNISSEUR', array_column($member['categoryTypes'], 'code'));
        }
    }

    public function testTypeCodeFilterWorksWithPagination(): void
    {
        $supplierType = $this->createCategoryType('TEST_FOURNISSEUR');
        $this->createCategory(self::TEST_CATEGORY_PREFIX.'paginated', $supplierType);

        $client   = $this->createAdminClient();
        // Sans ?pagination=false : on doit obtenir l'enveloppe Hydra paginee.
        $response = $client->request('GET', '/api/categories?typeCode=TEST_FOURNISSEUR');
        self::assertSame(200, $response->getStatusCode());

        $data = $response->toArray();
        self::assertArrayHasKey('totalItems', $data, 'Le filtre ne doit pas casser la pagination Hydra.');
        self::assertArrayHasKey('member', $data);

        foreach ($data['member'] as $member) {
            self::assertContains('TEST_FOURNISSEUR', array_column($member['categoryTypes'], 'code'));
        }
    }

    public function testUnknownTypeCodeReturnsEmptyList(): void
    {
        $type = $this->createCategoryType('TEST_CLIENT');
        $this->createCategory(self::TEST_CATEGORY_PREFIX.'lonely', $type);

        $client   = $this->createAdminClient();
        $response = $client->request('GET', '/api/categories?typeCode=TEST_DOES_NOT_EXIST&pagination=false');
        self::assertSame(200, $response->getStatusCode());

        self::assertSame([], $response->toArray()['member']);
    }
}
