<?php

declare(strict_types=1);

namespace CpCreation\VitiThemeLegacyTheme3\Tests;

use PHPUnit\Framework\TestCase;

final class TemplateContractTest extends TestCase
{
    private const string TEMPLATES = __DIR__.'/../templates';

    public function testCoreWrappersUseTheExplicitCoreFallbackNamespace(): void
    {
        foreach (['cgv.html.twig', 'legal.html.twig', 'privacy_policy.html.twig', 'shop/index.html.twig'] as $template) {
            $contents = $this->contents($template);

            self::assertStringContainsString("{% extends '@viti_core_default/", $contents, $template);
            self::assertStringNotContainsString("{% extends '@CpCreationVitiCore/", $contents, $template);
        }
    }

    public function testShopOverridesKeepTheNewCoreContracts(): void
    {
        $catalog = $this->contents('components/shop/Catalog.html.twig');
        self::assertStringContainsString('not this.collectionSource or this.productCollection', $catalog);

        $navigation = $this->contents('components/shop/ProductNavigation.html.twig');
        self::assertStringContainsString('this.showCategoryMenu', $navigation);
        self::assertStringContainsString("path('shop', backToShopRouteParams)", $navigation);

        $grid = $this->contents('components/shop/ProductGrid.html.twig');
        foreach (['this.getReviewSummary(product)', 'reviewRatingValue', 'reviewCount', 'reviewsEnabled'] as $contract) {
            self::assertStringContainsString($contract, $grid);
        }

        $itemForm = $this->contents('components/cart/ItemForm.html.twig');
        foreach (['showProductReviewsModal', 'product-reviews-modal', 'data-action="live#action"', 'data-live-action-param'] as $contract) {
            self::assertStringContainsString($contract, $itemForm);
        }

        $product = $this->contents('shop/product.html.twig');
        foreach (['localized_page_routes()', 'product_review_aggregate_rating(product)', '<twig:marketing:ProductReviews'] as $contract) {
            self::assertStringContainsString($contract, $product);
        }

        self::assertStringContainsString("component('modal:SimpleModalProductReviews')", $this->contents('base.html.twig'));
    }

    public function testReviewTemplatesPreserveLiveAndFormHooks(): void
    {
        $reviewForm = $this->contents('components/marketing/ProductReviewForm.html.twig');
        foreach (['{{ attributes.defaults', 'live#action:prevent', 'submitReview', 'norender|*', 'data-loading', 'form_rest(form)'] as $contract) {
            self::assertStringContainsString($contract, $reviewForm);
        }

        $reviews = $this->contents('components/marketing/ProductReviews.html.twig');
        foreach (['{{ attributes.defaults', 'data-turbo-frame="_top"', 'previousPage', 'nextPage', 'data-loading', 'knp_pagination_render'] as $contract) {
            self::assertStringContainsString($contract, $reviews);
        }

        $modal = $this->contents('components/modal/SimpleModalProductReviews.html.twig');
        foreach (['{{ attributes }}', 'role="dialog"', 'aria-modal="true"', 'data-live-action-param="close"', "component('marketing:ProductReviews'"] as $contract) {
            self::assertStringContainsString($contract, $modal);
        }

        $optOut = $this->contents('components/marketing/ReviewSolicitationOptOut.html.twig');
        foreach (['{{ attributes.defaults', 'confirmOptOut', 'data-loading'] as $contract) {
            self::assertStringContainsString($contract, $optOut);
        }

        foreach (['invitation', 'opt_out', 'policy', 'report'] as $page) {
            $pageContents = $this->contents('marketing/review/'.$page.'.html.twig');
            self::assertStringContainsString("component('announcement:Banner')", $pageContents, $page);
        }

        self::assertStringNotContainsString("'submit'|trans({}, 'form')", $reviewForm);
    }

    public function testWithdrawalFieldsAreVisibleInEveryRelevantView(): void
    {
        foreach (['withdrawal/index.html.twig', 'withdrawal/success.html.twig', 'mail/_withdrawal_summary.html.twig'] as $template) {
            $contents = $this->contents($template);
            self::assertStringContainsString('reasonCode', $contents, $template);
            self::assertStringContainsString('comment', $contents, $template);
        }
    }

    public function testAgeGateAndNotFoundPageUseTheThemeContracts(): void
    {
        $ageGate = $this->contents('components/site/AgeGate.html.twig');
        foreach (['{{ attributes }}', 'data-controller="age-gate"', 'data-model="countryCode"', 'data-model="norender|birthYear"', 'validateAge', 'data-loading'] as $contract) {
            self::assertStringContainsString($contract, $ageGate);
        }

        $notFound = $this->contents('bundles/TwigBundle/Exception/error404.html.twig');
        foreach (['noindex,follow', 'viti_theme().name', "encore_entry_link_tags('app'", 'encore_entry_link_tags(theme_entry', "path('homepage')"] as $contract) {
            self::assertStringContainsString($contract, $notFound);
        }
    }

    public function testPublicPagesUseLocalizedSeoAndGenericStructuredData(): void
    {
        foreach (['homepage.html.twig', 'home.html.twig', 'cuvees.html.twig', 'contact.html.twig'] as $template) {
            self::assertStringContainsString("include('partials/seo.html.twig'", $this->contents($template), $template);
        }

        $head = $this->contents('partials/head.html.twig');
        self::assertSame(1, substr_count($head, "component('seo:SiteStructuredData'"));
        self::assertStringNotContainsString('simple_seo_pages', $head);
    }

    private function contents(string $relativePath): string
    {
        $path = self::TEMPLATES.'/'.$relativePath;
        self::assertFileExists($path);
        $contents = file_get_contents($path);
        self::assertIsString($contents);

        return $contents;
    }
}
