<?php

/*
 * This file has been created by developers from BitBag.
 * Feel free to contact us once you face any issues or want to start
 * another great project.
 * You can find more information about us on https://bitbag.io and write us
 * an email on hello@bitbag.io.
 */

declare(strict_types=1);

namespace PHPUnit\Integration\Api;

use ApiTestCase\JsonApiTestCase;
use Sylius\Bundle\CoreBundle\SyliusCoreBundle;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Process\Process;

final class ProductListingTest extends JsonApiTestCase
{
    public function __construct(
        ?string $name = null,
        array $data = [],
        string $dataName = ''
    ) {
        parent::__construct($name, $data, $dataName);

        $this->dataFixturesPath = __DIR__ . \DIRECTORY_SEPARATOR . 'DataFixtures' . \DIRECTORY_SEPARATOR . 'ORM';
        $this->expectedResponsesPath = __DIR__ . \DIRECTORY_SEPARATOR . 'Responses' . \DIRECTORY_SEPARATOR . 'Expected';
    }

    public function test_it_finds_products_by_name(): void
    {
        $this->loadFixturesFromFiles(['test_it_finds_products_by_name.yaml']);
        $this->populateElasticsearch();

        $this->client->request(
            'GET',
            '/api/v2/shop/products/search?query=mug'
        );

        $response = $this->client->getResponse();

        if (SyliusCoreBundle::VERSION_ID >= 20100) {
            $this->assertResponse($response, '2.1_test_it_finds_products_by_name', Response::HTTP_OK);

            return;
        }

        $this->assertResponse($response, 'test_it_finds_products_by_name', Response::HTTP_OK);
    }

    public function test_it_finds_products_by_name_and_facets(): void
    {
        $this->loadFixturesFromFiles(['test_it_finds_products_by_name_and_facets.yaml']);
        $this->populateElasticsearch();

        $this->client->request(
            'GET',
            '/api/v2/shop/products/search?query=mug&facets[color][]=red'
        );

        $response = $this->client->getResponse();

        if (SyliusCoreBundle::VERSION_ID >= 20100) {
            $this->assertResponse($response, '2.1_test_it_finds_products_by_name_and_facets', Response::HTTP_OK);

            return;
        }

        $this->assertResponse($response, 'test_it_finds_products_by_name_and_facets', Response::HTTP_OK);
    }

    public function test_it_finds_products_by_name_and_multiple_facets(): void
    {
        $this->loadFixturesFromFiles(['test_it_finds_products_by_name_and_multiple_facets.yaml']);
        $this->populateElasticsearch();

        $this->client->request(
            'GET',
            '/api/v2/shop/products/search?query=mug&facets[color][]=red&facets[material][]=ceramic'
        );

        $response = $this->client->getResponse();

        if (SyliusCoreBundle::VERSION_ID >= 20100) {
            $this->assertResponse($response, '2.1_test_it_finds_products_by_name_and_multiple_facets', Response::HTTP_OK);

            return;
        }

        $this->assertResponse($response, 'test_it_finds_products_by_name_and_multiple_facets', Response::HTTP_OK);
    }

    public function test_it_updates_facets(): void
    {
        $this->loadFixturesFromFiles(['test_it_updates_facets.yaml']);
        $this->populateElasticsearch();

        $this->client->request(
            'GET',
            '/api/v2/shop/products/search?query=mug&facets[color][]=red&facets[material][]=ceramic'
        );

        $response = $this->client->getResponse();

        if (SyliusCoreBundle::VERSION_ID >= 20100) {
            $this->assertResponse($response, '2.1_test_it_updates_facets', Response::HTTP_OK);

            return;
        }

        $this->assertResponse($response, 'test_it_updates_facets', Response::HTTP_OK);
    }

    private function populateElasticsearch(): void
    {
        $process = new Process(['tests/Application/bin/console', 'fos:elastica:populate']);
        $process->run();

        if (!$process->isSuccessful()) {
            throw new \Exception('Failed to populate Elasticsearch: ' . $process->getErrorOutput());
        }
    }
}
