<?php
/**
 * Copyright since 2025 InPost S.A.
 *
 * For the full license information, please view the LICENSE file bundled with the module.
 *
 * @author InPost S.A.
 * @copyright since 2025 InPost S.A.
 * @license MIT
 */

declare(strict_types=1);

namespace InPost\International\Controller\Admin;

use InPost\International\Entity\ParcelTemplate;
use InPost\International\ParcelTemplate\Exception\ParcelTemplateException;
use InPost\International\ParcelTemplate\Form\Type\ParcelTemplateType;
use InPost\International\ParcelTemplate\Grid\ParcelTemplateFilters;
use InPost\International\ParcelTemplate\Message\CreateParcelTemplateCommand;
use InPost\International\ParcelTemplate\Message\DeleteParcelTemplateCommand;
use InPost\International\ParcelTemplate\Message\EditParcelTemplateCommand;
use InPost\International\ParcelTemplate\Message\SelectDefaultParcelTemplateCommand;
use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\FilterableGridDefinitionFactoryInterface;
use PrestaShop\PrestaShop\Core\Grid\GridFactoryInterface;
use PrestaShop\PrestaShop\Core\Grid\Presenter\GridPresenterInterface;
use PrestaShopBundle\Security\Annotation\AdminSecurity;
use PrestaShopBundle\Security\Voter\PageVoter;
use PrestaShopBundle\Service\Grid\ResponseBuilder;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

if (!defined('_PS_VERSION_')) {
    exit;
}

/**
 * @Route("/config/parcel-templates", name="admin_inpost_intl_parcel_templates_", defaults={"_legacy_controller"=ConfigurationController::TAB_NAME, "_inpost_intl_parcel_templates_page"=true})
 */
final class ParcelTemplateController extends AbstractConfigurationController
{
    /**
     * @Route(name="index", methods={"GET"})
     *
     * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", redirectRoute="admin_module_manage")
     */
    public function index(ParcelTemplateFilters $filters, GridFactoryInterface $gridFactory, GridPresenterInterface $gridPresenter): Response
    {
        $grid = $gridFactory->getGrid($filters);

        return $this->render('@Modules/inpostinternational/views/templates/admin/parcel_template/index.html.twig', [
            'grid' => $gridPresenter->present($grid),
            'layoutTitle' => $this->trans('Parcel templates', [], 'Modules.Inpostinternational.Configuration'),
            'headerTabContent' => $this->getNavBar(),
            'layoutHeaderToolbarBtn' => $this->getToolbarButtons(),
        ]);
    }

    /**
     * @Route(name="filter", methods={"POST"})
     *
     * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", redirectRoute="admin_module_manage")
     */
    public function filter(Request $request, FilterableGridDefinitionFactoryInterface $gridDefinitionFactory, ResponseBuilder $responseBuilder): Response
    {
        return $responseBuilder
            ->buildSearchResponse(
                $gridDefinitionFactory,
                $request,
                $gridDefinitionFactory->getFilterId(),
                'admin_inpost_intl_parcel_templates_index'
            )
            ->setStatusCode(Response::HTTP_SEE_OTHER);
    }

    /**
     * @Route("/create", name="create", methods={"GET", "POST"})
     *
     * @AdminSecurity("is_granted('create', request.get('_legacy_controller'))", redirectRoute="admin_inpost_intl_parcel_templates_index")
     */
    public function create(Request $request): Response
    {
        $form = $this->createForm(ParcelTemplateType::class, new CreateParcelTemplateCommand());
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            try {
                $this->handle($form->getData());
                $this->addFlash('success', $this->trans('Successful creation', [], 'Admin.Notifications.Success'));

                return $this->redirectToRoute('admin_inpost_intl_parcel_templates_index', [], Response::HTTP_SEE_OTHER);
            } catch (ParcelTemplateException $e) {
                $this->addFlash('error', $e->getMessage());
            }
        }

        return $this->render('@Modules/inpostinternational/views/templates/admin/parcel_template/form.html.twig', [
            'form' => $form->createView(),
            'layoutTitle' => $this->trans('New parcel template', [], 'Modules.Inpostinternational.Configuration'),
            'headerTabContent' => $this->getNavBar(),
        ]);
    }

    /**
     * @Route("/{id}/edit", name="edit", methods={"GET", "POST"})
     *
     * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", redirectRoute="admin_inpost_intl_parcel_templates_index")
     */
    public function edit(ParcelTemplate $address, Request $request): Response
    {
        $form = $this->createForm(ParcelTemplateType::class, EditParcelTemplateCommand::for($address), [
            'data_class' => EditParcelTemplateCommand::class,
        ]);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            try {
                $this->handle($form->getData());
                $this->addFlash('success', $this->trans('Successful update.', [], 'Admin.Notifications.Success'));

                return $this->redirectToRoute('admin_inpost_intl_parcel_templates_index', [], Response::HTTP_SEE_OTHER);
            } catch (ParcelTemplateException $e) {
                $this->addFlash('error', $e->getMessage());
            }
        }

        return $this->render('@Modules/inpostinternational/views/templates/admin/parcel_template/form.html.twig', [
            'form' => $form->createView(),
            'layoutTitle' => $this->trans('Edit parcel template: {label}', [
                '{label}' => $address->getName(),
            ], 'Modules.Inpostinternational.Configuration'),
            'headerTabContent' => $this->getNavBar(),
            'layoutHeaderToolbarBtn' => $this->getToolbarButtons(),
        ]);
    }

    /**
     * @Route("/{id}/select-default", name="select_default", methods={"POST"})
     *
     * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", redirectRoute="admin_inpost_intl_parcel_templates_index")
     */
    public function selectDefault(int $id): Response
    {
        try {
            $this->handle(new SelectDefaultParcelTemplateCommand($id));
            $this->addFlash('success', $this->trans('Successful update.', [], 'Admin.Notifications.Success'));
        } catch (ParcelTemplateException $e) {
            $this->addFlash('error', $e->getMessage());
        }

        return $this->redirectToRoute('admin_inpost_intl_parcel_templates_index', [], Response::HTTP_SEE_OTHER);
    }

    /**
     * @Route("/{id}", name="delete", methods={"DELETE"})
     *
     * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_inpost_intl_parcel_templates_index")
     */
    public function delete(int $id): Response
    {
        try {
            $this->handle(new DeleteParcelTemplateCommand($id));
            $this->addFlash('success', $this->trans('Successful deletion', [], 'Admin.Notifications.Success'));
        } catch (ParcelTemplateException $e) {
            $this->addFlash('error', $e->getMessage());
        }

        return $this->redirectToRoute('admin_inpost_intl_parcel_templates_index', [], Response::HTTP_SEE_OTHER);
    }

    private function getToolbarButtons(): array
    {
        if (!$this->isGranted(PageVoter::CREATE, ConfigurationController::TAB_NAME)) {
            return [];
        }

        return [
            'add' => [
                'href' => $this->generateUrl('admin_inpost_intl_parcel_templates_create'),
                'desc' => $this->trans('New parcel template', [], 'Modules.Inpostinternational.Configuration'),
                'icon' => 'add_circle_outline',
            ],
        ];
    }
}
