<?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\Bridge\Symfony\Bundle\Seed;

use CpCreation\VitiCore\Contact\Model\Contact;
use CpCreation\VitiCore\Locale\Model\Locale;
use CpCreation\VitiCore\Product\Model\ProductCategory;
use CpCreation\VitiCore\Product\Model\ProductCollection;
use CpCreation\VitiCore\Product\Model\ProductPriceGroup;
use CpCreation\VitiCore\Product\Model\ProductTax;
use CpCreation\VitiCore\Product\Model\ProductType;
use CpCreation\VitiCore\Product\Model\Translation\ProductCategoryTranslation;
use CpCreation\VitiCore\Product\Model\Translation\ProductTypeTranslation;
use CpCreation\VitiCore\Seed\SeederInterface;
use CpCreation\VitiCore\Seed\SeedPayload;
use CpCreation\VitiCore\Shop\Model\ShippingConfig;
use CpCreation\VitiCore\Shop\Model\ShippingCountry;
use CpCreation\VitiCore\Shop\Model\ShippingCounty;
use CpCreation\VitiCore\Shop\Model\ShippingPrice;
use CpCreation\VitiCore\Shop\Model\ShippingZone;
use CpCreation\VitiCore\Shop\Model\ShopConfig;
use CpCreation\VitiCore\Shop\Model\Translation\ShippingConfigTranslation;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\Attribute\AsTaggedItem;

#[AsTaggedItem(index: 'core', priority: 100)]
class CoreSeed implements SeederInterface
{
    public function __construct(private EntityManagerInterface $entityManager) {}

    public function isEnabled(): bool
    {
        return true;
    }

    /** Version cible (monotone croissante) */
    public function version(): int
    {
        return 5;
    }

    /**
     * Applique les deltas depuis $fromVersion (0..n) -> targetVersion.
     * Doit être idempotent (upsert) et ne pas écraser les modifs user.
     */
    public function seed(SeedPayload $seedPayload, int $fromVersion): void
    {
        for ($version = $fromVersion + 1; $version <= $this->version(); ++$version) {
            $method = 'v' . $version;

            if (!method_exists($this, $method)) {
                throw new \LogicException(\sprintf('Missing seed step method "%s" for "%s".', $method, static::class));
            }

            $this->{$method}();
        }
    }

