<?php

namespace App\Controller\Dashboard;

use App\Entity\Formules;
use App\Entity\FormulesOptionsInclus;
use App\Entity\FormulesProductInclus;
use App\Entity\FormulesRestriction;
use App\Form\FormulesType;
use App\Logger\AppLogger;
use App\Repository\FormulesRepository;
use App\Repository\ProductRepository;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/crm/formules')]
class FormulesController extends AbstractController
{
    public function __construct(
        private readonly EntityManagerInterface $em,
        private readonly AppLogger $appLogger,
        private readonly FormulesRepository $formulesRepository
    ) {
    }

    #[Route('', name: 'app_crm_formules', methods: ['GET', 'POST'])]
    public function index(Request $request, PaginatorInterface $paginator): Response
    {
        // Gestion du réordonnancement (Drag & Drop via JSON)
        if ($request->isMethod('POST')) {
            $data = json_decode($request->getContent(), true);
            if (isset($data['items']) && is_array($data['items'])) {
                foreach ($data['items'] as $key => $id) {
                    $formule = $this->formulesRepository->find($id);
                    if ($formule) {
                        $formule->setPos($key);
                        $this->em->persist($formule);
                    }
                }
                $this->em->flush();
            }
            return $this->json(['status' => 'success']);
        }

        $this->appLogger->record('VIEW', 'Consultation des formules');

        $query = $this->formulesRepository->findBy([], ['pos' => 'asc']);

        return $this->render('dashboard/formules.twig', [
            'formules' => $paginator->paginate($query, $request->query->getInt('page', 1), 10),
        ]);
    }

    #[Route('/add', name: 'app_crm_formules_add', methods: ['GET', 'POST'])]
    public function add(Request $request): Response
    {
        $this->appLogger->record('VIEW', 'Consultation page création formules');

        $formule = new Formules();
        $formule->setIsPublish(false)
            ->setUpdatedAt(new \DateTimeImmutable())
            ->setType($request->query->get('type', 'pack'));

        $form = $this->createForm(FormulesType::class, $formule);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->em->persist($formule);

            // Création automatique des restrictions pour les formules gratuites
            if ($formule->getType() === "free") {
                $restriction = new FormulesRestriction();
                $restriction->setFormule($formule)
                    ->setNbStructureMax(0)
                    ->setNbAlimentaireMax(0)
                    ->setNbBarhumsMax(0)
                    ->setRestrictionConfig([]);
                $this->em->persist($restriction);
            }

            $this->em->flush();

            $this->appLogger->record('CREATED', "Création de la formule : " . $formule->getName());
            $this->addFlash("success", "La formule a été créée avec succès.");

            return $this->redirectToRoute('app_crm_formules_view', ['id' => $formule->getId()]);
        }

