<?php

namespace App\Service;

use App\Entity\PriceAutomatic;
use App\Repository\PriceAutomaticRepository;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;

class TarificationService
{
    private const PRICE_500 = '500.00';
    private const PRICE_100 = '100.00';
    private const PRICE_50 = '50.00';
    private const PRICE_30 = '30.00';

    private ?MeilisearchService $meilisearch = null;
    private ?StripePriceService $stripePriceService = null;

    // NOSONAR - data configuration, not duplicated logic
    private const DEFAULT_PRICES = [
        'esite_business' => [
            'title' => 'E-Site Basique',
            'description' => 'Creation, hebergement et maintenance de site internet realise avec Esy-Web. Le client remplit le site en autonomie.',
            'priceHt' => self::PRICE_500,
            'monthPrice' => self::PRICE_100,
            'period' => 1,
            'lineType' => 'website',
        ],
        'esite_premium' => [
            'title' => 'E-Site Avancee',
            'description' => 'Creation, hebergement et maintenance de site internet realise avec Esy-Web. Accompagnement complet jusqu\'a la mise en ligne.',
            'priceHt' => '2000.00',
            'monthPrice' => self::PRICE_100,
            'period' => 1,
            'lineType' => 'website',
        ],
        'esite_ecommerce_business' => [
            'title' => 'E-Site E-Commerce Basique',
            'description' => 'Creation, hebergement et maintenance de site E-Commerce realise avec Esy-Web. Produits illimites.',
            'priceHt' => '999.00',
            'monthPrice' => '150.00',
            'period' => 1,
            'lineType' => 'website',
        ],
        'esite_ecommerce_premium' => [
            'title' => 'E-Site E-Commerce Avancee',
            'description' => 'Creation, hebergement et maintenance de site E-Commerce realise avec Esy-Web. Accompagnement complet. Produits illimites.',
            'priceHt' => '3100.00',
            'monthPrice' => '150.00',
            'period' => 1,
            'lineType' => 'website',
        ],
        'email_3go' => [
            'title' => 'E-Mail 3 Go',
            'description' => 'Boite mail professionnelle 3 Go. Antispam, antivirus, RGPD, IMAP/POP/SMTP.',
            'priceHt' => '1.00',
            'monthPrice' => '1.00',
            'period' => 1,
            'lineType' => 'esymail',
        ],
        'email_50go' => [
            'title' => 'E-Mail 50 Go',
            'description' => 'Boite mail professionnelle 50 Go. Antispam, antivirus, RGPD, IMAP/POP/SMTP.',
            'priceHt' => '5.00',
            'monthPrice' => '5.00',
            'period' => 1,
            'lineType' => 'esymail',
        ],
        'email_mise_en_service' => [
            'title' => 'E-Mail - Mise en service',
            'description' => 'Mise en service de la messagerie professionnelle E-Mail.',
            'priceHt' => '25.00',
            'monthPrice' => '0.00',
            'period' => 1,
            'lineType' => 'esymail',
        ],
        'email_supp_3go' => [
            'title' => 'E-Mail - Boite supplementaire 3 Go',
            'description' => 'Boite mail supplementaire 3 Go. Antispam, antivirus, RGPD.',
            'priceHt' => '1.00',
            'monthPrice' => '1.00',
            'period' => 1,
            'lineType' => 'esymail',
        ],
        'email_supp_50go' => [
            'title' => 'E-Mail - Boite supplementaire 50 Go',
            'description' => 'Boite mail supplementaire 50 Go. Antispam, antivirus, RGPD.',
            'priceHt' => '5.00',
            'monthPrice' => '5.00',
            'period' => 1,
            'lineType' => 'esymail',
        ],
        'emailer' => [
            'title' => 'E-Mailer',
            'description' => 'Envoi de mail en masse. 15 000 mails/mois.',
            'priceHt' => self::PRICE_50,
            'monthPrice' => self::PRICE_30,
            'period' => 1,
            'lineType' => 'esymail',
        ],
        'esydefender_pro' => [
            'title' => 'E-Protect Pro',
            'description' => 'Cyber defense avancee. Anti-DDoS, pare-feu, filtrage geo, surveillance.',
            'priceHt' => self::PRICE_50,
            'monthPrice' => '60.00',
            'period' => 3,
            'lineType' => 'hosting',
        ],
        'esymeet' => [
            'title' => 'E-Calendar',
            'description' => 'Prise de rendez-vous en ligne via Cal.com.',
            'priceHt' => self::PRICE_50,
            'monthPrice' => self::PRICE_30,
            'period' => 1,
            'lineType' => 'website',
        ],
        'esytchat' => [
            'title' => 'E-Chat',
            'description' => 'Chat en ligne sur votre site via Chatwoot.',
            'priceHt' => self::PRICE_50,
            'monthPrice' => '15.00',
            'period' => 1,
            'lineType' => 'website',
        ],
        'ndd_depot' => [
            'title' => 'Nom de domaine - Depot',
            'description' => 'Enregistrement initial avec SPF, DMARC, DNSSEC, Whois, HTTPS.',
            'priceHt' => '20.00',
            'monthPrice' => '0.00',
            'period' => 1,
            'lineType' => 'ndd',
        ],
        'ndd_renouvellement' => [
            'title' => 'Nom de domaine - Renouvellement',
            'description' => 'Renouvellement annuel du nom de domaine.',
            'priceHt' => '20.00',
            'monthPrice' => '0.00',
            'period' => 12,
            'lineType' => 'ndd',
        ],
        'ndd_gestion' => [
            'title' => 'Nom de domaine - Gestion',
            'description' => 'Gestion technique DNS, HTTPS, redirections, surveillance.',
            'priceHt' => self::PRICE_30,
            'monthPrice' => '0.00',
            'period' => 12,
            'lineType' => 'ndd',
        ],
        'ndd_reactivation' => [
            'title' => 'Nom de domaine - Reactivation',
            'description' => 'Reactivation d\'un nom de domaine expire.',
            'priceHt' => self::PRICE_50,
            'monthPrice' => '0.00',
            'period' => 1,
            'lineType' => 'ndd',
        ],
        'formation_pack10h' => [
            'title' => 'Pack 10 heures de formation',
            'description' => 'Construction du site ensemble with formation.',
            'priceHt' => self::PRICE_500,
            'monthPrice' => '0.00',
            'period' => 1,
            'lineType' => 'other',
        ],
        'formation_heure' => [
            'title' => 'Formation a la demande',
            'description' => 'Formation individuelle a l\'heure.',
            'priceHt' => '70.00',
            'monthPrice' => '0.00',
            'period' => 1,
            'lineType' => 'other',
        ],
    ];

