<?php declare(strict_types=1);

namespace Newland\Toubiz\Events\Neos\Tests\Integration;

class TeaserListTest extends IntegrationTestCase
{
    public function setUp(): void
    {
        parent::setUp();
        $this->node->setNodeType($this->nodeTypeManager->getNodeType('Newland.Toubiz.Events.Neos:TeaserList'));
        $this->node->setProperty('recordLimit', 5);
        $this->persistNode($this->node);
    }

    public function testDoesNotThrowError(): void
    {
        $tomorrow = (new \DateTime())->add(new \DateInterval('P1D'));
        $eventTomorrow = $this->eventFactory->create([ 'title' => 'DATE_TOMORROW' ]);
        $this->eventDateFactory->create(
            [
                'beginsAt' => $tomorrow,
                'endsAt' => (clone $tomorrow)->add(new \DateInterval('PT1H')),
                'event' => $eventTomorrow,
            ]
        );

        $yesterday = (new \DateTime())->sub(new \DateInterval('P1D'));
        $eventYesterday = $this->eventFactory->create([ 'title' => 'DATE_YESTERDAY' ]);
        $this->eventDateFactory->create(
            [
                'beginsAt' => $yesterday,
                'endsAt' => (clone $yesterday)->add(new \DateInterval('PT1H')),
                'event' => $eventYesterday,
            ]
        );

        $dayAfterTomorrow = (new \DateTime())->add(new \DateInterval('P2D'));
        $eventDayAfterTomorrow = $this->eventFactory->create([ 'title' => 'DATE_DAY_AFTER_TOMORROW' ]);
        $this->eventDateFactory->create(
            [
                'beginsAt' => $dayAfterTomorrow,
                'endsAt' => (clone $dayAfterTomorrow)->add(new \DateInterval('PT1H')),
                'event' => $eventDayAfterTomorrow,
            ]
        );

        $response = $this->browser->request($this->nodeUri);
        $this->assertResponseOk($response);
    }


    public function testOnlyDisplaysEventsThatHaveDatesInTheFuture(): void
    {
        $this->node->setProperty('numberOfDays', 5);
        $this->persistNode($this->node);

        $this->eventFactory->create([ 'title' => 'NO_DATES' ]);

        $tomorrow = (new \DateTime())->add(new \DateInterval('P1D'));
        $dateTomorrow = $this->eventFactory->create([ 'title' => 'DATE_TOMORROW' ]);
        $this->eventDateFactory->create(
            [
                'beginsAt' => $tomorrow,
                'endsAt' => (clone $tomorrow)->add(new \DateInterval('PT1H')),
                'event' => $dateTomorrow,
            ]
        );

        $yesterday = (new \DateTime())->sub(new \DateInterval('P1D'));
        $dateYesterday = $this->eventFactory->create([ 'title' => 'DATE_YESTERDAY' ]);
        $this->eventDateFactory->create(
            [
                'beginsAt' => $yesterday,
                'endsAt' => (clone $yesterday)->add(new \DateInterval('PT1H')),
                'event' => $dateYesterday,
            ]
        );

        $dayAfterTomorrow = (new \DateTime())->add(new \DateInterval('P2D'));
        $dateYesterday = $this->eventFactory->create([ 'title' => 'DATE_DAY_AFTER_TOMORROW' ]);
        $this->eventDateFactory->create(
            [
                'beginsAt' => $dayAfterTomorrow,
                'endsAt' => (clone $dayAfterTomorrow)->add(new \DateInterval('PT1H')),
                'event' => $dateYesterday,
            ]
        );

        $response = $this->browser->request($this->nodeUri);
        $this->assertResponseOk($response);

        $this->assertResponseContains('DATE_TOMORROW', $response);
        $this->assertResponseContains('DATE_DAY_AFTER_TOMORROW', $response);
        $this->assertResponseNotContains('NO_DATES', $response);
        $this->assertResponseNotContains('DATE_YESTERDAY', $response);
    }

    public function testDisplaysDatesOnlyUpToGivenNumberOfDaysInFuture(): void
    {

        $this->node->setProperty('numberOfDays', 2);
        $this->persistNode($this->node);

        $this->eventFactory->create([ 'title' => 'NO_DATES' ]);

        $tomorrow = (new \DateTime())->add(new \DateInterval('P1D'));
        $dateTomorrow = $this->eventFactory->create([ 'title' => 'DATE_TOMORROW' ]);
        $this->eventDateFactory->create(
            [
                'beginsAt' => $tomorrow,
                'endsAt' => (clone $tomorrow)->add(new \DateInterval('PT1H')),
                'event' => $dateTomorrow,
            ]
        );

        $yesterday = (new \DateTime())->sub(new \DateInterval('P1D'));
        $dateYesterday = $this->eventFactory->create([ 'title' => 'DATE_YESTERDAY' ]);
        $this->eventDateFactory->create(
            [
                'beginsAt' => $yesterday,
                'endsAt' => (clone $yesterday)->add(new \DateInterval('PT1H')),
                'event' => $dateYesterday,
            ]
        );

        $dayAfterTomorrow = (new \DateTime())->add(new \DateInterval('P2D'));
        $dateYesterday = $this->eventFactory->create([ 'title' => 'DATE_DAY_AFTER_TOMORROW' ]);
        $this->eventDateFactory->create(
            [
                'beginsAt' => $dayAfterTomorrow,
                'endsAt' => (clone $dayAfterTomorrow)->add(new \DateInterval('PT1H')),
                'event' => $dateYesterday,
            ]
        );

        $response = $this->browser->request($this->nodeUri);
        $this->assertResponseOk($response);

        $this->assertResponseContains('DATE_TOMORROW', $response);
        $this->assertResponseNotContains('DATE_DAY_AFTER_TOMORROW', $response);
        $this->assertResponseNotContains('NO_DATES', $response);
        $this->assertResponseNotContains('DATE_YESTERDAY', $response);
    }

    public function testRendersSlots(): void
    {
        $this->node->setProperty('numberOfDays', 2);
        $tomorrow = (new \DateTimeImmutable())->add(new \DateInterval('P1D'));
        $this->createEventWithDate([  ], [
            'beginsAt' => $tomorrow,
            'endsAt' => $tomorrow->add(new \DateInterval('PT1H')),
        ]);

        $response = $this->browser->request($this->nodeUri());
        $this->assertResponseOk($response);

        foreach ($this->provideSlotsThatShouldExist() as [ $slot ]) {
            $this->assertResponseContains(sprintf('Slot(%s)', $slot), $response, null, false);
        }
    }

    public function provideSlotsThatShouldExist(): array
    {
        return [
            [ 'aboveAll' ],
            [ 'belowAll' ],
            [ 'aboveTitle' ],
            [ 'belowTitle' ],
            [ 'aboveTeaserList' ],
            [ 'belowTeaserList' ],
            [ 'aboveListItem' ],
            [ 'belowListItem' ],
            [ 'aboveListItemTitle' ],
            [ 'belowListItemTitle' ],
        ];
    }

}