    private function v1(): void
    {
        $group = $this->entityManager->getRepository(ProductPriceGroup::class)->findOneBy([
            'name' => 'Public',
        ]);

        if (!$group instanceof ProductPriceGroup) {
            $group = new ProductPriceGroup();
            $group->setName('Public');
            $group->setByDefault(true);
            $this->entityManager->persist($group);
        }

        $lang = $this->entityManager->getRepository(Locale::class)->findOneBy([
            'locale' => 'en',
        ]);

        if (!$lang instanceof Locale) {
            $lang = new Locale();
            $lang->setName('Anglais');
            $lang->setLocale('en');
            $this->entityManager->persist($lang);
        }

        $tax = $this->entityManager->getRepository(ProductTax::class)->findOneBy([
            'name' => 'TVA 20%',
        ]);

        if (!$tax instanceof ProductTax) {
            $tax = new ProductTax();
            $tax->setName('TVA 20%');
            $tax->setByDefault(true);
            $tax->setInPro(true);
            $tax->setInCustomer(true);
            $tax->setOutCustomer(true);
            $tax->setOutPro(true);
            $tax->setValue(0.2);
            $this->entityManager->persist($tax);
        }

        $shopConfig = $this->entityManager->getRepository(ShopConfig::class)->findOneBy([]);
        if (!$shopConfig instanceof ShopConfig) {
            $shopConfig = new ShopConfig();
            $shopConfig->setEnableProductPageFront(true);
            $this->entityManager->persist($shopConfig);
        }

        $contact = $this->entityManager->getRepository(Contact::class)->findOneBy([]);
        if (!$contact instanceof Contact) {
            $contact = new Contact();
            $contact->setCgv($this->defaultCgvContent());
            $contact->setCity('Epernay');
            $contact->setAddress('Rue de la mairie');
            $contact->setCompany('SAS Champagne');
            $contact->setPostal('51200');
            $contact->setCity('Epernay');
            $contact->setFirstname('Bertrand');
            $contact->setLastname('Girard');
            $contact->setPhone1('0123456789');
            $contact->setEmailFrom('web@cpcreation.fr');
            $contact->setEmailToMessage('web@cpcreation.fr');
            $contact->setEmailToShop('web@cpcreation.fr');
            $contact->setEditorAddress('Rue de la mairie');
            $contact->setEditorCity('Epernay');
            $contact->setEditorCompany('SAS Champagne');
            $contact->setEditorPostal('51200');
            $contact->setEditorRcs('888888888');
            $contact->setEditorTva('FR8888888888');
            $contact->setCommitteeChampagneIdentifiant('FR246127_01QEKR');
            $contact->setCommitteeChampagneSiret('SIRET 78038582900012');
            $contact->setLegalNoticeContent($this->defaultLegalNoticeContent());
            $contact->setPrivacyPolicyContent($this->defaultPrivacyPolicyContent());
            $this->entityManager->persist($contact);
        }

        $champagneCategory = $this->findProductCategoryByName('Champagne');
        if (!$champagneCategory instanceof ProductCategory) {
            $champagneCategory = new ProductCategory();

            $champagneCategoryFr = new ProductCategoryTranslation();
            $champagneCategoryFr->setLocale('fr');
            $champagneCategoryFr->setName('Champagne');
            $champagneCategory->addTranslation($champagneCategoryFr);

            $champagneCategoryEn = new ProductCategoryTranslation();
            $champagneCategoryEn->setLocale('en');
            $champagneCategoryEn->setName('Champagne');
            $champagneCategory->addTranslation($champagneCategoryEn);

            $this->entityManager->persist($champagneCategory);
        }

        // Demi-Bouteille
        $typeHalfBottle = $this->findProductTypeByName('Demi-Bouteille');
        if (!$typeHalfBottle instanceof ProductType) {
            $typeHalfBottle = new ProductType();
            $typeHalfBottle->setCode('DEMI-BOUTEILLE');
            $typeHalfBottleFr = new ProductTypeTranslation();
            $typeHalfBottleFr->setLocale('fr');
            $typeHalfBottleFr->setName('Demi-Bouteille');
            $typeHalfBottle->addTranslation($typeHalfBottleFr);
            $typeHalfBottleEn = new ProductTypeTranslation();
            $typeHalfBottleEn->setLocale('en');
            $typeHalfBottleEn->setName('Half-bottle');
            $typeHalfBottle->addTranslation($typeHalfBottleEn);
            $typeHalfBottle->setVolume(37.5);
            $typeHalfBottle->setUnity('cl');
            $typeHalfBottle->setMultipleQuantityCart(6);
            $typeHalfBottle->setEquivalency(0.5);
            $typeHalfBottle->setEquivalencyManu(0.5);
            $typeHalfBottle->setEquivalencyDegressive(0.5);
            $typeHalfBottle->setEquivalencyFreeShipping(0.5);
            $typeHalfBottle->setEquivalencyOnShipping(true);
            $typeHalfBottle->setEquivalencyOnFreeShipping(true);
            $this->entityManager->persist($typeHalfBottle);
        }

        // Bouteille
        $typeBottle = $this->findProductTypeByName('Bouteille');
        if (!$typeBottle instanceof ProductType) {
            $typeBottle = new ProductType();
            $typeBottle->setCode('BOUTEILLE');
            $typeBottleFr = new ProductTypeTranslation();
            $typeBottleFr->setLocale('fr');
            $typeBottleFr->setName('Bouteille');
            $typeBottle->addTranslation($typeBottleFr);
            $typeBottleEn = new ProductTypeTranslation();
            $typeBottleEn->setLocale('en');
            $typeBottleEn->setName('Bottle');
            $typeBottle->addTranslation($typeBottleEn);
            $typeBottle->setEquivalencyDefault(true);
            $typeBottle->setVolume(75);
            $typeBottle->setUnity('cl');
            $typeBottle->setMultipleQuantityCart(1);
            $typeBottle->setEquivalency(1);
            $typeBottle->setEquivalencyManu(1);
            $typeBottle->setEquivalencyDegressive(1);
            $typeBottle->setEquivalencyFreeShipping(1);
            $typeBottle->setOrderWithaMinimumEquivalency(6);
            $typeBottle->setEquivalencyOnShipping(true);
            $typeBottle->setEquivalencyOnFreeShipping(true);
            $this->entityManager->persist($typeBottle);
        }

        // Magnum
        $typeMagnum = $this->findProductTypeByName('Magnum');
        if (!$typeMagnum instanceof ProductType) {
            $typeMagnum = new ProductType();
            $typeMagnum->setCode('MAGNUM');
            $typeMagnumFr = new ProductTypeTranslation();
            $typeMagnumFr->setLocale('fr');
            $typeMagnumFr->setName('Magnum');
            $typeMagnum->addTranslation($typeMagnumFr);
            $typeMagnumEn = new ProductTypeTranslation();
            $typeMagnumEn->setLocale('en');
            $typeMagnumEn->setName('Magnum');
            $typeMagnum->addTranslation($typeMagnumEn);
            $typeMagnum->setVolume(1.5);
            $typeMagnum->setUnity('L');
            $typeMagnum->setMultipleQuantityCart(1);
            $typeMagnum->setEquivalency(2);
            $typeMagnum->setEquivalencyManu(2);
            $typeMagnum->setEquivalencyDegressive(2);
            $typeMagnum->setEquivalencyFreeShipping(2);
            $typeMagnum->setEquivalencyOnShipping(true);
            $typeMagnum->setEquivalencyOnFreeShipping(true);
            $this->entityManager->persist($typeMagnum);
        }

        // Jéro
        $typeJero = $this->findProductTypeByName('Jeroboam');
        if (!$typeJero instanceof ProductType) {
            $typeJero = new ProductType();
            $typeJero->setCode('JEROBOAM');
            $typeJeroFr = new ProductTypeTranslation();
            $typeJeroFr->setLocale('fr');
            $typeJeroFr->setName('Jeroboam');
            $typeJero->addTranslation($typeJeroFr);
            $typeJeroEn = new ProductTypeTranslation();
            $typeJeroEn->setLocale('en');
            $typeJeroEn->setName('Jeroboam');
            $typeJero->addTranslation($typeJeroEn);
            $typeJero->setVolume(3);
            $typeJero->setUnity('L');
            $typeJero->setMultipleQuantityCart(1);
            $typeJero->setEquivalency(4);
            $typeJero->setEquivalencyManu(4);
            $typeJero->setEquivalencyDegressive(4);
            $typeJero->setEquivalencyFreeShipping(4);
            $typeJero->setEquivalencyOnShipping(true);
            $typeJero->setEquivalencyOnFreeShipping(true);
            $this->entityManager->persist($typeJero);
        }

        foreach ($this->shippingCountriesData() as $code => $config) {
            $country = $this->entityManager->getRepository(ShippingCountry::class)->findOneBy([
                'code' => $code,
            ]);

            if (!$country instanceof ShippingCountry) {
                $country = new ShippingCountry();
                $country->setCode($code);
                $this->entityManager->persist($country);
            }

            $country->setCounty($config['county']);
            $country->setDisabled($config['disabled']);

            if (!$country->getGroups()->contains($group)) {
                $country->addGroup($group);
            }
        }

        foreach ($this->shippingCountiesData() as $code) {
            $county = $this->entityManager->getRepository(ShippingCounty::class)->findOneBy([
                'code' => $code,
            ]);

            if ($county instanceof ShippingCounty) {
                continue;
            }

            $county = new ShippingCounty();
            $county->setCode($code);
            $this->entityManager->persist($county);
        }

        foreach ($this->shippingZonesData() as $name => $config) {
            $zone = $this->entityManager->getRepository(ShippingZone::class)->findOneBy([
                'name' => $name,
            ]);

            if (!$zone instanceof ShippingZone) {
                $zone = new ShippingZone();
                $zone->setName($name);
                $this->entityManager->persist($zone);
            }

            foreach ($config['countries'] as $countryCode) {
                $country = $this->entityManager->getRepository(ShippingCountry::class)->findOneBy([
                    'code' => $countryCode,
                ]);

                if ($country instanceof ShippingCountry) {
                    $zone->addCountry($country);
                }
            }

            foreach ($config['counties'] as $countyCode) {
                $county = $this->entityManager->getRepository(ShippingCounty::class)->findOneBy([
                    'code' => $countyCode,
                ]);

                if ($county instanceof ShippingCounty) {
                    $zone->addCounty($county);
                }
            }
        }

        foreach ($this->shippingPricesData() as $config) {
            $shippingPrice = $this->entityManager->getRepository(ShippingPrice::class)->findOneBy([
                'qtyOf' => $config['qtyOf'],
                'qtyAt' => $config['qtyAt'],
                'packagePrice' => $config['packagePrice'],
                'nameCarrier' => $config['nameCarrier'],
                'deliveryMethod' => null,
            ]);

            if (!$shippingPrice instanceof ShippingPrice) {
                $shippingPrice = new ShippingPrice();
                $shippingPrice->setQtyOf($config['qtyOf']);
                $shippingPrice->setQtyAt($config['qtyAt']);
                $shippingPrice->setPackagePrice($config['packagePrice']);
                $shippingPrice->setNameCarrier($config['nameCarrier']);
                $this->entityManager->persist($shippingPrice);
            }

            if (!$shippingPrice->getTypes()->contains($typeBottle)) {
                $shippingPrice->addType($typeBottle);
            }

            if (!$shippingPrice->getGroups()->contains($group)) {
                $shippingPrice->addGroup($group);
            }

            foreach ($config['zones'] as $zoneName) {
                $zone = $this->entityManager->getRepository(ShippingZone::class)->findOneBy([
                    'name' => $zoneName,
                ]);

                if ($zone instanceof ShippingZone && !$shippingPrice->getZones()->contains($zone)) {
                    $shippingPrice->addZone($zone);
                }
            }
        }
    }

