<?php

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

use Myvetshop\Module\Clinique\Adapter\Controller\Front\MyRecoControllerAdapter;
use Myvetshop\Module\Clinique\Adapter\Controller\Front\MyRecoDeleteControllerAdapter;
use Myvetshop\Module\Clinique\Adapter\Controller\Front\MyRecoImportControllerAdapter;
use Myvetshop\Module\Clinique\Adapter\Controller\Front\MyRecoNotLoggedInControllerAdapter;
use Myvetshop\Module\Clinique\Adapter\Controller\Front\MyRecoPdfControllerAdapter;
use Myvetshop\Module\Clinique\Adapter\Controller\Front\MyRecoUpdateControllerAdapter;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;

class MyRecoControllerAdapterTest extends TestCase
{
    private MyRecoControllerAdapter $myRecoControllerAdapter;

    /**
     * @var MyRecoDeleteControllerAdapter&MockObject
     */
    private MyRecoDeleteControllerAdapter $myRecoDeleteControllerAdapter;

    /**
     * @var MyRecoImportControllerAdapter&MockObject
     */
    private MyRecoImportControllerAdapter $myRecoImportControllerAdapter;

    /**
     * @var MyRecoNotLoggedInControllerAdapter&MockObject
     */
    private MyRecoNotLoggedInControllerAdapter $myRecoNotLoggedInControllerAdapter;

    /**
     * @var MyRecoPdfControllerAdapter&MockObject
     */
    private MyRecoPdfControllerAdapter $myRecoPdfControllerAdapter;

    /**
     * @var MyRecoUpdateControllerAdapter&MockObject
     */
    private MyRecoUpdateControllerAdapter $myRecoUpdateControllerAdapter;

    protected function setUp(): void
    {
        $this->myRecoDeleteControllerAdapter = $this->createMock(MyRecoDeleteControllerAdapter::class);
        $this->myRecoImportControllerAdapter = $this->createMock(MyRecoImportControllerAdapter::class);
        $this->myRecoNotLoggedInControllerAdapter = $this->createMock(MyRecoNotLoggedInControllerAdapter::class);
        $this->myRecoPdfControllerAdapter = $this->createMock(MyRecoPdfControllerAdapter::class);
        $this->myRecoUpdateControllerAdapter = $this->createMock(MyRecoUpdateControllerAdapter::class);
        $this->myRecoControllerAdapter = new MyRecoControllerAdapter(
            $this->myRecoDeleteControllerAdapter,
            $this->myRecoImportControllerAdapter,
            $this->myRecoNotLoggedInControllerAdapter,
            $this->myRecoPdfControllerAdapter,
            $this->myRecoUpdateControllerAdapter
        );
    }

    public function testHandleRequestWithImportAction(): void
    {
        $context = $this->createMock(\Context::class);
        $context->customer = $this->createMock(\Customer::class);
        $context->customer->method('isLogged')->willReturn(false);

        $request = new Request(['action' => 'import']);

        $this->myRecoNotLoggedInControllerAdapter->expects($this->once())
            ->method('handleRequest')
            ->with($context, $request);

        $this->myRecoControllerAdapter->handleRequest($context, $request);
    }

    public function testHandleRequestWithUpdateAction(): void
    {
        $context = $this->createMock(\Context::class);
        $context->customer = $this->createMock(\Customer::class);
        $context->customer->method('isLogged')->willReturn(true);

        $request = new Request(['action' => 'update']);

        $this->myRecoUpdateControllerAdapter->expects($this->once())
            ->method('handleRequest')
            ->with($context, $request);

        $this->myRecoControllerAdapter->handleRequest($context, $request);
    }

    public function testHandleRequestWithDeleteAction(): void
    {
        $context = $this->createMock(\Context::class);
        $context->customer = $this->createMock(\Customer::class);
        $context->customer->method('isLogged')->willReturn(true);

        $request = new Request(['action' => 'delete']);

        $this->myRecoDeleteControllerAdapter->expects($this->once())
            ->method('handleRequest')
            ->with($context, $request);

        $this->myRecoControllerAdapter->handleRequest($context, $request);
    }

    public function testHandleRequestWithPdfAction(): void
    {
        $context = $this->createMock(\Context::class);
        $context->customer = $this->createMock(\Customer::class);
        $context->customer->method('isLogged')->willReturn(true);

        $request = new Request(['action' => 'pdf']);

        $this->myRecoPdfControllerAdapter->expects($this->once())
            ->method('handleRequest')
            ->with($context, $request);

        $this->myRecoControllerAdapter->handleRequest($context, $request);
    }

    public function testHandleRequestWithNoExistingAction(): void
    {
        $context = $this->createMock(\Context::class);
        $context->customer = $this->createMock(\Customer::class);
        $context->customer->method('isLogged')->willReturn(true);

        $request = new Request(['action' => 'nonExistentAction']);

        $this->expectException(InvalidOptionsException::class);

        $this->myRecoControllerAdapter->handleRequest($context, $request);
    }
}
