<?php

namespace KupShop\ContentBundle\View;

use KupShop\ContentBundle\Exception\InvalidCartItemException;
use KupShop\GraphQLBundle\EventListener\JsShopRefreshListener;
use KupShop\KupShopBundle\Context\PriceLevelContext;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Exception\RedirectException;
use KupShop\KupShopBundle\Exception\ResponseException;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Database\QueryHint;
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
use KupShop\KupShopBundle\Views\Traits\RequestTrait;
use KupShop\KupShopBundle\Views\View;
use KupShop\KupShopBundle\Wrapper\PriceWrapper;
use KupShop\OrderingBundle\Cart;
use KupShop\OrderingBundle\Exception\CartValidationException;
use KupShop\OrderingBundle\Exception\DeliveryException;
use KupShop\OrderingBundle\Exception\DICException;
use KupShop\OrderingBundle\Exception\PaymentException;
use KupShop\OrderingBundle\Util\Cart\CartImporter;
use KupShop\OrderingBundle\Util\UserContent\UserContent;
use KupShop\UserAddressesBundle\Util\UserAddressesUtil;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Contracts\Service\Attribute\Required;

class CartView extends View
{
    use RequestTrait;

    protected $template;

    private $act;

    protected $cart;

    private $step;

    private $stepName;

    private $error;

    private $errorId;

    private $session;

    /** @var UserContent */
    private $userContent;

    /** @var UserContext */
    private $userContext;

    /** @var PriceLevelContext */
    private $priceLevelContext;

    protected CartImporter $cartImporter;
    protected ?UserAddressesUtil $userAddressesUtil;

    protected string $smartyFallback = 'ordering';

    public function __construct(SessionInterface $session, \Cart $cart)
    {
        $this->session = $session;
        $this->cart = $cart;
    }

    /**
     * @required
     */
    public function setUserContent(UserContent $userContext): void
    {
        $this->userContent = $userContext;
    }

    /**
     * @required
     */
    public function setUserContext(UserContext $userContext): void
    {
        $this->userContext = $userContext;
    }

    /**
     * @required
     */
    public function setPriceLevelContext(PriceLevelContext $pricelistLevelContext): void
    {
        $this->priceLevelContext = $pricelistLevelContext;
    }

    #[Required]
    final public function setCartImporter(CartImporter $cartImporter): void
    {
        $this->cartImporter = $cartImporter;
    }

