<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Checkout\Module;

use Gls\GlsPoland\PrestaShop\Asset\DTO\Assets;
use Gls\GlsPoland\PrestaShop\Checkout\AbstractCheckout;
use Gls\GlsPoland\PrestaShop\Checkout\Event\CarrierProcessEvent;
use Gls\GlsPoland\PrestaShop\Checkout\Event\ValidateStepCompleteEvent;
use Gls\GlsPoland\PrestaShop\Checkout\ModuleCheckoutInterface;

final class STEasyCheckout extends AbstractCheckout implements ModuleCheckoutInterface
{
    use ModuleControllerCheckerTrait;

    private const MODULE_NAME = 'steasycheckout';

    public static function getModuleName(): string
    {
        return self::MODULE_NAME;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            CarrierProcessEvent::class => 'onCarrierProcess',
            ValidateStepCompleteEvent::class => 'onValidateStepComplete',
        ];
    }

    public function getAssets(\Cart $cart): Assets
    {
        return parent::getAssets($cart)
            ->addJavaScript('js/front/st-easy-checkout.js');
    }

    /**
     * In the version of the module we had access to, the hook call was commented out.
     * We have not found an acceptable way to prevent orders if the required data has not been provided.
     */
    public function onValidateStepComplete(ValidateStepCompleteEvent $event): void
    {
        $cart = $event->getCart();

        if (!$this->validateDeliveryOption($cart, $event->getRequestParameters())) {
            $event->setComplete(false);
        }
    }

    public function onCarrierProcess(CarrierProcessEvent $event): void
    {
        $request = $event->getRequest();

        if (!$request->request->has('delivery_option')) {
            return;
        }

        $cart = $event->getCart();
        $params = $request->request->all();

        if (!$this->validateDeliveryOption($cart, $params)) {
            return;
        }

        $this->saveDeliveryOption($cart, $request);
    }

    private static function getCheckoutControllerNames(): array
    {
        return ['default'];
    }
}
