<?php

namespace App\Controller\Admin;

use App\Entity\OrderNumber;
use App\Repository\OrderNumberRepository;
use App\Service\OrderNumberService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[Route('/admin/numerotation', name: 'app_admin_order_number')]
#[IsGranted('ROLE_ROOT')]
class OrderNumberController extends AbstractController
{
    #[Route('', name: '')]
    public function index(OrderNumberService $orderNumberService, OrderNumberRepository $repository): Response
    {
        $nextNumber = $orderNumberService->preview();

        $lastOrders = $repository->createQueryBuilder('o')
            ->orderBy('o.id', 'DESC')
            ->setMaxResults(20)
            ->getQuery()
            ->getResult();

        return $this->render('admin/order_number/index.html.twig', [
            'nextNumber' => $nextNumber,
            'lastOrders' => $lastOrders,
        ]);
    }

    #[Route('/update', name: '_update', methods: ['POST'])]
    public function update(Request $request, OrderNumberRepository $repository, EntityManagerInterface $em): Response
    {
        $error = $this->applyNextNumber($request, $repository, $em);

        if (null !== $error) {
            $this->addFlash('error', $error);
        }

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

    private function applyNextNumber(Request $request, OrderNumberRepository $repository, EntityManagerInterface $em): ?string
    {
        $error = $this->validateNumber($request->request->getString('next_number'), $repository);
        if (null !== $error) {
            return $error;
        }

        $newNumber = trim($request->request->getString('next_number'));
        $parts = explode('-', $newNumber);
        $prefix = $parts[0].'-';
        $previousNum = (int) $parts[1] - 1;

        $previousNumOrder = $prefix.str_pad((string) $previousNum, 5, '0', \STR_PAD_LEFT);

        if (null === $repository->findOneBy(['numOrder' => $previousNumOrder]) && $previousNum > 0) {
            $placeholder = new OrderNumber($previousNumOrder);
            $placeholder->markAsUsed();
            $em->persist($placeholder);
            $em->flush();
        }

        $this->addFlash('success', 'Prochain numero de commande mis a jour : '.$newNumber);

        return null;
    }

    private function validateNumber(string $rawNumber, OrderNumberRepository $repository): ?string
    {
        $newNumber = trim($rawNumber);

        if ('' === $newNumber || !preg_match('/^\d{2}\/\d{4}-\d{5}$/', $newNumber)) {
            return 'Format invalide. Utilisez le format MM/YYYY-XXXXX (ex: 04/2026-00042).';
        }

        if (null !== $repository->findOneBy(['numOrder' => $newNumber])) {
            return 'Le numero '.$newNumber.' existe deja.';
        }

        return (int) explode('-', $newNumber)[1] < 1 ? 'Le numero doit etre au minimum 00001.' : null;
    }
}