    public function getBodyVariables()
    {
        $vars = parent::getBodyVariables();

        $this->act = $this->request->get('act', null);
        $this->error = getVal('error');

        // Act Eraseall
        if ($this->act == 'eraseall') {
            $this->cart->clear();
            redirection('REFERER');
        }

        $this->cart->load();

        // Set Step
        $newStepName = $this->cart->visitStep($this->stepName, $this->request->get('OrderNext', false) || $this->request->get('SubmitOrder', false), $this->request->getMethod() == 'POST');
        if ($newStepName) {
            $step = $this->cart->findStep($newStepName);
            redirection($step['url']);
        }
        $this->step = $this->cart->findStep($this->stepName);

        $this->template = $this->step['template'];
        $this->title = $this->step['title'];

        // Act Erase
        if ($this->act == 'erase') {
            $id = $this->request->get('IDInCart');
            if ($id) {
                $this->cart->deleteItem($id);
            }
        }

        // Act recount
        $products = getVal('products');
        if (!empty($products)) {
            $this->cart->recalculate($products);
            if (findModule(\Modules::JS_SHOP)) {
                $this->session->set(JsShopRefreshListener::SESSION_NAME, true);
            }
        }

        // Act add
        if ($this->act == 'add') {
            $this->actAdd();
        }

        // Act import
        if ($this->act == 'import') {
            $this->actImport();
        }

        // Act fix out of stock
        if ($this->act == 'fixOutOfStock') {
            $updated = $this->cart->ensureCartInStore();
            addUserMessage(translate('fixedOutOfStock', 'ordering'), 'success', ['id' => 'fixedOutOfStock', 'products' => $updated]);
            redirection('REFERER');
        }

        // Discounts
        if ($couponNo = getVal('couponNo')) {
            $vars['couponNo'] = $couponNo;
            if (getVal('AddDiscount')) {
                $this->applyDiscountCoupon(strval($couponNo));
                redirection($this->step['url']);
            }
        }

        if ($this->stepName == 'cart' && $couponNo = getVal('ApplyCouponNo')) {
            if ($this->applyDiscountCoupon(strval($couponNo))) {
                redirection($this->step['url']);
            }
            $vars['couponNo'] = $couponNo;
        }

        if (getVal('DeleteDiscount')) {
            $couponNo = null;
            if (getVal('couponNo')) {
                $couponNo = getVal('couponNo');
            }

            $this->cart->deleteCoupon($couponNo);
            $this->cart->save();
            redirection($this->step['url']);
        }

        // Set addresses
        $invoice = getVal('invoice');
        $delivery = getVal('delivery');
        if (!empty($invoice) || !empty($delivery)) {
            if (getVal('different_address') === '0') {
                $delivery = [];
                $this->cart->delivery = [];
            }

            if (getVal('firm_address') === '0') {
                $invoice['firm'] = '';
                $invoice['ico'] = '';
                $invoice['dic'] = '';
                $invoice['copy_email'] = '';
            }

            try {
                $addrError = $this->cart->updateAddresses($invoice, $delivery);
                if (!$this->errorId) {
                    $this->errorId = $addrError;
                }
            } catch (\Exception $e) {
                addUserMessage($e->getMessage(), 'danger');
                if (isLocalDevelopment()) {
                    throw $e;
                }
                if (!$this->errorId) {
                    $this->errorId = -1;
                }
            }
        }

        $password = getVal('password');
        if ($password !== null) {
            $this->setFutureUser($password);

            $pwdError = $this->cart->registerUser($password);

            if (!$this->errorId) {
                $this->errorId = $pwdError;
            }
        }

        // Set delivery and payment
        $delivery_id = getVal('delivery_id');
        $payment_id = getVal('payment_id');
        if (!empty($delivery_id) || !empty($payment_id)) {
            $this->cart->setDeliveryAndPayment($delivery_id, $payment_id);
        }

        // Set transport
        $transport = getVal('transport');
        if ($transport) {
            $this->cart->setTransport($transport);
        }

        // Set note
        $note = getVal('noteUser');
        if (!is_null($note)) {
            $this->cart->setNote($note);
        }

        // Set note
        $userOrderNo = getVal('userOrderNo');
        if (!is_null($userOrderNo)) {
            $this->cart->setUserOrderNo($userOrderNo);
        }

        // Set newsletter
        $newsletter = getVal('news');
        if (!is_null($newsletter)) {
            $this->cart->setNewsletter(!empty($newsletter));
        }

        // Set cart data
        $cart_data = getVal('cart_data');
        if (!is_null($cart_data)) {
            $this->cart->setData(null, $cart_data);
        }

        $actionHandlersData = getVal('action_handler');
        if ($actionHandlersData !== null) {
            $this->cart->setActionHandlersData(
                array_replace(
                    $this->cart->getActionHandlersData(),
                    $actionHandlersData,
                )
            );
            $this->cart->invalidatePurchaseState();
        }

        if (($this->stepName == 'summary') || ($this->stepName == 'cart' && empty($this->act))) {
            $this->cart->invalidatePurchaseState();
        }

        // Load cart from DB
        $this->cart->createFromDB();

        // Save to session
        $this->cart->save();

        try {
            $inStoreError = QueryHint::withRouteToMaster(function () {
                return $this->cart->checkCartItems();
            });
            if (!$this->errorId) {
                $this->errorId = $inStoreError;
            }
        } catch (\Exception $e) {
            // rethrow RedirectException
            if ($e instanceof RedirectException) {
                throw $e;
            }
            // vyskocila DeliveryException nebo PaymentException, coz znamena, ze mam vybranou dopravu / platbu, ktera je disabled / ma nejakou chybu
            // takovou dopravu / platbu kvuli novemu kosiku nechci mit zaselectovanou, takze ji odeselectuju, aby se zobrazily vsechny moznosti, ktere jsou dostupne

            // zkousime to vyhazovat jen kdyz to je DELIVERY_DISABLED/HARD exception, nechcem resetovat delivery type, kdyz je spatny PSC
            if ($e instanceof DeliveryException && $e->isDeliveryDisabled()) {
                $this->cart->resetDeliveryType(!($e instanceof PaymentException));
            }

            addUserMessage($e->getMessage(), 'danger', method_exists($e, 'getData') ? $e->getData() : []);
            if (!$this->errorId) {
                $this->errorId = -1;
            }
        }

        if (\Settings::getDefault()['cart_price_change_notification'] != 'N') {
            // notifikace o zmene ceny
            // pokud mam predesly purchase state a nejsem na prvnim kroku kosiku nebo jdu na dalsi step, a neodesilam
            // objednavku, tak provedu kontrolu zmeny cen v kosiku a pripadne zobrazim info o zmene
            if ($this->cart->getPreviousPurchaseState() && ($this->stepName !== 'cart' || getVal('OrderNext')) && !getVal('SubmitOrder')) {
                foreach ($this->cart->getPurchaseState()->getProducts() as $purchaseItem) {
                    // pokud v previous statu nemam polozku, tak skipuju
                    if (!($previousPurchaseItem = ($this->cart->getPreviousPurchaseState()->getProducts()[$purchaseItem->getId()] ?? false))) {
                        continue;
                    }

                    $newPrice = $purchaseItem->getPiecePrice();
                    $prevPrice = $previousPurchaseItem->getPiecePrice();

                    // prevedu ceny do stejne meny
                    PriceCalculator::makeCompatible($newPrice, $prevPrice, false);

                    // spocitam rozdil mezi novou cenou a starou cenou
                    $diff = $newPrice->getPriceWithVat()->sub($prevPrice->getPriceWithVat())->abs();

                    // pokud se cena zmenila o vic jak 0.1, tak zobrazim hlasku o zmene ceny
                    if ($diff->asFloat() >= 0.1) {
                        addUserMessage(
                            sprintf(translate('error', 'order')['price_changed'] ?? 'Product price changed',
                                $purchaseItem->getName(),
                                "{$previousPurchaseItem->getPiecePrice()->getPriceWithVat()->asString()} {$previousPurchaseItem->getPiecePrice()->getCurrency()->getSymbol()}",
                                printPrice($newPrice))
                        );
                    }
                }
            }
        }

        if (!empty($this->errorId)) {
            $this->unsetFutureUser();
        }

        if (empty($this->errorId) && getVal('SubmitOrder')) {
            // re-create PurchaseState before order submit
            $this->cart->invalidatePurchaseState();
            $this->cart->getPurchaseState();

            $this->submitOrder();
        }

        // Should we redirect to another address
        if (empty($this->errorId)) {
            if (getVal('OrderNext')) {
                $this->step = $this->cart->findNextStep($this->stepName);
                $this->cart->save();

                redirection($this->step['url']);
            }
        }

        if (getVal('OrderPrevious')) {
            $this->step = $this->cart->findPreviousStep($this->stepName);
            $this->cart->save();

            redirection($this->step['url']);
        }

        $this->getError();

        $vars['returnNav'] = $this->getReturnNav();
        $vars['error'] = $this->error;
        $vars['act'] = $this->act;
        // $vars['cart'] = $this->cart; // v SMARTY_DEBUG = 3 to delalo: Recursion detected
        $vars['step'] = $this->step;
        $vars['stepName'] = $this->stepName;
        $vars['error_id'] = $this->errorId;

        $vars['lowestDeliveryPrice'] = $this->cart->getLowestDeliveryPrice();

        foreach ($vars as $key => $value) {
            $this->cart->$key = &$value;
            unset($value);
        }

        return $this->cart;
    }

