<?php

declare(strict_types=1);

require_once __DIR__ . DIRECTORY_SEPARATOR . 'ApiFrontController.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'Clinique.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'Animal.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'AnimalSac.php';

class MyvetshopcliniqueCartModuleFrontController extends ApiFrontController
{
    protected static function getPaymentImage(string $form): string
    {
        if (false !== strpos($form, 'mvs_payment_express_form')) {
            return 'app-mvs-paiement-express.png';
        }

        return 'app-mvs-paiement-normal.png';
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function serializeCart(Cart $cart): array
    {
        $ret = [
            'id' => (int) $cart->id,
            'id_carrier' => (int) $cart->id_carrier,
            'delivery_option' => $cart->delivery_option,
            'id_address_delivery' => (int) $cart->id_address_delivery,
            'id_address_invoice' => (int) $cart->id_address_invoice,
            'id_currency' => (int) $cart->id_currency,
            'recyclable' => (bool) $cart->recyclable,
            'gift' => (bool) $cart->gift,
            'gift_message' => $cart->gift_message,
            'mobile_theme' => (bool) $cart->mobile_theme,
            'allow_seperated_package' => (bool) $cart->allow_seperated_package,
            'shipping_cost' => round($cart->getTotalShippingCost(), 2),
            'total_products_tax_excl' => $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS),
            'total_products_tax_incl' => $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS),
            'total_discounts_tax_excl' => $cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS),
            'total_discounts_tax_incl' => $cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS),
            'total_shipping_tax_excl' => $cart->getOrderTotal(false, Cart::ONLY_SHIPPING),
            'total_shipping_tax_incl' => $cart->getOrderTotal(true, Cart::ONLY_SHIPPING),
            'total_tax_excl' => $cart->getOrderTotal(false, Cart::BOTH),
            'total_tax_incl' => $cart->getOrderTotal(true, Cart::BOTH),
            'donation_amount' => isset($cart->donation_amount) ? (float) $cart->donation_amount : 0,
            'date_add' => $cart->date_add,
            'date_upd' => $cart->date_upd,
            'products' => [],
            'rules' => $cart->getCartRules(),
        ];

        foreach ($cart->getProducts() as $product) {
            $productObj = new Product($product['id_product']);
            $images = $productObj->getImages($this->context->language->id);
            $images_urls = [
                'cart_default' => [],
                'home_default' => [],
                'large_default' => [],
            ];
            foreach ($images as $image) {
                foreach ($images_urls as $size => $values) {
                    $images_urls[$size][] = (new Link('https://', 'https://'))->getImageLink($product['link_rewrite'], $image['id_image'], $size);
                }
            }

            $ret['products'][] = [
                'id_product' => $product['id_product'],
                'id_product_attribute' => $product['id_product_attribute'],
                'cart_quantity' => $product['cart_quantity'],
                'name' => $product['name'],
                'is_virtual' => $product['is_virtual'],
                'description_short' => $product['description_short'],
                'id_manufacturer' => $product['id_manufacturer'],
                'on_sale' => $product['on_sale'],
                'ecotax' => $product['ecotax'],
                'additional_shipping_cost' => $product['additional_shipping_cost'],
                'available_for_order' => boolval($product['available_for_order']),
                'price' => round($product['price'], 2),
                'active' => boolval($product['active']),
                'unity' => $product['unity'],
                'unit_price_ratio' => $product['unit_price_ratio'],
                'quantity_available' => $product['quantity_available'],
                'width' => $product['width'],
                'height' => $product['height'],
                'depth' => $product['depth'],
                'out_of_stock' => $product['out_of_stock'],
                'weight' => $product['weight'],
                'quantity' => $product['quantity'],
                'link_rewrite' => $product['link_rewrite'],
                'category' => $product['category'],
                'unique_id' => $product['unique_id'],
                'supplier_reference' => $product['supplier_reference'],
                'price_attribute' => $product['price_attribute'],
                'ecotax_attr' => $product['ecotax_attr'],
                'reference' => $product['reference'],
                'weight_attribute' => $product['weight_attribute'],
                'ean13' => $product['ean13'],
                'price_without_reduction' => round($product['price_without_reduction'], 2),
                'price_with_reduction' => round($product['price_with_reduction'], 2),
                'price_with_reduction_without_tax' => round($product['price_with_reduction_without_tax'], 2),
                'total' => round($product['total'], 2),
                'total_wt' => round($product['total_wt'], 2),
                'reduction_applies' => $product['reduction_applies'],
                'quantity_discount_applies' => $product['quantity_discount_applies'],
                'attributes' => $product['attributes'],
                'attributes_small' => $product['attributes_small'],
                'rate' => $product['rate'],
                'tax_name' => $product['tax_name'],
                'images' => $images_urls,
                'is_croquette' => AnimalSac::isCroquette($product['id_product']),
            ];
        }

        return $ret;
    }

    /**
     * Ajout
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     *
     * @return array<string, mixed>
     */
    protected function actionAddCartRule(): array
    {
        $idCartRule = CartRule::getIdByCode(Tools::getValue('code_promo'));

        if (!$idCartRule) {
            return [
                'success' => false,
                'error' => "Ce code n'existe pas",
            ];
        }

        $cartRule = new CartRule((int) $idCartRule);

        if (!Validate::isLoadedObject($cartRule)) {
            return [
                'success' => false,
                'error' => "Ce code n'existe pas",
            ];
        }

        if (Validate::isLoadedObject($cartRule)
            && $error = $cartRule->checkValidity($this->context, false, true)) {
            return [
                'success' => false,
                'error' => $error,
            ];
        }
        $this->context->cart->addCartRule($idCartRule);
        CartRule::autoRemoveFromCart($this->context);
        CartRule::autoAddToCart($this->context);

        return ['success' => true, 'cart' => $this->serializeCart($this->context->cart)];
    }

    /**
     * @return array<string, string|bool>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionAssociateOrderAnimal(): array
    {
        $id_cart = Tools::getValue('id_cart');

        $id_order = Order::getOrderByCartId($id_cart);
        if (!$id_order) {
            header('HTTP/1.0 400 Bad Request');

            return ['error' => 'Aucune commande trouvée'];
        }
        $order = new Order($id_order);
        if ($order->id_customer != $this->context->customer->id) {
            header('HTTP/1.0 401 Unauthorized');

            return ['error' => 'Accès non autorisé'];
        }
        if (!$order->getCurrentOrderState() || !$order->getCurrentOrderState()->paid) {
            header('HTTP/1.0 400 Bad Request');

            return ['error' => 'Commande non payée'];
        }

        /** @var OrderDetail[] $orderDetails */
        $orderDetails = ObjectModel::hydrateCollection(OrderDetail::class, OrderDetail::getList($order->id));
        $products = Tools::getValue('products');
        foreach ($products as $product) {
            if (!$product['id_animal']) {
                continue;
            }
            $animal = new Animal($product['id_animal']);

            // Ignore une association pour l'animal d'un autre client
            if ($animal->id_customer != $this->context->customer->id) {
                continue;
            }

            $row = Db::getInstance()->getRow(
                'SELECT *'
                . ' FROM ps_animal_sac'
                . ' WHERE id_animal = ' . (int) $product['id_animal']
                . ' AND id_product = ' . (int) $product['id_product']
                . ' AND id_product_attribute = ' . (int) $product['id_product_attribute']
                . ' AND id_order = ' . (int) $order->id
            );

            if (!$row) {
                $od = array_values(
                    array_filter(
                        $orderDetails, function ($orderDetail) use ($product) {
                            return $orderDetail->product_id == $product['id_product']
                            && $orderDetail->product_attribute_id == $product['id_product_attribute'];
                        }
                    )
                );

                if (count($od)) {
                    try {
                        // Association du sac avec l'animal
                        AnimalSac::createFromOrderDetail($od[0], $animal);
                    } catch (PrestaShopDatabaseException $e) {
                        // Inhibiteur d'erreur
                    } catch (PrestaShopException $e) {
                        // Inhibiteur d'erreur
                    }
                }
            }
        }

        return [
            'success' => true,
        ];
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     * @throws SmartyException
     */
    protected function actionCartServerVueComponent(): array
    {
        /* @var Smarty $smarty */
        global $smarty;

        $scheme = (Configuration::get('PS_SSL_ENABLED') || Tools::usingSecureMode()) ? 'https' : 'http';
        $domain = Configuration::get('https' === $scheme ? 'PS_SHOP_DOMAIN_SSL' : 'PS_SHOP_DOMAIN');

        $clinique = new Clinique(Clinique::getCliniqueByGroup($this->context->customer->id_default_group));

        $smarty->assign(
            [
                'url' => $scheme . '://' . $domain,
                'don_univet' => Configuration::get('MVS_PAYMENT_DONATION_UNIVET_NATURE') && $clinique->don,
                'context' => Context::getContext(),
            ]
        );

        return [
            'template' => $this->context->smarty->fetch(__DIR__ . '/../../views/templates/front/server-cart.tpl'),
            'computed' => [
                'don_image' => 'function() { '
                    . ' return this.cart.donation_amount ? "don-univet-nature-enable2.png" : "don-univet-nature-disable2.png";'
                    . ' }',
            ],
            'methods' => [
                'toggleMicroDon' => 'function() { ' . file_get_contents(__DIR__ . '/../../views/templates/front/toggleMicroDon.js') . ' }',
            ],
            'data' => 'function() { '
                . 'return ' . json_encode(['url' => $scheme . '://' . $domain]) . ' ;'
                . ' }',
        ];
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionEmpty(): array
    {
        foreach ($this->context->cart->getProducts() as $product) {
            $this->context->cart->deleteProduct($product['id_product'], $product['id_product_attribute']);
        }

        return $this->serializeCart($this->context->cart);
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionGet(): array
    {
        global $cart;

        // Si une commande est déjà associée à un panier, on génère un nouveau panier
        if (Order::getOrderByCartId($this->context->cart->id)) {
            $this->context->cookie->id_cart = 0;
            $this->context->cart = null;
        }

        if (!$this->context->cart) {
            if (!$this->context->cart) {
                $cart = new Cart();
                $cart->id_lang = (int) $this->context->cookie->id_lang;
                $cart->id_currency = (int) $this->context->cookie->id_currency;
                $cart->id_guest = (int) $this->context->cookie->id_guest;
                $cart->id_shop_group = (int) $this->context->shop->id_shop_group;
                $cart->id_shop = $this->context->shop->id;
                if ($this->context->cookie->id_customer) {
                    $cart->id_customer = (int) $this->context->cookie->id_customer;
                    $cart->id_address_delivery = (int) Address::getFirstCustomerAddressId($cart->id_customer);
                    $cart->id_address_invoice = (int) $cart->id_address_delivery;
                } else {
                    $cart->id_address_delivery = 0;
                    $cart->id_address_invoice = 0;
                }

                // Needed if the merchant want to give a free product to every visitors
                $this->context->cart = $cart;
                CartRule::autoAddToCart($this->context);
            } else {
                $this->context->cart = $cart;
            }

            $this->context->cart->save();
            $this->context->cookie->id_cart = $this->context->cart->id;
        }

        return $this->serializeCart($this->context->cart);
    }

    /**
     * @return array<string, mixed>
     */
    protected function actionGetAddresses(): array
    {
        // Uniquement les adresses où la livraison à domicile est possible
        return array_values(array_filter(
            $this->context->customer->getAddresses($this->context->language->id),
            function ($address) {
                return 8 == $address['id_country'];
            }
        ));
    }

    /**
     * @return array<string, mixed>
     */
    protected function actionGetCarrierList(): array
    {
        $carriers = $this->context->cart->simulateCarriersOutput();
        $delivery_option = $this->context->cart->getDeliveryOption(null, false, false);

        return [
            'carriers' => $carriers,
            'delivery_option_list' => $this->context->cart->getDeliveryOptionList(),
            'delivery_option' => $delivery_option,
            'id_address_delivery' => $this->context->cart->id_address_delivery,
            'products' => $this->context->cart->getProducts(),
        ];
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function getCartGif(): array
    {
        $cart = new Cart(Tools::getValue('id_cart'));

        if (!Validate::isLoadedObject($cart)) {
            header('HTTP/1.0 400 Bad Request');

            return [];
        }

        if ($cart->id_customer != $this->context->customer->id) {
            header('HTTP/1.0 401 Unauthorized');

            return [];
        }

        /// Détermine si la commande est payée ou non
        $order_id = Order::getOrderByCartId($cart->id);
        if (!$order_id) {
            $status = Tools::getValue('status');
        } else {
            $order = new Order($order_id);
            $orderState = $order->getCurrentOrderState();
            $status = $orderState->paid ? 'success' : 'reject';
        }

        /// Détermine si la commande est chien ou chat (ou inconnu)
        $prefix = '';
        $middle = ('success' == $status ? 'A' : 'R');

        switch ($prefix . $middle) {
            case 'A':
                $end = $cart->id % 7;
                break;

            case 'cat-A':
                $end = $cart->id % 7;
                break;

            case 'dog-A':
                $end = $cart->id % 6;
                break;

            case 'R':
                $end = $cart->id % 3;
                break;

            case 'cat-R':
                $end = $cart->id % 6;
                break;

            case 'dog-R':
                $end = $cart->id % 6;
                break;

            default:
                // Impossible ?!
                $end = 0;
        }

        // Incrément pour éviter le 0
        ++$end;

        $link = new Link();

        return [
            'gif' => $link->getBaseLink() . '/modules/myvetshopclinique/gifs/' . ('A' == $middle ? 'paiement-accepte' : 'paiement-refuse') . '/' . $prefix . $middle . $end . '.gif',
        ];
    }

    /**
     * @return array<string, string>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionGetOrderStatus(): array
    {
        $cart = new Cart(Tools::getValue('id_cart'));

        $order_id = Order::getOrderByCartId($cart->id);
        if (!$order_id) {
            return ['status' => 'unknown'];
        }

        $orderState = (new Order($order_id))->getCurrentOrderState();

        if ($orderState->paid) {
            return ['status' => 'success'];
        }

        return ['status' => 'reject'];
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionGetPayment(): array
    {
        $this->context->cookie->checkedTOS = true;

        if ($this->context->cart->OrderExists()) {
            return [
                'success' => false,
                'html' => '<div>Cette commande a déjà été payée</div>',
            ];
        }
        if (!$this->context->cart->id_customer || !Customer::customerIdExistsStatic($this->context->cart->id_customer) || Customer::isBanned($this->context->cart->id_customer)) {
            return [
                'success' => false,
                'html' => '<div>Vous ne pouvez pas passer commande</div>',
            ];
        }
        $address_delivery = new Address($this->context->cart->id_address_delivery);
        $address_invoice = ($this->context->cart->id_address_delivery == $this->context->cart->id_address_invoice ? $address_delivery : new Address($this->context->cart->id_address_invoice));
        if (!$this->context->cart->id_address_delivery || !$this->context->cart->id_address_invoice || !Validate::isLoadedObject($address_delivery) || !Validate::isLoadedObject($address_invoice)
            || $address_invoice->deleted
            || $address_delivery->deleted) {
            return [
                'success' => false,
                'html' => '<div>Sélectionnez une adresse</div>',
            ];
        }
        if (0 == count($this->context->cart->getDeliveryOptionList()) && !$this->context->cart->isVirtualCart()) {
            return [
                'success' => false,
                'html' => "<div>La livraison est impossible à l'adresse indiquée</div>",
            ];
        }
        if (!$this->context->cart->getDeliveryOption(null, false) && !$this->context->cart->isVirtualCart()) {
            return [
                'success' => false,
                'html' => '<div>Sélectionnez un moyen de livraison</div>',
            ];
        }
        if (!$this->context->cart->id_currency) {
            return [
                'success' => false,
                'html' => '<div>Sélectionnez une devise pour le règlement</div>',
            ];
        }

        /* If some products have disappear */
        if (is_array($product = $this->context->cart->checkQuantities(true))) {
            return [
                'success' => false,
                'html' => "<div>Un produit de votre panier n'est plus disponible</div>",
            ];
        }

        if ((int) $id_product = $this->context->cart->checkProductsAccess()) {
            return [
                'success' => false,
                'html' => "<div>Un produit de votre panier n'est plus disponible</div>",
            ];
        }

        /* Check minimal amount */
        //$currency = Currency::getCurrency((int)$this->context->cart->id_currency);

        /*
        $minimal_purchase = Tools::convertPrice((float)Configuration::get('PS_PURCHASE_MINIMUM'), $currency);
        if ($this->context->cart->getOrderTotal(false, Cart::ONLY_PRODUCTS) < $minimal_purchase) {
            return '<p class="warning">'.sprintf(
                    Tools::displayError('A minimum purchase total of %1s (tax excl.) is required to validate your order, current purchase total is %2s (tax excl.).'),
                    Tools::displayPrice($minimal_purchase, $currency), Tools::displayPrice($this->context->cart->getOrderTotal(false, Cart::ONLY_PRODUCTS), $currency)
                ).'</p>';
        }*/

        /* Bypass payment step if total is 0 */
        /*
        if ($this->context->cart->getOrderTotal() <= 0) {
            return '<p class="center"><button class="button btn btn-default button-medium" name="confirmOrder" id="confirmOrder" onclick="confirmFreeOrder();" type="submit"> <span>'.Tools::displayError('I confirm my order.').'</span></button></p>';
        }*/

        $paymentModule = Module::getInstanceByName('myvetshoppayment');
        if ($paymentModule instanceof MyvetshopPayment) {
            $return = $paymentModule->hookDisplayPayment(
                [
                    'cart' => $this->context->cart,
                    'url_retour_ok' => Tools::getHttpHost(true, true, true) . _MODULE_DIR_ . 'myvetshoppayment/submit.php?id_cart=' . intval($this->context->cart->id) . '&app=1&status=success',
                    'url_retour_err' => Tools::getHttpHost(true, true, true) . _MODULE_DIR_ . 'myvetshoppayment/submit.php?id_cart=' . intval($this->context->cart->id) . '&app=1&status=reject',
                ]
            );
        } else {
            $return = null;
        }

        //$return = Hook::exec('displayPayment');
        if (!$paymentModule || !$return) {
            return [
                'success' => false,
                'html' => '<div>Aucun moyen de paiement disponible</div>',
            ];
        }

        // Post-Traitement sur le html
        if (0 == preg_match('#(<form.*?mvs_payment_form.*?/form>)#', $return, $matches)) {
            return [
                'success' => false,
                'html' => '<div>Erreur HTML</div>',
            ];
        }

        /// Post-traitemet nouveau
        if (0 == preg_match_all('#(<form.*?/form>)#', $return, $full_matches)) {
            return [
                'success' => false,
                'html' => '<div>Erreur HTML</div>',
            ];
        }

        $ret = [
            'success' => true,
            'html' => '<div></div>',
            'payments' => [
            ],
        ];

        foreach ($full_matches[0] as $match) {
            if (false !== strpos($match, 'mvs_payment_form') || !$ret['html']) {
                $ret['html'] = $match;
            }

            $url_matches = [];

            // Récupère l'URL
            preg_match('#action="([^"]+)"#', $match, $url_matches);

            $ret['payments'][] = [
                'img' => self::getPaymentImage($match),
                'form' => $match,
                'url' => isset($url_matches[1]) ? $url_matches[1] : '',
            ];
        }

        return $ret;
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionSetCarrier(): array
    {
        $id_carrier = Tools::getValue('id_carrier');

        $delivery_option = [$this->context->cart->id_address_delivery => $id_carrier . ','];
        $this->context->cart->setDeliveryOption($delivery_option);
        $this->context->cart->save();

        return $this->serializeCart($this->context->cart);
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionSetDeliveryAddress(): array
    {
        $id_address = Tools::getValue('id_address');
        $address = new Address($id_address);

        if ($address->id_customer != $this->context->customer->id) {
            header('HTTP/1.0 400 Bad Request');

            return [];
        }

        $id_carrier = $this->context->cart->id_carrier;
        $id_address_invoice = $this->context->cart->id_address_invoice;
        $this->context->cart->updateAddressId($this->context->cart->id_address_delivery, $id_address);
        $this->context->cart->id_address_invoice = $id_address_invoice;
        $delivery_option = [$this->context->cart->id_address_delivery => $id_carrier . ','];
        $this->context->cart->setDeliveryOption($delivery_option);
        $this->context->cart->save();

        return $this->serializeCart($this->context->cart);
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionToggleMicroDon(): array
    {
        $donationActived = Configuration::get('MVS_PAYMENT_DONATION_UNIVET_NATURE');
        $donationAmount = Configuration::get('MVS_PAYMENT_DONATION_UNIVET_NATURE_AMOUNT');

        if (!$donationActived || 'POST' !== $_SERVER['REQUEST_METHOD']) {
            return $this->serializeCart($this->context->cart);
        }

        $context = Context::getContext();

        if ($context->cart->donation_amount) {
            $context->cart->setDonation((float) 0);
        } else {
            $context->cart->setDonation((float) $donationAmount);
        }

        return $this->serializeCart($this->context->cart);
    }

    /**
     * @return array<string, mixed>
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function actionUpdateProductQuantity(): array
    {
        $id_product = Tools::getValue('id_product');
        $id_product_attribute = Tools::getValue('id_product_attribute');
        $quantity = Tools::getValue('quantity');

        $actualQuantity = null;
        foreach ($this->context->cart->getProducts() as $product) {
            if ($product['id_product'] == $id_product && $product['id_product_attribute'] == $id_product_attribute) {
                $actualQuantity = $product['quantity'];
            }
        }

        if ($actualQuantity != $quantity) {
            // Mise à jour du nombre de produits dans le panier
            $this->context->cart->updateQty(intval(abs($actualQuantity - $quantity)), $id_product, $id_product_attribute, false, $actualQuantity < $quantity ? 'up' : 'down');
        }

        // Promotions automatiques
        CartRule::autoRemoveFromCart($this->context);
        CartRule::autoAddToCart($this->context);

        return $this->serializeCart($this->context->cart);
    }

    /**
     * Assign template vars related to page content
     *
     * @see FrontController::initContent()
     */
    public function initContent(): void
    {
        parent::initContent();

        try {
            switch (Tools::getValue('action', 'nothing')) {
                case 'addCartRule':
                    $ret = $this->actionAddCartRule();
                    break;

                case 'associateOrderAnimal':
                    $ret = $this->actionAssociateOrderAnimal();
                    break;

                case 'cartServerVueComponent':
                    $ret = $this->actionCartServerVueComponent();
                    break;

                case 'empty':
                    $ret = $this->actionEmpty();
                    break;

                case 'get':
                    $ret = $this->actionGet();
                    break;

                case 'getAddresses':
                    $ret = $this->actionGetAddresses();
                    break;

                case 'getCarrierList':
                    $ret = $this->actionGetCarrierList();
                    break;

                case 'getCartGif':
                    $ret = $this->getCartGif();
                    break;

                case 'getOrderStatus':
                    $ret = $this->actionGetOrderStatus();
                    break;

                case 'getPayment':
                    $ret = $this->actionGetPayment();
                    break;

                case 'setCarrier':
                    $ret = $this->actionSetCarrier();
                    break;

                case 'setDeliveryAddress':
                    $ret = $this->actionSetDeliveryAddress();
                    break;

                case 'toggleMicroDon':
                    $ret = $this->actionToggleMicroDon();
                    break;

                case 'updateProductQuantity':
                    $ret = $this->actionUpdateProductQuantity();
                    break;

                default:
                    $ret = [];
            }

            echo json_encode($ret, JSON_PRETTY_PRINT);
            exit();
        } catch (PrestaShopDatabaseException $e) {
            header('HTTP/1.0 500 Internal Server Error');
            header('Content-Type: application/json');
            echo json_encode(['error' => $e->getMessage()], JSON_PRETTY_PRINT);
            exit();
        } catch (PrestaShopException $e) {
            header('HTTP/1.0 500 Internal Server Error');
            header('Content-Type: application/json');
            echo json_encode(['error' => $e->getMessage()], JSON_PRETTY_PRINT);
            exit();
        }
    }
}