    private function v2(): void
    {
        $this->seedLegalContents();
    }

    private function v3(): void
    {
        $this->seedLegalContents();
    }

    private function v4(): void
    {
        $shippingConfig = $this->entityManager->getRepository(ShippingConfig::class)->findOneBy([]);

        if (!$shippingConfig instanceof ShippingConfig) {
            $shippingConfig = new ShippingConfig();
            $shippingConfig->setAmountMinVDManu(1000);
            $shippingConfig->setMarginManu(0.02);
            $shippingConfig->setTvaManu(0.2);
            $this->entityManager->persist($shippingConfig);
        }

        $this->seedShippingText(
            $shippingConfig,
            'fr',
            'Livraison dans un délai de 15 jours maximum.',
        );
        $this->seedShippingText(
            $shippingConfig,
            'en',
            'Delivery within 15 days maximum.',
        );
    }

    private function v5(): void
    {
        $collection = $this->entityManager->getRepository(ProductCollection::class)->findOneBy([
            'code' => 'champagnes',
        ]);

        if ($collection instanceof ProductCollection) {
            return;
        }

        $collection = new ProductCollection();
        $collection->setName('Nos champagnes');
        $collection->setCode('champagnes');
        $collection->setMode(ProductCollection::MODE_MANUAL);
        $this->entityManager->persist($collection);
    }