    public function getPaymentPrice($paymentId)
    {
        $deliveryType = $this->cart->getDeliveryType();

        if ($deliveryType) {
            $deliveryId = $deliveryType->id_delivery;
        } else {
            $deliveryId = $this->cart->delivery_id;
        }

        foreach ($this->cart->delivery_types as $type) {
            if (($type->id_payment == $paymentId)
                && (($type->id_delivery == $deliveryId) || empty($deliveryId))) {
                $price = PriceCalculator::sub($type->getPrice(), $type->getDelivery()->getPrice($type->vat ?? null));

                return ServiceContainer::getService(PriceWrapper::class)->setObject($price);
            }
        }

        return null;
    }

    public function getDeliveryPrice($deliveryId)
    {
        $deliveryType = null;

        if ($selectedDeliveryType = $this->cart->getDeliveryType()) {
            // uz je vybrana nejaka kombinace dopravy a platby
            // zkusime najit deliveryType s dopravou $deliveryId a vybranou platbou
            foreach ($this->cart->delivery_types as $type) {
                if ($type->id_payment == $selectedDeliveryType->id_payment && $deliveryId == $type->id_delivery) {
                    $deliveryType = $type;
                    break;
                }
            }
        }

        if (!$deliveryType) {
            // zkusime najit prvni deliveryType s dopravou $deliveryId
            foreach ($this->cart->delivery_types as $type) {
                if ($deliveryId == $type->id_delivery) {
                    $deliveryType = $type;
                    break;
                }
            }
        }

        if ($deliveryType) {
            $deliveryType->getDelivery()->applyToCart($this->getCart());
            $type_price = $deliveryType->getPrice();
            $price = $deliveryType->price_delivery;
            if (PriceCalculator::firstGreater($price, $type_price)) {
                // cena za dopravu nemuze byt vetsi nez celkova cena zpusobu doruceni (kdyz je spatne predefinovana)
                $price = $type_price;
            }

            return ServiceContainer::getService(PriceWrapper::class)->setObject($price);
        }

        return null;
    }

