<?php

namespace App\Tests\A_Unit\Adapter\Controller\Front\Registration\Store;

use Myvetshop\Module\Clinique\Adapter\Controller\Front\Registration\Store\StoreLocatorControllerAdapter;
use Myvetshop\Module\Clinique\Adapter\Repository\StoreRepository;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

class StoreLocatorControllerAdapterTest extends TestCase
{
    /**
     * @var StoreRepository&\PHPUnit\Framework\MockObject\MockObject
     */
    private StoreRepository $storeRepositoryMock;

    private StoreLocatorControllerAdapter $adapter;

    protected function setUp(): void
    {
        $this->storeRepositoryMock = $this->createMock(StoreRepository::class);
        $this->adapter = new StoreLocatorControllerAdapter($this->storeRepositoryMock);
    }

    public function testHandleRequestDefaultParameters(): void
    {
        $request = new Request();

        $this->storeRepositoryMock
            ->expects($this->once())
            ->method('findByDistance')
            ->with(
                45.9884485,
                -2.6998618,
                500,
                0,
                50
            )
            ->willReturn(['store1', 'store2']);

        $context = $this->createMock(\Context::class);
        $result = $this->adapter->handleRequest($context, $request);

        $this->assertArrayHasKey('response', $result);
        \assert(isset($result['response']));
        $responseContent = \json_decode((string) $result['response']->getContent(), true);

        $this->assertInstanceOf(JsonResponse::class, $result['response']);
        $this->assertEquals(['store1', 'store2'], $responseContent);
    }

    public function testHandleRequestCustomParameters(): void
    {
        $request = new Request([
            'latitude' => 40.0,
            'longitude' => -3.0,
            'distance' => 300,
            'start' => 10,
            'limit' => 5,
        ]);

        $this->storeRepositoryMock
            ->expects($this->once())
            ->method('findByDistance')
            ->with(
                40.0,
                -3.0,
                300,
                10,
                5
            )
            ->willReturn(['storeA', 'storeB']);

        $context = $this->createMock(\Context::class);
        $result = $this->adapter->handleRequest($context, $request);

        $this->assertArrayHasKey('response', $result);
        \assert(isset($result['response']));
        $responseContent = \json_decode((string) $result['response']->getContent(), true);

        $this->assertInstanceOf(JsonResponse::class, $result['response']);
        $this->assertEquals(['storeA', 'storeB'], $responseContent);
    }

    public function testHandleRequestInvalidParameterType(): void
    {
        $this->expectException(\Symfony\Component\OptionsResolver\Exception\InvalidOptionsException::class);

        $request = new Request(['latitude' => 'invalid']);
        $context = $this->createMock(\Context::class);
        $this->adapter->handleRequest($context, $request);
    }
}