    private function seedShippingText(ShippingConfig $shippingConfig, string $locale, string $defaultText): void
    {
        $translation = $shippingConfig->translate($locale);

        if (!$translation instanceof ShippingConfigTranslation) {
            throw new \LogicException(\sprintf('Unexpected shipping configuration translation for locale "%s".', $locale));
        }

        if ('' === mb_trim((string) $translation->getShippingText())) {
            $translation->setShippingText($defaultText);
        }
    }

    private function seedLegalContents(): void
    {
        $contact = $this->entityManager->getRepository(Contact::class)->findOneBy([]);

        if (!$contact instanceof Contact) {
            return;
        }

        if ('' === mb_trim((string) $contact->getCgv())) {
            $contact->setCgv($this->defaultCgvContent());
        }

        if ('' === mb_trim((string) $contact->getLegalNoticeContent())) {
            $contact->setLegalNoticeContent($this->defaultLegalNoticeContent());
        }

        if ('' === mb_trim((string) $contact->getPrivacyPolicyContent())) {
            $contact->setPrivacyPolicyContent($this->defaultPrivacyPolicyContent());
        }
    }

    private function defaultCgvContent(): string
    {
        return <<<'HTML'
            <p><b>Article 1 : Champ d'application</b></p>
            <p>Toutes nos ventes sont régies par les présentes conditions générales de vente qui prévalent sur toute condition d'achat, sauf stipulation dérogatoire expresse.</p>
            <p><b>Article 2 : Prix</b></p>
            <p>Les prix applicables sont ceux en vigueur au jour de la prise de commande, et figurent sur le barème ci-contre, libellés en euros.</p>
            <p>Ils s'entendent « départ cellier », le transport étant à la charge de l'acheteur.</p>
            <p>Sauf accord entre les parties, le règlement s'effectue à la commande.</p>
            <p>Si un délai est accordé, aucun escompte ne sera consenti en cas de paiement anticipé.</p>
            <p>Tout règlement intervenant après la date de paiement figurant sur la facture entraînera le paiement de pénalités de retard dont le montant est égal à trois fois le taux de l'intérêt légal. Ces pénalités sont exigibles sans qu'un rappel soit nécessaire. En outre, l'ensemble des frais de mise en recouvrement seront mis à la charge de l'acheteur.</p>
            <p>En application des dispositions légales, tout professionnel en situation de retard de paiement sera débiteur à l'égard du créancier d'une indemnité forfaitaire de 40 € pour frais de recouvrement. Toutefois, si les frais de recouvrement sont supérieurs au montant de cette indemnité, le créancier pourra demander une indemnisation supplémentaire, sur justification.</p>
            <p><b>Article 3 : Droit de rétractation</b></p>
            <p>– Si le client est un professionnel : aucun droit de rétractation ne lui est accordé, sous réserve des dispositions légales impératives applicables.</p>
            <p>– Si le client est un consommateur particulier</p>
            <p>Conformément à la directive 2011/83/UE du Parlement européen et du Conseil du 25 octobre 2011 relative aux droits des consommateurs, telle que modifiée par la directive (UE) 2023/2673 du 22 novembre 2023, et aux articles L. 221-18 et suivants du Code de la consommation, le client dispose, sauf exception légale, d'un délai de quatorze jours à compter de la réception des vins pour exercer son droit de rétractation, sans avoir à motiver sa décision.</p>
            <p>Le client peut exercer ce droit en remplissant le <a href="/droit-de-retractation">formulaire de rétractation en ligne</a> ou en adressant au viticulteur, avant l'expiration du délai, toute autre déclaration dénuée d'ambiguïté exprimant sa volonté de se rétracter. L'utilisation du formulaire en ligne n'est pas obligatoire.</p>
            <p>Le client doit renvoyer les biens à l'adresse de l'exploitation sans retard excessif et, au plus tard, dans les quatorze jours suivant la communication de sa décision de se rétracter. Les frais directs de renvoi des biens restent à sa charge.</p>
            <p>Le viticulteur rembourse la totalité des sommes versées, y compris les frais de livraison standard, sans retard injustifié et au plus tard dans les quatorze jours à compter de la date à laquelle il est informé de la décision de rétractation. Il peut différer ce remboursement jusqu'à la récupération des biens ou jusqu'à la réception d'une preuve de leur expédition, la date retenue étant celle du premier de ces faits.</p>
            <p>Le remboursement est effectué avec le même moyen de paiement que celui utilisé pour la transaction initiale, sauf accord exprès du client pour un autre moyen, et n'occasionne aucuns frais pour le client. Les frais supplémentaires liés au choix exprès d'un mode de livraison plus coûteux que la livraison standard ne sont pas remboursés.</p>
            <p>La responsabilité du client ne peut être engagée qu'en cas de dépréciation des biens résultant de manipulations autres que celles nécessaires pour établir leur nature, leurs caractéristiques et leur bon fonctionnement.</p>
            <p>Le droit de rétractation ne s'applique pas dans les cas prévus par l'article L. 221-28 du Code de la consommation, notamment aux boissons alcoolisées dont la livraison est différée au-delà de trente jours et dont la valeur convenue à la conclusion du contrat dépend de fluctuations du marché échappant au contrôle du professionnel.</p>
            <p>– Si la vente a été conclue sur une foire ou un salon : le client ne dispose d'aucun droit de rétractation.</p>
            <p><b>Article 4 : Réserve de propriété</b></p>
            <p>Le vendeur conserve la propriété des biens vendus jusqu'à complet paiement du prix par le client, en principal et accessoires. Toutefois, dès la livraison, les risques de perte ou de détérioration sont transférés à l'acheteur.</p>
            <p><b>Article 5 : Livraison</b></p>
            <p>La livraison est effectuée :</p>
            <p>– soit par la remise directe de la marchandise à l'acheteur</p>
            <p>– soit au lieu indiqué par l'acheteur sur le bon de commande.</p>
            <p>Nos vins voyagent aux risques et périls du destinataire, même en cas d'expédition franco. Le vendeur ne pourra être tenu pour responsable en cas d'avarie, de perte, de vol ou de colis défectueux. En conséquence, les clients sont invités à vérifier les colis à leur réception et à notifier toute réserve au transporteur, par lettre recommandée, dans les trois jours ouvrables qui suivent la réception de la marchandise.</p>
            <p><b>Article 6 : Litiges</b></p>
            <p>Nos ventes sont soumises à la législation française.</p>
            <p>Il est expressément attribué compétence au tribunal de grande instance du domicile du vendeur.</p>
            <p></p>
            HTML;
    }

