<?php

/**
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 *
 * Copy of the Licence is available at:
 * https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Licence is distributed on an as is basis,
 * without warranties or conditions of any kind, either express or implied.
 * Check the Licence for the specific language governing permissions
 * and limitations under the License.
 *
 * @author   Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

declare(strict_types=1);

namespace SimplyIn\Ajax;

use Context;
use Db;
use Simplyin;
use SimplyIn\Ajax\Handler\AddAddressHandler;
use SimplyIn\Ajax\Handler\CheckCodeHandler;
use SimplyIn\Ajax\Handler\CheckPushNotificationHandler;
use SimplyIn\Ajax\Handler\DeleteAddressHandler;
use SimplyIn\Ajax\Handler\EditAddressHandler;
use SimplyIn\Ajax\Handler\GetClosestParcelLockersHandler;
use SimplyIn\Ajax\Handler\GetFormHandler;
use SimplyIn\Ajax\Handler\GetNewAccountFormHandler;
use SimplyIn\Ajax\Handler\LogoutHandler;
use SimplyIn\Ajax\Handler\PlaceOrderHandler;
use SimplyIn\Ajax\Handler\SearchAddressHandler;
use SimplyIn\Ajax\Handler\SelectAddressHandler;
use SimplyIn\Ajax\Handler\SendEmailCodeHandler;
use SimplyIn\Ajax\Handler\SendShopLoginEmailOtpHandler;
use SimplyIn\Ajax\Handler\SendSmsCodeHandler;
use SimplyIn\Ajax\Handler\StoreNewAccountDetailsHandler;
use SimplyIn\Ajax\Handler\SubmitAddressHandler;
use SimplyIn\Ajax\Handler\SubmitEmailHandler;
use SimplyIn\Ajax\Handler\UserDataCommerceHandler;
use SimplyIn\Ajax\Handler\VerifyShopLoginEmailOtpHandler;
use SimplyIn\Ajax\Service\AddressService;
use SimplyIn\Ajax\Service\CarrierPointService;
use SimplyIn\Ajax\Service\CheckoutSessionService;
use SimplyIn\Ajax\Service\CustomerService;
use SimplyIn\Ajax\Service\DeliveryFormRenderer;
use SimplyIn\Ajax\Service\SimplyInAddressService;
use SimplyIn\Api\SimplyInApiClientFactory;
use SimplyIn\Carrier\CarrierRegistryFactory;
use SimplyIn\Carrier\CartCarrierSetter;
use SimplyIn\Session\PrestashopSessionAdapter;
use SimplyIn\Session\SimplyInSessionInterface;

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

final class AjaxRegistryFactory
{
    public static function create(Simplyin $module, Context $context): AjaxActionRegistry
    {
        $api = SimplyInApiClientFactory::fromPrestaShop($module, $context);
        $session = self::buildSession($context);
        $db = Db::getInstance();

        $checkoutSession = new CheckoutSessionService($session);
        $addressService = new AddressService($db);
        $customerService = new CustomerService($context);
        $deliveryFormRenderer = new DeliveryFormRenderer($context, $module, $checkoutSession);
        $simplyInAddress = new SimplyInAddressService($api, $module, $addressService);

        $carrierRegistry = CarrierRegistryFactory::create($db);
        $carrierSetter = new CartCarrierSetter($context);
        $carrierPointService = new CarrierPointService($carrierRegistry, $carrierSetter);

        return new AjaxActionRegistry([
            new GetFormHandler($deliveryFormRenderer),
            new SubmitEmailHandler($api, $module, $context, $session, $checkoutSession, $deliveryFormRenderer),
            new SendSmsCodeHandler($api, $context, $session, $deliveryFormRenderer),
            new SendEmailCodeHandler($api, $context, $session, $deliveryFormRenderer),
            new CheckCodeHandler($api, $context, $session, $customerService, $deliveryFormRenderer),
            new CheckPushNotificationHandler($api, $session, $customerService, $deliveryFormRenderer),
            new SendShopLoginEmailOtpHandler($api, $context, $checkoutSession, $deliveryFormRenderer),
            new VerifyShopLoginEmailOtpHandler($api, $session, $checkoutSession, $customerService),
            new UserDataCommerceHandler($api, $checkoutSession),
            new LogoutHandler($module),
            new DeleteAddressHandler($simplyInAddress, $checkoutSession),
            new EditAddressHandler($context, $module, $simplyInAddress, $addressService, $checkoutSession),
            new AddAddressHandler($context, $module, $simplyInAddress, $addressService),
            new SubmitAddressHandler($simplyInAddress, $checkoutSession, $deliveryFormRenderer),
            new SearchAddressHandler($api, $checkoutSession),
            new GetClosestParcelLockersHandler($api, $module, $checkoutSession),
            new SelectAddressHandler(
                $context,
                $module,
                $simplyInAddress,
                $addressService,
                $checkoutSession,
                $carrierPointService,
            ),
            new PlaceOrderHandler($api, $module, $session, $checkoutSession),
            new GetNewAccountFormHandler(new \SimplyIn\Front\NewAccountFormRenderer($context, $module)),
            new StoreNewAccountDetailsHandler($session),
        ]);
    }

    private static function buildSession(Context $context): SimplyInSessionInterface
    {
        $cookie = $context->cookie;
        $cart = $context->cart;

        return new PrestashopSessionAdapter($cookie, $cart);
    }
}
