<?php

/*
 * 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\Twig;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Component\Translation\Loader\ArrayLoader;
use Symfony\Component\Translation\Translator;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Twig\TwigFilter;
use Twig\TwigFunction;

final class OrderDocumentPriceGroupTemplateTest extends TestCase
{
    /**
     * @return iterable<string, array{string, string}>
     */
    public static function documentProvider(): iterable
    {
        yield 'bon de commande' => ['pdf/order.html.twig', 'checkout_design.document_order'];
        yield 'facture' => ['pdf/invoice.html.twig', 'checkout_design.document_invoice'];
    }

    #[DataProvider('documentProvider')]
    public function testDocumentDisplaysAppliedPriceGroupWithoutPartnerCode(
        string $template,
        string $documentLabelKey,
    ): void {
        $html = $this->renderDocument($template, $documentLabelKey, null);

        self::assertStringContainsString('Groupe tarifaire', $html);
        self::assertStringContainsString('Club Clients', $html);
        self::assertStringNotContainsString('Code partenaire', $html);
    }

    #[DataProvider('documentProvider')]
    public function testDocumentDisplaysPartnerCodeSeparatelyFromAppliedPriceGroup(
        string $template,
        string $documentLabelKey,
    ): void {
        $html = $this->renderDocument($template, $documentLabelKey, 'PARTENAIRE-42');

        self::assertStringContainsString('Groupe tarifaire', $html);
        self::assertStringContainsString('Club Clients', $html);
        self::assertStringContainsString('Code partenaire', $html);
        self::assertStringContainsString('PARTENAIRE-42', $html);
    }

    private function renderDocument(
        string $template,
        string $documentLabelKey,
        ?string $partnerCode,
    ): string {
        return $this->twig()->render($template, [
            'contact' => $this->contact(),
            'cart' => new OrderDocumentCartViewStub(
                pricing: [
                    'lines' => [],
                    'degressiveTTC' => 0,
                    'degressiveIsBottleOffered' => false,
                    'subtotalTTC' => 0,
                    'totalTax' => 0,
                    'totalTTC' => 0,
                    'priceGroupName' => 'Club Clients',
                ],
                groupCode: $partnerCode,
                documentLabelKey: $documentLabelKey,
            ),
            'admin' => true,
            'document_label' => 'Document test',
            'invoice_context' => $this->invoiceContext(),
            'credit_context' => null,
            'credit_only' => false,
        ]);
    }

    private function twig(): Environment
    {
        $resourcesDirectory = \dirname(__DIR__, 2).'/src/Bridge/Symfony/Bundle/Resources';
        $translator = new Translator('fr');
        $translator->addLoader('array', new ArrayLoader());
        $translator->addResource('array', [
            'order.price_group' => 'Groupe tarifaire',
            'order.partner_code' => 'Code partenaire',
        ], 'fr', 'messages');

        $twig = new Environment(new FilesystemLoader($resourcesDirectory.'/views'));
        $twig->addExtension(new TranslationExtension($translator));
        $twig->addFunction(new TwigFunction('asset', static fn (string $path): string => $path));
        $twig->addFunction(new TwigFunction('absolute_url', static fn (string $path): string => $path));

        foreach (['country_name', 'country_name_alpha3', 'imagine_filter', 'price_format'] as $filter) {
            $twig->addFilter(new TwigFilter(
                $filter,
                static fn (mixed $value, mixed ...$arguments): mixed => $value,
            ));
        }

        return $twig;
    }

    /**
     * @return array<string, mixed>
     */
    private function contact(): array
    {
        return [
            'image' => null,
            'company' => 'Domaine Test',
            'firstname' => null,
            'lastname' => null,
            'address' => '1 rue de Test',
            'postal' => '51100',
            'city' => 'Reims',
            'phone1' => '0102030405',
            'phone2' => null,
            'emailFrom' => 'contact@example.test',
            'emailToShop' => 'boutique@example.test',
            'editorCompany' => null,
            'editorAddress' => null,
            'editorPostal' => null,
            'editorCity' => null,
            'editorTva' => null,
            'editorRcs' => null,
        ];
    }

    /**
     * @return array<string, mixed>
     */
    private function invoiceContext(): array
    {
        $documentDate = new \DateTimeImmutable('2026-08-27 10:00:00');

        return [
            'invoice_number' => 'FAC-TEST',
            'invoice_date' => $documentDate,
            'order_date' => $documentDate,
            'payment_due_at' => null,
            'payment_method_label' => null,
            'payment_paid_at' => null,
            'payment_term_label' => null,
            'product_tax' => 0,
            'product_tax_rate_label' => null,
            'product_total_ht' => 0,
            'product_total_ht_before_promos' => 0,
            'product_total_ttc' => 0,
            'promo_item_discounts' => [],
            'promo_shipping_discounts' => [],
            'shipping_ht' => 0,
            'shipping_ht_before_promos' => 0,
            'shipping_tax' => 0,
            'shipping_tax_rate_label' => null,
            'shipping_ttc' => 0,
            'total_tax_rate_label' => null,
        ];
    }
}

final class OrderDocumentCartViewStub
{
    public readonly null $invoiceAddress;
    public readonly null $deliveryAddress;
    public readonly null $cartShipping;
    public readonly null $cartCheckout;
    public readonly null $paymentMethod;
    public readonly null $deliveryMethod;
    public readonly null $comment;
    public readonly string $locale;
    public readonly string $token;
    public readonly \DateTimeImmutable $createdAt;

    /**
     * @param array<string, mixed> $pricing
     */
    public function __construct(
        private readonly array $pricing,
        public readonly ?string $groupCode,
        private readonly string $documentLabelKey,
    ) {
        $this->invoiceAddress = null;
        $this->deliveryAddress = null;
        $this->cartShipping = null;
        $this->cartCheckout = null;
        $this->paymentMethod = null;
        $this->deliveryMethod = null;
        $this->comment = null;
        $this->locale = 'fr';
        $this->token = 'CMD-TEST';
        $this->createdAt = new \DateTimeImmutable('2026-08-27 10:00:00');
    }

    /**
     * @return array<string, mixed>
     */
    public function getPricing(): array
    {
        return $this->pricing;
    }

    public function getDocumentLabelKey(): string
    {
        return $this->documentLabelKey;
    }
}