    private function defaultLegalNoticeContent(): string
    {
        return <<<'HTML'
            <h2>Édition du site internet</h2>
            <ul>
                <li>Concepteur : SAS CP Création au capital de 375 000 €, 43 rue des Forges 51200 Épernay, RCS Reims B 392 267 977, TVA intra : FR40 392 267 977</li>
                <li>Éditeur : {{ contact.editorCompany }} - {{ contact.editorFullAddress }} - RCS : {{ contact.editorRcs }} - TVA intra. : {{ contact.editorTva }}</li>
                <li>Directeur de publication : {{ contact.companyUpper }}</li>
                <li>Responsable des mises à jour du contenu éditorial : {{ contact.companyUpper }}</li>
            </ul>
            <h2>Hébergement du site</h2>
            <p>L'hébergement du site est réalisé par la société OVH.<br>SAS OVH<br>2 rue Kellermann, BP 80157, 59053 Roubaix Cedex 1, France<br>Tél : 1007<br>Site : https://www.ovh.com</p>
            <h2>Propriétés intellectuelles</h2>
            <p>Les contenus éditoriaux et visuels du présent site, notamment les textes, photographies, visuels, logos, marques et documents relatifs à l’activité de l’éditeur, sont la propriété de l’éditeur du site ou font l’objet d’un droit d’utilisation régulier. Le développement du site, son intégration, son architecture technique, ainsi que le socle logiciel et les outils propriétaires utilisés dans le cadre de sa conception et de son fonctionnement, demeurent la propriété de CP Création, sauf stipulation contraire expresse et écrite. Toute reproduction, représentation, diffusion, adaptation ou exploitation, totale ou partielle, de tout ou partie du site, sans autorisation préalable écrite du titulaire des droits concerné, est interdite.</p>
            <h2>Informations et exclusion</h2>
            <p>{{ contact.companyUpper }} met en œuvre tous les moyens raisonnables à sa disposition pour assurer l’exactitude et la mise à jour des informations diffusées sur le présent site. Toutefois, des erreurs, omissions ou inexactitudes peuvent subsister. L’utilisateur est invité à vérifier toute information utile directement auprès de {{ contact.company }}, et à signaler toute anomalie ou correction qui lui semblerait nécessaire.</p>
            <h2>Données personnelles</h2>
            <p>Le présent site utilise des cookies et autres traceurs susceptibles d’être déposés sur le terminal de l’utilisateur, notamment à des fins de mesure d’audience, de fonctionnement du site et d’amélioration des services proposés. Pour en savoir plus sur l’utilisation des cookies et sur vos droits, consultez la politique de confidentialité du site.</p>
            HTML;
    }

