<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Tests\Twig;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Twig\Components\Marketing\ProductReviewForm;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Yaml\Yaml;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveProp;

final class ProductReviewFormComponentTest extends TestCase
{
    public function testComponentExposesAStableLiveAndTemplateOverrideContract(): void
    {
        $reflection = new \ReflectionClass(ProductReviewForm::class);
        $componentAttribute = $reflection->getAttributes(AsLiveComponent::class)[0]->newInstance();
        $config = $componentAttribute->serviceConfig();

        self::assertSame('marketing:ProductReviewForm', $config['key']);
        self::assertSame('@components/marketing/ProductReviewForm.html.twig', $config['template']);
        self::assertTrue($config['live']);
        self::assertNotEmpty($reflection->getProperty('token')->getAttributes(LiveProp::class));
        self::assertNotEmpty($reflection->getProperty('saved')->getAttributes(LiveProp::class));
        self::assertNotEmpty($reflection->getProperty('template')->getAttributes(LiveProp::class));
        self::assertNotEmpty($reflection->getMethod('submitReview')->getAttributes(LiveAction::class));
    }

    public function testDefaultViewKeepsAllLiveFormHooks(): void
    {
        $template = file_get_contents(
            __DIR__ . '/../../src/Bridge/Symfony/Bundle/Resources/views/components/marketing/ProductReviewForm.html.twig',
        );

        self::assertIsString($template);
        self::assertStringContainsString('{{ attributes.defaults(', $template);
        self::assertStringContainsString("'data-action': 'live#action:prevent'", $template);
        self::assertStringContainsString("'data-live-action-param': 'submitReview'", $template);
        self::assertStringContainsString("'data-model': 'norender|*'", $template);
        self::assertStringContainsString('marketing.review.form.saved_next', $template);
        self::assertStringContainsString('data-loading="addAttribute(disabled)"', $template);
        self::assertStringNotContainsString('data-loading="show"', $template);
        self::assertStringNotContainsString('data-loading="hide"', $template);
        self::assertStringNotContainsString('form.title', $template);
        self::assertStringContainsString('form_rest(form)', $template);
    }

    public function testSuccessfulSubmissionUsesTheNotifierAndAContinuationMessage(): void
    {
        $component = file_get_contents(
            __DIR__ . '/../../src/Bridge/Symfony/Bundle/Twig/Components/Marketing/ProductReviewForm.php',
        );

        self::assertIsString($component);
        self::assertStringContainsString('new NotificationCommand(', $component);
        self::assertStringContainsString('PushLevel::SUCCESS', $component);
        self::assertStringContainsString('PushLevel::ERROR', $component);
        self::assertStringContainsString('PushTransport::MERCURE', $component);
        self::assertStringContainsString("'marketing.review.form.saved_next'", $component);
        self::assertStringContainsString("'marketing.review.form.invalid'", $component);
    }

    public function testContinuationMessageIsTranslatedInEverySupportedLocale(): void
    {
        foreach (['de', 'en', 'es', 'fr', 'it', 'nl'] as $locale) {
            $messages = Yaml::parseFile(sprintf(
                '%s/../../src/Bridge/Symfony/Bundle/Resources/translations/messages.%s.yaml',
                __DIR__,
                $locale,
            ));

            self::assertIsArray($messages);
            self::assertNotEmpty(
                $messages['marketing']['review']['form']['saved_next'] ?? null,
                sprintf('La traduction saved_next est absente pour la locale %s.', $locale),
            );
            self::assertNotEmpty(
                $messages['marketing']['review']['form']['invalid'] ?? null,
                sprintf('La traduction invalid est absente pour la locale %s.', $locale),
            );
        }
    }
}