    public function getTemplate(): string
    {
        if (\Settings::getDefault()->orders_closed == 'Y') {
            return 'ordersClosed.tpl';
        }

        return parent::getTemplate();
    }

    public function submitOrder()
    {
        try {
            /** @var \Order $order */
            $order = $this->cart->submitOrder();
        } catch (\Doctrine\DBAL\Exception\DriverException $ex) {
            $error_code = $ex->getErrorCode();
            $order = -1;
            if (($error_code == 1205) || ($error_code == 1213)) {
                addUserMessage(translate('order_failed_try_again', 'order_error'), 'danger');
            } else {
                addUserMessage(translate('order_failed_permanent', 'order_error'), 'danger');
                $sentryLogger = ServiceContainer::getService(SentryLogger::class);
                $sentryLogger->captureException($ex);
            }
        } catch (\RuntimeException|CartValidationException|DeliveryException|DICException $e) {
            addUserMessage($e->getMessage(), 'danger');
            $order = -1;
        }

        if (is_object($order)) {
            // reset userContent data when order is sent
            $this->userContent->setData('cart', null);

            if (findModule(\Modules::JS_SHOP)) {
                $this->session->set('orderCreated', true);
            }

            $payment = $order->getDeliveryType()->getPayment();
            if (findModule('orders', 'payment_redirect') && $payment->hasOnlinePayment()) {
                $pathData = ['id' => $order->id];
                if (!\User::getCurrentUser()) {
                    $pathData['cf'] = $order->getSecurityCode();
                }

                throw new RedirectException(
                    path('payment-redirect', $pathData)
                );
            } else {
                throw new RedirectException($order->getDetailUrl(1));
            }
        }

        $this->errorId = $order;
    }