    private function defaultPrivacyPolicyContent(): string
    {
        return <<<'HTML'
            <h2>Introduction</h2>
            <p>Nous nous soucions de la vie privée des utilisateurs de notre site Internet et nous nous engageons à protéger les informations partagées avec nous lorsqu'ils utilisent notre site.<br>Cette politique de confidentialité décrit nos pratiques en matière de recueil, d'utilisation et de divulgation de vos informations lorsque vous accédez à nos services.</p>
            <h2>Les informations que nous recueillons</h2>
            <p>Nous recueillons des informations non identifiées et non identifiables, composées principalement d'informations techniques et d'utilisation agrégées. Nous pouvons également recueillir des informations personnelles permettant de vous identifier lorsque cela est nécessaire au traitement de vos demandes.</p>
            <h2>Comment nous recueillons les informations</h2>
            <p>Nous recueillons des informations lorsque vous utilisez les services, visitez nos propriétés numériques ou nous fournissez volontairement des informations, par exemple via un formulaire de contact.</p>
            <h2>Pourquoi nous recueillons les informations</h2>
            <p>Nous recueillons ces informations pour exploiter, sécuriser, personnaliser et améliorer nos services, répondre à vos demandes et respecter nos obligations légales.</p>
            <h2>Avec qui nous partageons les informations</h2>
            <p>Nous pouvons partager vos informations avec nos fournisseurs de services afin d'exploiter le site et les services associés. Nous ne cédons pas vos informations personnelles à des tiers à des fins publicitaires sans consentement.</p>
            <h2>Cookies</h2>
            <p>Lorsque vous visitez notre site, certains cookies ou traceurs peuvent être utilisés afin d'améliorer votre navigation, mesurer l'audience, assurer la sécurité du service ou prévenir la fraude.</p>
            <h2>Où sont stockées les informations</h2>
            <p>Les informations peuvent être stockées et traitées par nos partenaires et fournisseurs de services. Les informations personnelles sont conservées, traitées et stockées conformément à la réglementation applicable.</p>
            <h2>Combien de temps les informations sont conservées</h2>
            <p>Nous conservons les informations aussi longtemps que nécessaire pour fournir les services, répondre aux demandes, respecter nos obligations légales ou contractuelles et résoudre d'éventuels litiges.</p>
            <h2>Comment nous protégeons les informations</h2>
            <p>Nous mettons en œuvre des mesures techniques et organisationnelles raisonnables pour protéger les informations contre l'accès non autorisé, la perte, l'altération ou la divulgation.</p>
            <h2>Modifications ou mises à jour</h2>
            <p>Nous pouvons réviser cette politique de confidentialité à tout moment. La version la plus récente est toujours affichée sur le site.</p>
            <h2>Nous contacter</h2>
            <p>Pour toute question relative aux services ou aux informations recueillies, vous pouvez nous contacter à l'aide du formulaire de contact.</p>
            HTML;
    }

