<?php

namespace App\Controller\Dashboard;

use App\Entity\Customer;
use App\Entity\CustomerAddress;
use App\Form\CustomerAddAddressType;
use App\Form\CustomerAddType;
use App\Form\CustomerType;
use App\Logger\AppLogger;
use App\Repository\CustomerAddressRepository;
use App\Repository\CustomerRepository;
use App\Service\Stripe\Client as StripeClient;
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/customer')]
class CustomerController extends AbstractController
{
    public function __construct(
        private readonly EntityManagerInterface $em,
        private readonly AppLogger $appLogger,
        private readonly StripeClient $stripeClient,
        private readonly CustomerRepository $customerRepository,
        private readonly CustomerAddressRepository $addressRepository
    ) {
    }

    #[Route('/address/{id}', name: 'app_crm_customer_address', methods: ['GET'])]
    public function addressList(Customer $customer): JsonResponse
    {
        $addressList = [];
        foreach ($customer->getCustomerAddresses() as $address) {
            $addressList[] = [
                'id' => $address->getId(),
                'label' => sprintf('%s %s %s', $address->getAddress(), $address->getZipcode(), $address->getCity()),
            ];
        }

        return $this->json(['addressList' => $addressList]);
    }

    #[Route('', name: 'app_crm_customer', methods: ['GET'])]
    public function index(PaginatorInterface $paginator, Request $request): Response
    {
        $this->appLogger->record('VIEW', 'Consultation de la liste des clients');

        $query = $this->customerRepository->createQueryBuilder('c')
            ->orderBy('c.surname', 'ASC')
            ->getQuery();

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

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

        $customer = new Customer();
        $form = $this->createForm(CustomerAddType::class, $customer);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            // Gestion manuelle de l'adresse initiale (hors formulaire mappé)
            $data = $request->request->all('customer_add');

            $address = new CustomerAddress();
            $address->setCustomer($customer)
                ->setAddress($data['adresse'] ?? '')
                ->setCity($data['city'] ?? '')
                ->setZipcode($data['zipcode'] ?? '')
                ->setCountry($data['country'] ?? '')
                ->setAddress2($data['adresse2'] ?? null)
                ->setAddress3($data['adresse3'] ?? null);

            $this->em->persist($address);
            $this->em->persist($customer);
            $this->em->flush();

            // Création Stripe
            try {
                $this->stripeClient->createCustomer($customer);
            } catch (\Exception $e) {
                $this->addFlash('warning', 'Erreur création Stripe : ' . $e->getMessage());
            }
            $this->em->flush();

            $this->appLogger->record('CREATE', sprintf(
                'Nouveau client créé : %s %s (Type: %s)',
                $customer->getSurname(), $customer->getName(), $customer->getType()
            ));

            $this->addFlash('success', 'Le client a été enregistré avec succès.');
            return $this->redirectToRoute('app_crm_customer');
        }

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

    #[Route('/edit/{id}', name: 'app_crm_customer_edit', methods: ['GET', 'POST'])]
    public function edit(int $id, Request $request): Response
    {
        $customer = $this->customerRepository->find($id);
        if (!$customer) {
            throw $this->createNotFoundException('Client introuvable');
        }

        // --- 1. GESTION ADRESSE (Ajout / Modification) ---
        $idAddr = $request->query->get('idAddr');

        if ($idAddr) {
            $address = $this->addressRepository->findOneBy(['id' => $idAddr, 'customer' => $customer]);
            if (!$address) {
                $this->addFlash('error', 'Adresse introuvable ou non associée à ce client.');
                return $this->redirectToRoute('app_crm_customer_edit', ['id' => $customer->getId()]);
            }
        } else {
            $address = new CustomerAddress();
            $address->setCustomer($customer);
        }

        $formAddress = $this->createForm(CustomerAddAddressType::class, $address);
        $formAddress->handleRequest($request);

        if ($formAddress->isSubmitted() && $formAddress->isValid()) {
            $isNew = !$address->getId();
            if ($isNew) {
                $this->em->persist($address);
            }
            $this->em->flush();

            $this->appLogger->record($isNew ? 'CREATE' : 'EDIT', sprintf(
                '%s adresse pour le client : %s',
                $isNew ? 'Ajout' : 'Modification',
                $customer->getName()
            ));

            $this->addFlash('success', sprintf('L\'adresse a été %s avec succès.', $isNew ? 'ajoutée' : 'modifiée'));
            return $this->redirectToRoute('app_crm_customer_edit', ['id' => $customer->getId()]);
        }

        // --- 2. GESTION CLIENT ---
        $form = $this->createForm(CustomerType::class, $customer);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            if ($customer->getCustomerId()) {
                try {
                    $this->stripeClient->updateCustomer($customer);
                } catch (\Exception $e) {
                    $this->addFlash('warning', 'Erreur synchro Stripe : ' . $e->getMessage());
                }
            }
            $this->em->flush();

            $this->appLogger->record('EDIT', sprintf('Modification du client : %s %s', $customer->getSurname(), $customer->getName()));
            $this->addFlash('success', 'Les informations du client ont été mises à jour.');

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

        if ($request->isMethod('GET') && !$idAddr) {
            $this->appLogger->record('VIEW', sprintf('Consultation de la fiche client : %s', $customer->getName()));
        }

        return $this->render('dashboard/customer/show.twig', [
            'customer' => $customer,
            'formAddress' => $formAddress->createView(),
            'form' => $form->createView(),
            'editingAddress' => (bool)$idAddr
        ]);
    }

    #[Route('/delete/{id}', name: 'app_crm_customer_delete', methods: ['GET', 'POST'])]
    public function delete(int $id, Request $request): RedirectResponse
    {
        $customer = $this->customerRepository->find($id);

        if (!$customer) {
            $this->addFlash('error', 'Le client demandé n\'existe pas.');
            return $this->redirectToRoute('app_crm_customer');
        }

        if ($this->isCsrfTokenValid('delete' . $customer->getId(), $request->query->get('_token'))) {
            $name = sprintf('%s %s', $customer->getSurname(), $customer->getName());

            // Suppression Stripe
            if ($customer->getCustomerId()) {
                try {
                    $this->stripeClient->deleteCustomer($customer->getCustomerId());
                } catch (\Exception $e) {
                    $this->appLogger->record('ERROR', "Erreur suppression Stripe : " . $e->getMessage());
                }
            }

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

            $this->appLogger->record('DELETE', "Suppression définitive du client : $name");
            $this->addFlash('success', "Le client $name a été supprimé définitivement.");
        } else {
            $this->addFlash('error', 'Jeton de sécurité invalide.');
        }

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