<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Checkout;

use Gls\GlsPoland\Entity\Carrier;
use Gls\GlsPoland\Entity\ShopDeliveryCarrier;
use Gls\GlsPoland\PrestaShop\Asset\DTO\Assets;
use Gls\GlsPoland\PrestaShop\Checkout\Presenter\CheckoutConfigPresenter;
use Gls\GlsPoland\PrestaShop\Templating\RendererInterface;
use Gls\GlsPoland\Translation\TranslatorAwareTrait;

/**
 * @mixin CheckoutInterface
 */
trait CheckoutTrait
{
    use TranslatorAwareTrait;

    /**
     * @var \FrontController|null
     */
    protected $controller;

    /**
     * @var RendererInterface
     */
    private $renderer;

    /**
     * @var CheckoutConfigPresenter
     */
    private $dataPresenter;

    public static function getSubscribedEvents(): array
    {
        return [];
    }

    public function setController(\FrontController $controller): CheckoutInterface
    {
        $this->controller = $controller;

        return $this;
    }

    public function getAssets(\Cart $cart): Assets
    {
        return (new Assets())
            ->addJavaScript(AbstractCheckout::MAP_SDK_JS_URI)
            ->addJavaScript('js/front/bootstrap-modal-compat.js')
            ->addJavaScript('js/front/parcel-shop-fallback.js')
            ->addStyleSheet('css/front/checkout.css')
            ->addJavaScriptVariable('glsPolandGenericCheckoutError', $this->getTranslator()->trans('Please select a ParcelShop.', [], 'Modules.Glspoland.Checkout'))
            ->addJavaScriptVariable('glsPolandCheckoutConfig', $this->dataPresenter->present($cart))
            // TODO: refactor
            ->addJavaScriptVariable('glsPolandRoutes', [
                'selectParcelShop' => \Context::getContext()->link->getModuleLink('glspoland', 'checkout', [
                    'action' => 'selectParcelShop',
                ]),
            ]);
    }

    public function renderDeliveryOptionsForm(Carrier $carrier, \Cart $cart, int $carrierId): string
    {
        if (!$carrier instanceof ShopDeliveryCarrier) {
            return '';
        }

        /* TODO: SEPARATE SERVICE AND CACHED VALUES IN MEMORY */
        $presentedData = $this->dataPresenter->present($cart);
        $parcelShop = $presentedData['parcelShops'][$carrier->getId()->getValue()] ?? null;
        $postalCode = $presentedData['zipCode'] ?? null;

        if (null === $postalCode && null !== $parcelShop) {
            $postalCode = $parcelShop['postal_code'] ?? null;
        }

        return $this->renderer->render('module:glspoland/views/templates/hook/carrier_extra_content.tpl', [
            'carrier_id' => $carrierId,
            'reference_id' => $carrier->getId()->getValue(),
            'cart_id' => (int) $cart->id,
            'parcel_shop' => $parcelShop,
            'zip_code' => $postalCode,
            'parcelshop_type' => null !== $carrier->getParcelShopType() ? $carrier->getParcelShopType()->getValue() : null,
        ]);
    }

    public function renderMapModal(): string
    {
        return $this->renderer->render('module:glspoland/views/templates/hook/after_carrier.tpl');
    }

    protected function addError(string $error): void
    {
        if (!isset($this->controller)) {
            throw new \LogicException('Controller is not set.');
        }

        $this->controller->errors[] = $error;
    }
}