    /**
     * @return array<string, array{county: bool, disabled: bool}>
     */
    private function shippingCountriesData(): array
    {
        return [
            'DE' => ['county' => false, 'disabled' => true],
            'AT' => ['county' => false, 'disabled' => true],
            'BE' => ['county' => false, 'disabled' => true],
            'BG' => ['county' => false, 'disabled' => true],
            'CY' => ['county' => false, 'disabled' => true],
            'HR' => ['county' => false, 'disabled' => true],
            'DK' => ['county' => false, 'disabled' => true],
            'ES' => ['county' => false, 'disabled' => true],
            'EE' => ['county' => false, 'disabled' => true],
            'FI' => ['county' => false, 'disabled' => true],
            'FR' => ['county' => true, 'disabled' => false],
            'GR' => ['county' => false, 'disabled' => true],
            'HU' => ['county' => false, 'disabled' => true],
            'IE' => ['county' => false, 'disabled' => true],
            'IT' => ['county' => false, 'disabled' => true],
            'LV' => ['county' => false, 'disabled' => true],
            'LT' => ['county' => false, 'disabled' => true],
            'MT' => ['county' => false, 'disabled' => true],
            'LU' => ['county' => false, 'disabled' => true],
            'NL' => ['county' => false, 'disabled' => true],
            'PL' => ['county' => false, 'disabled' => true],
            'PT' => ['county' => false, 'disabled' => true],
            'CZ' => ['county' => false, 'disabled' => true],
            'RO' => ['county' => false, 'disabled' => true],
            'GB' => ['county' => false, 'disabled' => true],
            'SK' => ['county' => false, 'disabled' => true],
            'SI' => ['county' => false, 'disabled' => true],
            'SE' => ['county' => false, 'disabled' => true],
        ];
    }

