<?php

namespace App\Controller;

use App\Entity\Devis;
use App\Service\DocuSealService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class DevisProcessController extends AbstractController
{
    public function __construct(
        private EntityManagerInterface $em,
        private DocuSealService $docuSeal,
        #[Autowire(env: 'DOCUSEAL_URL')] private string $docuSealUrl,
    ) {
    }

    #[Route('/devis/process/{id}/{hmac}', name: 'app_devis_process', requirements: ['id' => '\d+'], methods: ['GET'])]
    public function show(int $id, string $hmac): Response
    {
        $devis = $this->loadAndCheck($id, $hmac);

        // Redirige vers les pages dediees si le devis est deja signe/refuse
        if (Devis::STATE_ACCEPTED === $devis->getState()) {
            return $this->render('devis/signed.html.twig', [
                'devis' => $devis,
                'customer' => $devis->getCustomer(),
            ]);
        }

        if (Devis::STATE_REFUSED === $devis->getState()) {
            return $this->render('devis/refused.html.twig', [
                'devis' => $devis,
                'customer' => $devis->getCustomer(),
            ]);
        }

        return $this->render('devis/process.html.twig', [
            'devis' => $devis,
            'customer' => $devis->getCustomer(),
        ]);
    }

    #[Route('/devis/process/{id}/{hmac}/sign', name: 'app_devis_process_sign', requirements: ['id' => '\d+'], methods: ['GET'])]
    public function sign(int $id, string $hmac): Response
    {
        $devis = $this->loadAndCheck($id, $hmac);

        $submitterId = (int) $devis->getSubmissionId();
        if ($submitterId <= 0) {
            throw $this->createNotFoundException('Devis non envoye pour signature.');
        }

        $slug = $this->docuSeal->getSubmitterSlug($submitterId);
        if (null === $slug) {
            throw $this->createNotFoundException('Lien de signature introuvable.');
        }

        return $this->redirect(rtrim($this->docuSealUrl, '/').'/s/'.$slug);
    }

    /**
     * Appele par DocuSeal en redirect apres signature du client.
     * Marque le devis comme accepted et affiche la page de confirmation.
     */
    #[Route('/devis/process/{id}/{hmac}/signed', name: 'app_devis_process_signed', requirements: ['id' => '\d+'], methods: ['GET'])]
    public function signed(int $id, string $hmac): Response
    {
        $devis = $this->loadAndCheck($id, $hmac);

        if (Devis::STATE_ACCEPTED !== $devis->getState()) {
            $devis->setState(Devis::STATE_ACCEPTED);
            $this->em->flush();
        }

        return $this->render('devis/signed.html.twig', [
            'devis' => $devis,
            'customer' => $devis->getCustomer(),
        ]);
    }

    #[Route('/devis/process/{id}/{hmac}/refuse', name: 'app_devis_process_refuse', requirements: ['id' => '\d+'], methods: ['POST'])]
    public function refuse(int $id, string $hmac, \Symfony\Component\HttpFoundation\Request $request): Response
    {
        $devis = $this->loadAndCheck($id, $hmac);

        $reason = trim($request->request->getString('reason'));

        $devis->setState(Devis::STATE_REFUSED);
        if ('' !== $reason) {
            $devis->setRaisonMessage($reason);
        }

        // Libere le numero de commande
        $devis->getOrderNumber()->markAsUnused();

        // Annule la submission dans DocuSeal
        $submitterId = (int) ($devis->getSubmissionId() ?? '0');
        if ($submitterId > 0) {
            try {
                // Recupere le submission_id via l'API pour archiver
                $submitterData = $this->docuSeal->getSubmitterData($submitterId);
                if (null !== $submitterData) {
                    $submissionId = $submitterData['submission_id'] ?? null;
                    if (null !== $submissionId) {
                        $this->docuSeal->archiveSubmission((int) $submissionId);
                    }
                }
            } catch (\Throwable) {
                // Silencieux : le refus est enregistre meme si DocuSeal echoue
            }
        }

        $this->em->flush();

        return $this->render('devis/refused.html.twig', [
            'devis' => $devis,
            'customer' => $devis->getCustomer(),
        ]);
    }

    private function loadAndCheck(int $id, string $hmac): Devis
    {
        $devis = $this->em->getRepository(Devis::class)->find($id);
        if (null === $devis) {
            throw $this->createNotFoundException('Devis introuvable.');
        }

        if (!hash_equals($devis->getHmac(), $hmac)) {
            throw $this->createAccessDeniedException('Lien invalide.');
        }

        return $devis;
    }
}
