<?php

declare(strict_types=1);

namespace Ferienpass\AdminBundle\Tests\Form\Extension;

use Contao\CoreBundle\Filesystem\VirtualFilesystemInterface;
use Doctrine\ORM\EntityManagerInterface;
use Ferienpass\AdminBundle\Export\XlsxExportQueryBuilder;
use Ferienpass\AdminBundle\Form\Event\SubmitEvent;
use Ferienpass\AdminBundle\Form\Extension\Form\EditAccountType;
use Ferienpass\AdminBundle\Form\Extension\Form\EditEditionType;
use Ferienpass\AdminBundle\Form\Extension\Form\EditHostType;
use Ferienpass\AdminBundle\Form\Extension\Form\EditOfferType;
use Ferienpass\AdminBundle\Form\Extension\Form\EditParticipantType;
use Ferienpass\AdminBundle\Service\FileUploader;
use Symfony\Component\String\Slugger\SluggerInterface;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;

final class EditFormTypesTest extends TestCase
{
    // ---- EditAccountType ----

    public function testEditAccountTypeSubmitDoesNothingForNonUserEntity(): void
    {
        $em = $this->createMock(EntityManagerInterface::class);
        $em->expects(self::never())->method('persist');

        $form = $this->createMock(FormInterface::class);
        $form->method('getData')->willReturn(new \stdClass());

        $event = new SubmitEvent($form, new Request());

        (new EditAccountType($em))->submit($event);
    }

    public function testEditAccountTypeGetSubscribedEventsContainsSubmitEvent(): void
    {
        self::assertArrayHasKey(SubmitEvent::class, EditAccountType::getSubscribedEvents());
    }

    // ---- EditEditionType ----

    public function testEditEditionTypeSubmitDoesNothingForNonEditionEntity(): void
    {
        $em = $this->createMock(EntityManagerInterface::class);
        $em->expects(self::never())->method('persist');

        $form = $this->createMock(FormInterface::class);
        $form->method('getData')->willReturn(new \stdClass());

        $event = new SubmitEvent($form, new Request());

        (new EditEditionType($em))->submit($event);
    }

    public function testEditEditionTypeGetSubscribedEventsContainsSubmitEvent(): void
    {
        self::assertArrayHasKey(SubmitEvent::class, EditEditionType::getSubscribedEvents());
    }

    // ---- EditHostType ----

    public function testEditHostTypeSubmitDoesNothingForNonHostEntity(): void
    {
        $fileUploader = $this->createMock(FileUploader::class);
        $em = $this->createMock(EntityManagerInterface::class);
        $em->expects(self::never())->method('persist');
        $storage = $this->createMock(VirtualFilesystemInterface::class);

        $form = $this->createMock(FormInterface::class);
        $form->method('getData')->willReturn(new \stdClass());

        $event = new SubmitEvent($form, new Request());

        (new EditHostType($fileUploader, $em, $storage))->submit($event);
    }

    public function testEditHostTypeGetSubscribedEventsContainsSubmitEvent(): void
    {
        self::assertArrayHasKey(SubmitEvent::class, EditHostType::getSubscribedEvents());
    }

    // ---- EditParticipantType ----

    public function testEditParticipantTypeSubmitDoesNothingForNonParticipantEntity(): void
    {
        $em = $this->createMock(EntityManagerInterface::class);
        $em->expects(self::never())->method('persist');

        $form = $this->createMock(FormInterface::class);
        $form->method('getData')->willReturn(new \stdClass());

        $event = new SubmitEvent($form, new Request());

        (new EditParticipantType($em))->submit($event);
    }

    public function testEditParticipantTypeGetSubscribedEventsContainsSubmitEvent(): void
    {
        self::assertArrayHasKey(SubmitEvent::class, EditParticipantType::getSubscribedEvents());
    }

    // ---- EditOfferType ----

    public function testEditOfferTypeSubmitDoesNothingForNonOfferEntity(): void
    {
        $em = $this->createMock(EntityManagerInterface::class);
        $em->expects(self::never())->method('persist');

        $form = $this->createMock(FormInterface::class);
        $form->method('getData')->willReturn(new \stdClass());

        $event = new SubmitEvent($form, new Request());

        (new EditOfferType(
            $this->createMock(FileUploader::class),
            $this->createMock(VirtualFilesystemInterface::class),
            $this->createMock(VirtualFilesystemInterface::class),
            $em,
            $this->createMock(SluggerInterface::class),
        ))->submit($event);
    }

    public function testEditOfferTypeGetSubscribedEventsContainsSubmitEvent(): void
    {
        self::assertArrayHasKey(SubmitEvent::class, EditOfferType::getSubscribedEvents());
    }

    // ---- XlsxExportQueryBuilder ----

    public function testXlsxExportQueryBuilderGetFormat(): void
    {
        self::assertSame('xlsx', XlsxExportQueryBuilder::getFormat());
    }
}
