<?php

declare(strict_types=1);

/*
 * This file is part of the VITICORE2 package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Tests\EventListener;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\EventListener\LocalBusinessStructuredDataSubscriber;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Twig\FileExtension;
use CpCreation\VitiCore\Contact\ContactProvider;
use CpCreation\VitiCore\Contact\Model\Contact;
use CpCreation\VitiCore\Contact\Repository\ContactRepository;
use CpCreation\VitiCore\Seo\LocalBusinessSchemaBuilder;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;

final class LocalBusinessStructuredDataSubscriberTest extends TestCase
{
    public function testInjectsTheSchemaBeforeTheClosingHeadTag(): void
    {
        $contact = new Contact();
        $contact->setCompany('Maison Exemple');
        $contact->setAddress('1 rue des Vignes');
        $contact->setPostal('51200');
        $contact->setCity('Épernay');
        $contact->setCountry('FR');
        $contact->setPhone1('+33 3 26 00 00 00');

        $repository = $this->createMock(ContactRepository::class);
        $repository->expects(self::once())->method('findOne')->willReturn($contact);
        $fileExtension = $this->createStub(FileExtension::class);
        $request = Request::create('https://example.com/une-page');
        $request->attributes->set('_route', 'homepage');
        $response = new Response('<html><head><title>Exemple</title></head><body></body></html>');
        $response->headers->set('Content-Type', 'text/html; charset=UTF-8');
        $event = new ResponseEvent(
            $this->createStub(KernelInterface::class),
            $request,
            HttpKernelInterface::MAIN_REQUEST,
            $response,
        );

        new LocalBusinessStructuredDataSubscriber(
            new ContactProvider($repository),
            new LocalBusinessSchemaBuilder(),
            $fileExtension,
        )->onKernelResponse($event);

        $content = (string) $response->getContent();
        self::assertStringContainsString(
            '<script id="viti-local-business-schema" type="application/ld+json">',
            $content,
        );
        self::assertStringContainsString('"@type":"Winery"', $content);
        self::assertStringContainsString('"name":"Maison Exemple"', $content);
        self::assertLessThan(strpos($content, '</head>'), strpos($content, 'viti-local-business-schema'));
    }

    public function testDoesNotInjectTheSchemaIntoAnAdminPage(): void
    {
        $repository = $this->createMock(ContactRepository::class);
        $repository->expects(self::never())->method('findOne');
        $request = Request::create('https://example.com/admin/contact');
        $request->attributes->set('_route', 'admin_contact');
        $response = new Response('<html><head></head><body></body></html>');
        $response->headers->set('Content-Type', 'text/html; charset=UTF-8');
        $event = new ResponseEvent(
            $this->createStub(KernelInterface::class),
            $request,
            HttpKernelInterface::MAIN_REQUEST,
            $response,
        );

        new LocalBusinessStructuredDataSubscriber(
            new ContactProvider($repository),
            new LocalBusinessSchemaBuilder(),
            $this->createStub(FileExtension::class),
        )->onKernelResponse($event);

        self::assertStringNotContainsString('viti-local-business-schema', (string) $response->getContent());
    }
}