    public function getError()
    {
        switch ($this->errorId) {
            // Discount
            case 2:
                $this->error = translate('error', 'order')['failed'];
                break;

                // User info
            case 5:
                $this->error = translate('error', 'order')['missing_transport'];
                break;
            case 6:
                $this->error = translate('error', 'user')['missing_name_invoice'];
                break;
            case 7:
                $this->error = translate('error', 'user')['missing_street_invoice'];
                break;
            case 8:
                $this->error = translate('error', 'user')['missing_city_invoice'];
                break;
            case 9:
                $this->error = translate('error', 'user')['missing_zip_invoice'];
                break;
            case 10:
                $this->error = translate('error', 'user')['missing_email_invoice'];
                break;
            case 11:
                $this->error = translate('error', 'user')['missing_phone_invoice'];
                break;
            case 12:
                $this->error = translate('error', 'order')['missing_products'];
                break;
            case 13:
                $this->error = translate('error', 'user')['false_zip'];
                break;
            case 14:
                $this->error = translate('error', 'user')['false_phone'];
                break;
            case 15:
                $this->error = replacePlaceholders(
                    translate('error', 'user')['login_exists'],
                    ['URL' => path('kupshop_user_login_login')]
                );
                break;
            case 16:
                $this->error = translate('error', 'user')['false_length_passw'];
                break;
            case 17:
                $this->error = translate('error', 'order')['false_country'];
                break;
            case 18:
                $this->error = translate('error', 'order')['disabled_country'];
                break;
            case 19:
                $this->error = translate('error', 'order')['invalid_variation'];
                break;
            case 20:
                $this->error = translate('error', 'user')['login_exists_edit'];
                break;

                // Products
                // TODO: uz by se nemelo nikde pouzivat, mohlo by se zahodit :-)
            case 30:
                $products = $this->cart->getErrors(Cart::$ERR_OUT_OF_STOCK);
                $productName = '';

                if (count($products) > 0) {
                    $product = new \Product();
                    $product->createFromDB(key($products));
                    $variaton = reset($products);

                    if (!is_null($variaton)) {
                        $product->fetchVariations();
                    }

                    if (($variaton = $product->findVariation($variaton)) !== null) {
                        $productName = $product->title.' '.$variaton['title'];
                    } else {
                        $productName = $product->title;
                    }
                }
                addUserMessage(str_replace('{PRODUCT}', $productName, translate('error', 'order')['not_stocked_products']),
                    'danger', ['id' => 'outOfStock', 'products' => $products]);
                break;
            case 31:
                $products = $this->cart->getErrors(Cart::$ERR_NOT_SELECTED_VARIATION);
                $productName = '';
                if (count($products) > 0) {
                    $product = new \Product();
                    $product->createFromDB(reset($products));
                    $productName = $product->title;
                }
                $this->error = str_replace('{PRODUCT}', $productName, translate('error', 'order')['invalid_products']);
                break;
            case 32:
                $this->error = 'Pro odeslání objednávky musíte být přihlášeni.';
                break;
            case 33:
                $products = $this->cart->getErrors(Cart::$ERR_CANNOT_BE_PURCHASED);
                $product_names = [];
                foreach ($products as $id => $product) {
                    $product = new \Product();
                    $product->createFromDB($id);
                    $product_names[] = $product->title;
                }
                addUserMessage(
                    str_replace('{PRODUCTS}', implode(', ', $product_names), translate('error', 'order')['cannot_be_purchased']),
                    'danger',
                    ['id' => 'cannotBePurchased', 'products' => $products]
                );
                break;
        }

        $this->error = replacePlaceholders($this->error, [], function ($placeholder) {
            switch ($placeholder) {
                case 'step_delivery':
                    return createScriptURL(['s' => 'ordering', 'step' => 'delivery']);
                case 'step_user':
                    return createScriptURL(['s' => 'ordering', 'step' => 'user']);
            }

            return '';
        });
    }

    public function actImport()
    {
        $count = 0;
        $errors = [];

        $data = getVal('data');
        if ($data) {
            [$tmpCount, $tmpErrors] = $this->cartImporter->importFromString($data);
            $count += $tmpCount;
            $errors = array_merge($errors, $tmpErrors);
            unset($data, $tmpCount, $tmpErrors);
        }

        foreach ($_FILES as $file) {
            if (!$file['tmp_name']) {
                continue;
            }

            [$tmpCount, $tmpErrors] = $this->cartImporter->importFromFile($file['tmp_name'], $file['name']);
            $count += $tmpCount;
            $errors = array_merge($errors, $tmpErrors);
            unset($tmpCount, $tmpErrors);
        }

        if (isAjax()) {
            exit(
                json_encode(
                    [
                        'result' => empty($errors),
                        'errors' => $errors,
                    ]
                )
            );
        }

        if ($count) {
            addUserMessage(sprintf(translate('importedItems', 'ordering'), $count), 'success');
        } else {
            addUserMessage(translate('importedNoItem', 'ordering'), 'danger');
        }

        if ($errors) {
            $message = sprintf(translate('importedWithError', 'ordering'), count($errors)).':<br>'.join('<br>', array_slice($errors, 0, 10));
            addUserMessage($message, 'warning');
        }

        redirection('REFERER');
    }

