<?php declare(strict_types=1);

namespace Newland\Toubiz\Poi\Neos\Tests\Integration\Detail;

use Neos\Flow\Http\Response;
use Newland\Toubiz\Api\ObjectAdapter\Concern\ArticleConstants;
use Newland\Toubiz\Poi\Neos\Tests\Integration\IntegrationTestCase;
use Newland\Toubiz\Sync\Neos\Domain\Model\Article;
use Newland\Toubiz\Sync\Neos\Tests\Factory\UriFactory;

abstract class AbstractDetailTestCase extends IntegrationTestCase
{

    protected abstract function articleType(): int;

    protected function article(array $attributes = []): Article
    {
        $attributes['mainType'] = $this->articleType();
        return $this->articleFactory->create($attributes);
    }

    protected function articleUrl(Article $article): string
    {
        return $this->articleUrlService->generateUrlByCurrentNode($article, $this->node);
    }

    protected function requestArticleDetailPage(Article $article): Response
    {
        return $this->browser->request(
            $this->articleUrl($article)
        );
    }

    public function testDoesNotThrowError(): void
    {
        $response = $this->requestArticleDetailPage($this->article());
        $this->assertResponseOk($response);
        $this->assertResponseNotContains('Exception.*', $response);
    }

    public function testDisplaysBookingLink(): void
    {
        if ($this->articleType() === ArticleConstants::TYPE_CITY) {
            $this->assertTrue(true);
            return;
        }

        $response = $this->requestArticleDetailPage($this->article([
            'bookingUris' => [
                (new UriFactory($this->objectManager))->create([ 'label' => 'Jetzt buchen', 'uri' => 'https://google.com', 'originalId' => 'foo' ]),
                (new UriFactory($this->objectManager))->create([ 'label' => 'Jetzt informieren', 'uri' => 'https://yahoo.com', 'originalId' => 'bar' ]),
            ]
        ]));

        $this->assertResponseOk($response);
        $this->assertResponseContains('Jetzt buchen', $response);
        $this->assertResponseContains('href="https:\/\/google.com"', $response);
        $this->assertResponseContains('Jetzt informieren', $response);
        $this->assertResponseContains('href="https:\/\/yahoo.com"', $response);
    }
    public function testUrlsWithoutUrlIdentifiersRedirectCorrectly(): void
    {
        $article = $this->article([ 'language' => 'de', 'urlIdentifier' => md5(random_bytes(32)) ]);
        $url = $this->articleUrl($article);
        $urlWithoutHash = str_replace('-' . $article->getUrlIdentifier(), '', $url);

        $this->browser->setFollowRedirects(false);
        $response = $this->browser->request($urlWithoutHash);

        $this->assertEquals(301, $response->getStatusCode());
        $this->assertEquals($url, $response->getHeader('Location'));
    }

    public function testUrlsWithIncorrectPathRedirectToCorrectUrlIdentifier(): void
    {
        $article = $this->article([ 'language' => 'de', 'urlIdentifier' => md5(random_bytes(32)) ]);
        $url = $this->articleUrl($article);

        $urlParts = explode('/', $url);
        $urlParts[count($urlParts) - 1] = 'foo-bar-' . $article->getUrlIdentifier();
        $urlWithIncorrectNamePart = implode('/', $urlParts);

        $this->browser->setFollowRedirects(false);
        $response = $this->browser->request($urlWithIncorrectNamePart);

        $this->assertEquals(301, $response->getStatusCode());
        $this->assertEquals($url, $response->getHeader('Location'));
    }
    public function testDoesNotShowHiddenArticles(): void
    {
        $hidden = $this->article([ 'hidden' => true ]);
        $response = $this->requestArticleDetailPage($hidden);
        $this->assertEquals(404, $response->getStatusCode());
    }

}
