<?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\Configuration\Form\Type\ApiConfigurationType;
use InPost\International\Configuration\Form\Type\CheckoutConfigurationType;
use InPost\International\Configuration\Form\Type\OrdersConfigurationType;
use InPost\International\Configuration\Form\Type\ShippingConfigurationType;
use InPost\International\Configuration\Message\Factory\UpdateCheckoutConfigurationCommandFactory;
use InPost\International\Configuration\Message\Factory\UpdateOrdersConfigurationCommandFactory;
use InPost\International\Configuration\Message\UpdateApiConfigurationCommand;
use InPost\International\Configuration\Message\UpdateShippingConfigurationCommand;
use InPost\International\Configuration\Repository\ApiConfigurationRepositoryInterface;
use InPost\International\Configuration\Repository\ShippingConfigurationRepositoryInterface;
use PrestaShopBundle\Security\Annotation\AdminSecurity;
use PrestaShopBundle\Security\Voter\PageVoter;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Validator\Constraint;

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

/**
 * @Route(path="config", name="admin_inpost_intl_config_", defaults={"_legacy_controller"=ConfigurationController::TAB_NAME})
 */
final class ConfigurationController extends AbstractConfigurationController
{
    public const TAB_NAME = 'AdminInPostInternationalConfiguration';

    /**
     * @Route(path="/api", name="api", methods={"GET", "POST"})
     *
     * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", redirectRoute="admin_module_manage")
     */
    public function apiConfig(Request $request, ApiConfigurationRepositoryInterface $repository): Response
    {
        $command = UpdateApiConfigurationCommand::forRepository($repository);

        $form = $this->createForm(ApiConfigurationType::class, $command, [
            'disabled' => !$canUpdate = $this->isGranted(PageVoter::UPDATE, self::TAB_NAME),
        ]);

        if ($canUpdate) {
            $form->handleRequest($request);
        }

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

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

        return $this->render('@Modules/inpostinternational/views/templates/admin/config/api.html.twig', [
            'form' => $form->createView(),
            'can_update' => $canUpdate,
            'layoutTitle' => $this->trans('API configuration', [], 'Modules.Inpostinternational.Configuration'),
            'headerTabContent' => $this->getNavBar(),
        ], $this->createResponseForForm($form));
    }

    /**
     * @Route(path="/checkout", name="checkout", methods={"GET", "POST"})
     *
     * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", redirectRoute="admin_module_manage")
     */
    public function checkoutConfig(Request $request, UpdateCheckoutConfigurationCommandFactory $commandFactory): Response
    {
        $form = $this->createForm(CheckoutConfigurationType::class, $commandFactory->createCommand(), [
            'disabled' => !$canUpdate = $this->isGranted(PageVoter::UPDATE, self::TAB_NAME),
            'validation_groups' => static function (FormInterface $form) {
                // disable validation if the CSRF token is not valid
                return $form->isValid() ? [Constraint::DEFAULT_GROUP] : false;
            },
        ]);

        if ($canUpdate) {
            $form->handleRequest($request);
        }

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

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

        return $this->render('@Modules/inpostinternational/views/templates/admin/config/checkout.html.twig', [
            'form' => $form->createView(),
            'can_update' => $canUpdate,
            'layoutTitle' => $this->trans('Checkout configuration', [], 'Modules.Inpostinternational.Configuration'),
            'headerTabContent' => $this->getNavBar(),
        ], $this->createResponseForForm($form));
    }

    /**
     * @Route(path="/shipping", name="shipping", methods={"GET", "POST"})
     *
     * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", redirectRoute="admin_module_manage")
     */
    public function shippingConfig(Request $request, ShippingConfigurationRepositoryInterface $repository): Response
    {
        $configuration = $repository->getShippingConfiguration();
        $command = null === $configuration ? new UpdateShippingConfigurationCommand() : UpdateShippingConfigurationCommand::forConfiguration($configuration);

        $form = $this->createForm(ShippingConfigurationType::class, $command, [
            'disabled' => !$canUpdate = $this->isGranted(PageVoter::UPDATE, self::TAB_NAME),
        ]);

        if ($canUpdate) {
            $form->handleRequest($request);
        }

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

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

        return $this->render('@Modules/inpostinternational/views/templates/admin/config/shipping.html.twig', [
            'form' => $form->createView(),
            'can_update' => $canUpdate,
            'layoutTitle' => $this->trans('Shipping configuration', [], 'Modules.Inpostinternational.Configuration'),
            'headerTabContent' => $this->getNavBar(),
        ], $this->createResponseForForm($form));
    }

    /**
     * @Route(path="/orders", name="orders", methods={"GET", "POST"})
     *
     * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", redirectRoute="admin_module_manage")
     */
    public function ordersConfig(Request $request, UpdateOrdersConfigurationCommandFactory $commandFactory): Response
    {
        $form = $this->createForm(OrdersConfigurationType::class, $commandFactory->createCommand(), [
            'disabled' => !$canUpdate = $this->isGranted(PageVoter::UPDATE, self::TAB_NAME),
        ]);

        if ($canUpdate) {
            $form->handleRequest($request);
        }

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

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

        return $this->render('@Modules/inpostinternational/views/templates/admin/config/orders.html.twig', [
            'form' => $form->createView(),
            'can_update' => $canUpdate,
            'layoutTitle' => $this->trans('Orders configuration', [], 'Modules.Inpostinternational.Configuration'),
            'headerTabContent' => $this->getNavBar(),
        ], $this->createResponseForForm($form));
    }
}