    public function __construct(
        private PriceAutomaticRepository $repository,
        private EntityManagerInterface $em,
        private ?LoggerInterface $logger = null,
        ?MeilisearchService $meilisearch = null,
        ?StripePriceService $stripePriceService = null,
    ) {
        $this->meilisearch = $meilisearch;
        $this->stripePriceService = $stripePriceService;
    }

    /**
     * Verifie que tous les tarifs par defaut existent, cree ceux qui manquent.
     *
     * @return list<string> liste des types crees
     */
    public function ensureDefaultPrices(): array
    {
        $existing = $this->repository->findAll();
        $existingTypes = array_map(fn (PriceAutomatic $p) => $p->getType(), $existing);
        $created = [];

        foreach (self::DEFAULT_PRICES as $type => $data) {
            if (!\in_array($type, $existingTypes, true)) {
                $price = new PriceAutomatic();
                $price->setType($type);
                $price->setTitle($data['title']);
                $price->setDescription($data['description']);
                $price->setPriceHt($data['priceHt']);
                $price->setMonthPrice($data['monthPrice']);
                $price->setPeriod($data['period']);

                $this->em->persist($price);
                $created[] = $type;
            }
        }

        if ([] !== $created) {
            $this->em->flush();

            // Indexer dans Meilisearch et sync Stripe
            $allPrices = $this->repository->findAll();
            foreach ($allPrices as $p) {
                if (\in_array($p->getType(), $created, true)) {
                    $this->meilisearch?->indexPrice($p);

                    try {
                        $this->stripePriceService?->syncPrice($p);
                    } catch (\Throwable $e) {
                        $this->logger?->error('Error syncing price with Stripe: '.$e->getMessage(), [
                            'price_id' => $p->getId(),
                            'type' => $p->getType(),
                            'exception' => $e,
                        ]);
                    }
                }
            }
        }

        return $created;
    }

    /**
     * @return list<PriceAutomatic>
     */
    public function getAll(): array
    {
        return $this->repository->findAll();
    }

    public function getByType(string $type): ?PriceAutomatic
    {
        return $this->repository->findOneBy(['type' => $type]);
    }

    /**
     * @return array<string, array{title: string, description: string, priceHt: string, monthPrice: string, period: int}>
     */
    public static function getDefaultTypes(): array
    {
        return self::DEFAULT_PRICES;
    }
}