        return $this->render('dashboard/formules/add.twig', [
            'formule' => $formule,
            'form' => $form->createView(),
            'type' => $formule->getType(),
        ]);
    }

    #[Route('/{id}', name: 'app_crm_formules_view', methods: ['GET', 'POST'])]
    public function view(
        Formules $formule,
        Request $request,
        ProductRepository $productRepository
    ): Response {
        // Changement de type via query param si nécessaire
        if ($type = $request->query->get('type')) {
            $formule->setType($type);
        }

        // 1. Actions Rapides (Query Param 'act')
        if ($request->query->get('act') === 'togglePublish') {
            return $this->handleTogglePublish($formule, $request->query->get('status') === 'true');
        }

        // 2. Traitement des formulaires manuels (détection via clés POST)
        if ($request->isMethod('POST')) {
            if ($request->request->has('lines')) {
                return $this->handleUpdateProducts($formule, $request->request->all('lines'), $productRepository);
            }
            if ($request->request->has('option')) {
                return $this->handleUpdateOptions($formule, $request->request->all('option'));
            }
            if ($request->request->has('rest')) {
                return $this->handleUpdateRestrictionConfig($formule, $request->request->all('rest'));
            }
            if ($request->request->has('price')) {
                return $this->handleUpdatePrices($formule, $request->request->all('price'));
            }
            if ($request->request->has('nbStructureMax')) {
                return $this->handleUpdateLimits($formule, $request);
            }
        }

        // 3. Formulaire Symfony principal
        $form = $this->createForm(FormulesType::class, $formule);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            if($formule->getType() == "free") {
                $r = $formule->getFormulesRestriction();
                if(!$r) {
                    $r = new FormulesRestriction();
                    $r->setNbStructureMax(0);
                    $r->setNbAlimentaireMax(0);
                    $r->setNbBarhumsMax(0);
                    $r->setRestrictionConfig([]);
                    $this->em->persist($r);
                    $formule->setFormulesRestriction($r);
                }
            }
            $this->em->persist($formule);
            $this->em->flush();

            $this->appLogger->record('UPDATE', "Modification de la formule (infos) : " . $formule->getName());
            $this->addFlash("success", "La formule a été modifiée avec succès.");

            return $this->redirectToRoute('app_crm_formules_view', ['id' => $formule->getId()]);
        }

        return $this->render('dashboard/formules/view.twig', [
            'formule' => $formule,
            'form' => $form->createView(),
            'type' => $formule->getType(),
            'lines' => $this->prepareLines($formule),
            'option' => $this->prepareOptions($formule),
            'restriction' => $this->prepareRestrictions($formule),
        ]);
    }

    #[Route('/delete/{id}', name: 'app_crm_formules_delete', methods: ['POST', 'GET'])]
    public function delete(Formules $formule, Request $request): RedirectResponse
    {
        if ($this->isCsrfTokenValid('delete' . $formule->getId(), $request->query->get('_token'))) {
            $name = $formule->getName();

            if ($restriction = $formule->getFormulesRestriction()) {
                $this->em->remove($restriction);
            }
            foreach ($formule->getFormulesProductIncluses() as $inclus) {
                $this->em->remove($inclus);
            }

            $this->em->remove($formule);
            $this->em->flush();

            $this->appLogger->record('DELETE', "Suppression définitive de la formule : $name");
            $this->addFlash('success', "La formule \"$name\" a été supprimée.");
        } else {
            $this->addFlash('error', 'Jeton de sécurité invalide.');
        }

        return $this->redirectToRoute('app_crm_formules');
    }

    // --- PRIVATE HELPERS : ACTIONS ---

    private function handleTogglePublish(Formules $formule, bool $status): RedirectResponse
    {
        $formule->setIsPublish($status);
        $this->em->flush();

        $action = $status ? 'Publication' : 'Désactivation';
        $this->appLogger->record('UPDATE', "$action de la formule " . $formule->getName());
        $this->addFlash('success', 'Statut mis à jour avec succès.');

        return $this->redirectToRoute('app_crm_formules_view', ['id' => $formule->getId()]);
    }

    private function handleUpdateProducts(Formules $formule, array $lines, ProductRepository $productRepo): RedirectResponse
    {
        foreach ($lines as $line) {
            if (empty($line['product'])) continue;

            $productInclus = null;
            if (!empty($line['id'])) {
                $productInclus = $this->em->getRepository(FormulesProductInclus::class)->find($line['id']);
            }

            if (!$productInclus) {
                $productInclus = new FormulesProductInclus();
                $productInclus->setFormules($formule)->setConfig([]);
            }

            $product = $productRepo->findOneBy(['name' => $line['product']]);
            if ($product) {
                $productInclus->setPRODUCT($product);
                $this->em->persist($productInclus);
            }
        }
        $this->em->flush();

        $this->appLogger->record('UPDATE', 'Mise à jour des produits inclus dans ' . $formule->getName());
        $this->addFlash('success', 'Produits mis à jour avec succès.');

        return $this->redirectToRoute('app_crm_formules_view', ['id' => $formule->getId()]);
    }

    private function handleUpdateOptions(Formules $formule, array $options): RedirectResponse
    {
        foreach ($options as $opt) {
            if (empty($opt['product'])) continue;

            $optionInclus = null;
            if (!empty($opt['id'])) {
                $optionInclus = $this->em->getRepository(FormulesOptionsInclus::class)->find($opt['id']);
            }

            if (!$optionInclus) {
                $optionInclus = new FormulesOptionsInclus();
                $optionInclus->setFormule($formule);
            }

            $optionInclus->setName($opt['product']);
            $this->em->persist($optionInclus);
        }
        $this->em->flush();

        $this->appLogger->record('UPDATE', 'Mise à jour des options incluses dans ' . $formule->getName());
        $this->addFlash('success', 'Options mises à jour avec succès.');

        return $this->redirectToRoute('app_crm_formules_view', ['id' => $formule->getId()]);
    }

    private function handleUpdateRestrictionConfig(Formules $formule, array $rest): RedirectResponse
    {
        $restriction = $formule->getFormulesRestriction();
        if ($restriction) {
            $restriction->setRestrictionConfig($rest);
            $this->em->persist($restriction);
            $this->em->flush();

            $this->appLogger->record('UPDATE', "Mise à jour configuration restriction pour : " . $formule->getName());
            $this->addFlash("success", "Les restrictions ont été mises à jour.");
        }

        return $this->redirectToRoute('app_crm_formules_view', ['id' => $formule->getId()]);
    }

    private function handleUpdatePrices(Formules $formule, array $prices): RedirectResponse
    {
        $formule->setPrice1j($prices['1j'] ?? $formule->getPrice1j());
        $formule->setPrice2j($prices['2j'] ?? $formule->getPrice2j());
        $formule->setPrice5j($prices['5j'] ?? $formule->getPrice5j());
        $formule->setCaution($prices['caution'] ?? $formule->getCaution());

        $this->em->flush();

        $this->appLogger->record('UPDATE', "Mise à jour des tarifs pour : " . $formule->getName());
        $this->addFlash("success", "Les tarifs ont été mis à jour.");

        return $this->redirectToRoute('app_crm_formules_view', ['id' => $formule->getId()]);
    }

    private function handleUpdateLimits(Formules $formule, Request $request): RedirectResponse
    {
        if ($formule->getType() !== "free") {
            $this->addFlash("warning", "Le nombre de structures max n'est modifiable que pour les formules gratuites.");
            return $this->redirectToRoute('app_crm_formules_view', ['id' => $formule->getId()]);
        }

        $restriction = $formule->getFormulesRestriction();
        if ($restriction) {
            $restriction->setNbStructureMax((int) $request->request->get('nbStructureMax'));
            $restriction->setNbBarhumsMax((int) $request->request->get('nbBarhumsMax'));
            $restriction->setNbAlimentaireMax((int) $request->request->get('nbAlimentaireMax'));

            $this->em->persist($restriction);
            $this->em->flush();

            $this->appLogger->record('UPDATE', "Modification limites (restrictions) : " . $formule->getName());
            $this->addFlash("success", "Les limites de la formule ont été modifiées.");
        } else {
            $this->addFlash("error", "Aucune entité de restriction trouvée.");
        }

        return $this->redirectToRoute('app_crm_formules_view', ['id' => $formule->getId()]);
    }

    // --- PRIVATE HELPERS : VIEW PREPARATION ---

    private function prepareLines(Formules $formule): array
    {
        $lines = [];
        foreach ($formule->getFormulesProductIncluses() as $fc) {
            $lines[] = [
                'id' => $fc->getId(),
                'product' => $fc->getProduct()->getName()
            ];
        }
        if (empty($lines)) $lines[] = ['product' => ''];
        return $lines;
    }

    private function prepareOptions(Formules $formule): array
    {
        $options = [];
        foreach ($formule->getFormulesOptionsIncluses() as $fc) {
            $options[] = [
                'id' => $fc->getId(),
                'product' => $fc->getName()
            ];
        }
        if (empty($options)) $options[] = ['product' => ''];
        return $options;
    }

    private function prepareRestrictions(Formules $formule): array
    {
        $restriction = $formule->getFormulesRestriction();
        if ($restriction && !empty($restriction->getRestrictionConfig())) {
            return $restriction->getRestrictionConfig();
        }
        return [['type' => 'structure', 'product' => '','id'=>0]];
    }
}