    /**
     * @throws \SmartyException
     * @throws ResponseException
     */
    public function actAdd()
    {
        global $cfg;

        $params = [
            'id_product' => intval($this->request->get('IDproduct', null)),
            'id_variation' => $this->request->get('IDvariation', null),
            'pieces' => max(floatval($this->request->get('No', null)), 0),
            'note' => $this->request->get('note', ''),
        ];

        $products = [];

        $items = getVal('items');

        if (!empty($items)) {
            foreach ($items as $id_variation => $item) {
                if ($item['pieces'] > 0) {
                    $products[] = array_merge($params, $item);
                }
            }
        } else {
            $products[] = $params;
        }

        $newIds = [];
        foreach ($products as $product) {
            $item = $product;
            try {
                $id = $this->cart->addItem($item);
            } catch (InvalidCartItemException $e) {
                $id = 0; // ajax neumře, ale nic se nevloží do košíku
            }

            if ($id <= 0) {
                addUserMessage(translate('error', 'order')['invalid_variation'], 'success');
            }

            $newIds[$id] = [
                'id_cart' => $id,
                'quantity' => $product['pieces'],
            ];
        }

        if (isAjax()) {
            $addedToCart = [
                'id_cart' => array_values($newIds)[0]['id_cart'],
                'pieces' => array_values($newIds)[0]['quantity'],
                'items' => $newIds,
            ];

            $this->session->set('addedToCart', $addedToCart);

            require_once $cfg['Path']['shared_version'].'web/block.cartInfo.php';

            $smarty = createSmarty(false, true);
            $this->cart->createFromDB();

            $smarty->assign([
                'cartInfo' => block_cartInfo(),
                'cart' => $this->cart,
                'view' => $this,
            ]);

            throw new ResponseException(new Response($smarty->fetch('block.cartInfo.tpl'), 200));
        }

        $redir = getVal('redir');
        if (!empty($redir)) {
            $addedToCart = [
                'id_cart' => array_values($newIds)[0]['id_cart'],
                'pieces' => array_values($newIds)[0]['quantity'],
                'items' => $newIds,
            ];

            $this->session->set('addedToCart', $addedToCart);
        }

        $next = getVal('next');
        if ($next) {
            redirection($next);
        }

        // pokud mame po pridani presmerovat
        if (!empty($redir) && !empty($_SERVER['HTTP_REFERER'])) {
            redirection($_SERVER['HTTP_REFERER']);
        }
    }

    public function getCart()
    {
        return $this->cart;
    }

    public function setStepName($stepName)
    {
        $this->stepName = $stepName;
    }

    public function getReturnNav()
    {
        $retNav = [['text' => translate('returnNav', 'order')[1]]];
        if ($this->stepName != 'cart') {
            $url = createScriptURL([
                'URL' => 'launch.php',
                's' => 'cart',
            ]);

            $retNav[] = ['text' => $this->step['title']];
            $retNav[0]['link'] = $url;
        }

        return getReturnNavigation(-1, 'NO_TYPE', $retNav);
    }

    public function __get($property)
    {
        if (property_exists($this, $property)) {
            return $this->$property;
        }
    }

    protected function setFutureUser(string $password): void
    {
        if ($password != '' && !empty($this->cart->invoice['email'])) {
            $this->priceLevelContext->activate(null);

            $user = new \User();
            $user->email = $this->cart->invoice['email'];
            $this->userContext->activate($user);

            $user->activateUser();
        }
        $this->cart->invalidatePurchaseState();
    }

    protected function unsetFutureUser(): void
    {
        // fixuje bug, ze kdyz se chci registrovat, ale vyskoci mi chyba, tak se to tvari jako ze jsem prihlasenej
        if ($user = $this->userContext->getActive()) {
            if ($user->id <= 0) {
                $this->userContext->activate(false);
            }
        }
    }

    protected function applyDiscountCoupon(string $couponNumber): bool
    {
        $success = false;
        try {
            if ($this->cart->addCoupon(preg_replace('/[[:^print:]]/', '', $couponNumber))) {
                addUserMessage(translate('error', 'order')['coupon_added'], 'success', ['id' => 'coupon'.$couponNumber]);
                $success = true;
            } else {
                addUserMessage(translate('error', 'order')['false_coupon'], 'danger', ['id' => 'coupon'.$couponNumber]);
            }
        } catch (CartValidationException $e) {
            addUserMessage($e->getMessage(), 'danger', ['id' => 'coupon'.$couponNumber]);
        }
        $this->cart->save();

        return $success;
    }
}