    /**
     * @return list<string>
     */
    private function shippingCountiesData(): array
    {
        return [
            '01', '02', '03', '04', '05', '06', '07', '08', '09',
            '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20',
            '21', '22', '23', '24', '25', '26', '27', '28', '29',
            '30', '31', '32', '33', '34', '35', '36', '37', '38', '39',
            '40', '41', '42', '43', '44', '45', '46', '47', '48', '49',
            '50', '51', '52', '53', '54', '55', '56', '57', '58', '59',
            '60', '61', '62', '63', '64', '65', '66', '67', '68', '69',
            '70', '71', '72', '73', '74', '75', '76', '77', '78', '79',
            '80', '81', '82', '83', '84', '85', '86', '87', '88', '89',
            '90', '91', '92', '93', '94', '95', '98',
        ];
    }

    /**
     * @return array<string, array{countries: list<string>, counties: list<string>}>
     */
    private function shippingZonesData(): array
    {
        return [
            'Zone 1 - France' => [
                'countries' => ['FR'],
                'counties' => [
                    '02', '08', '10', '14', '18', '21', '25', '27', '28', '36', '37', '39', '41', '45',
                    '51', '52', '54', '55', '57', '58', '59', '60', '61', '62', '67', '68', '70', '71',
                    '72', '75', '76', '77', '78', '80', '88', '89', '90', '91', '92', '93', '94', '95',
                    '01', '03', '17', '12', '15', '16', '17', '19', '22', '23', '24', '26', '29', '33',
                    '35', '38', '42', '43', '44', '46', '47', '48', '49', '50', '53', '56', '63', '69',
                    '73', '74', '79', '85', '86', '87', '04', '05', '06', '07', '09', '11', '13', '30',
                    '31', '32', '34', '40', '64', '65', '66', '81', '82', '83', '84', '98',
                ],
            ],
            'Zone 2 - Corse - France' => [
                'countries' => ['FR'],
                'counties' => ['20'],
            ],
            'Belgique' => [
                'countries' => ['BE'],
                'counties' => [],
            ],
            'Zone 1 - UE' => [
                'countries' => ['DE', 'GB', 'IT', 'LU', 'NL'],
                'counties' => [],
            ],
            'Zone 2 - UE' => [
                'countries' => ['AT', 'DK', 'ES', 'FI', 'PT', 'IE', 'SE'],
                'counties' => [],
            ],
        ];
    }

    /**
     * @return list<array{qtyOf: int, qtyAt: int, packagePrice: int, zones: list<string>, nameCarrier: string}>
     */
    private function shippingPricesData(): array
    {
        return [
            ['qtyOf' => 0, 'qtyAt' => 1, 'packagePrice' => 1100, 'zones' => ['Zone 1 - France', 'Zone 2 - Corse - France'], 'nameCarrier' => 'Colissimo'],
            ['qtyOf' => 1, 'qtyAt' => 2, 'packagePrice' => 1300, 'zones' => ['Zone 1 - France', 'Zone 2 - Corse - France'], 'nameCarrier' => 'Colissimo'],
            ['qtyOf' => 2, 'qtyAt' => 3, 'packagePrice' => 1500, 'zones' => ['Zone 1 - France', 'Zone 2 - Corse - France'], 'nameCarrier' => 'Colissimo'],
            ['qtyOf' => 3, 'qtyAt' => 6, 'packagePrice' => 1950, 'zones' => ['Zone 1 - France', 'Zone 2 - Corse - France'], 'nameCarrier' => 'Colissimo'],
            ['qtyOf' => 6, 'qtyAt' => 42, 'packagePrice' => 2600, 'zones' => ['Zone 1 - France', 'Zone 2 - Corse - France'], 'nameCarrier' => 'Colissimo'],
        ];
    }

    private function findProductTypeByName(string $name): ?ProductType
    {
        $types = $this->entityManager->getRepository(ProductType::class)
            ->createQueryBuilder('productType')
            ->innerJoin('productType.translations', 'translation')
            ->andWhere('translation.name = :name')
            ->setParameter('name', $name)
            ->setMaxResults(1)
            ->getQuery()
            ->getResult();

        return $types[0] ?? null;
    }

    private function findProductCategoryByName(string $name): ?ProductCategory
    {
        $categories = $this->entityManager->getRepository(ProductCategory::class)
            ->createQueryBuilder('productCategory')
            ->innerJoin('productCategory.translations', 'translation')
            ->andWhere('translation.name = :name')
            ->setParameter('name', $name)
            ->setMaxResults(1)
            ->getQuery()
            ->getResult();

        return $categories[0] ?? null;
    }
}
