<?php

declare(strict_types=1);

namespace External\HannahBundle\SAP\EventSubscriber;

use External\HannahBundle\SAP\Util\PricingUtil;
use External\HannahBundle\SAP\Util\SAPClient;
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
use KupShop\KupShopBundle\Util\System\AsyncQueue;
use KupShop\OrderingBundle\Event\OrderEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class OrderSubscriber implements EventSubscriberInterface
{
    public function __construct(
        private AsyncQueue $asyncQueue,
        private SAPClient $sapClient,
        private PricingUtil $pricingUtil,
        private SentryLogger $sentryLogger,
    ) {
    }

    public static function getSubscribedEvents()
    {
        return [
            OrderEvent::ORDER_FINISHED => [
                ['sendFinalPricing', 200],
            ],
            OrderEvent::ORDER_COMPLETE => [
                ['applyPaymentCoupons', 200],
                ['addInfoAboutDiscountsToOrder', 200],
                ['clearCaches', 200],
            ],
        ];
    }

    public function sendFinalPricing(OrderEvent $event): void
    {
        $this->asyncQueue->addHandler(function () use ($event) {
            // pokud jsem na locale, tak neprovadim ceneni typy ORDER, protoze se tam provede uplatneni poukazek
            // a to na locale uplatnovat nechci
            $pricingType = isLocalDevelopment() ? PricingUtil::ORDER_TYPE_PRICING : PricingUtil::ORDER_TYPE_ORDER;

            // provedu finalni ceneni typu ORDER, aby se uplatnily poukazy
            $data = $this->pricingUtil->getSAPPricedOrder(
                $event->getOrder()->getPurchaseState(),
                $pricingType,
                $event->getOrder()->order_no
            );

            if (!$data) {
                return;
            }

            // vysledna data si ulozim do custom dat
            $event->getOrder()->setData('sapPricingData', $data);
        }, 'Finální cenění objednávky');
    }

    public function applyPaymentCoupons(OrderEvent $event): void
    {
        if (isLocalDevelopment()) {
            return;
        }

        $data = [];
        if ($event->getCart()) {
            $data = $event->getCart()->getData('sap');
        }

        foreach ($data['paymentCoupons'] ?? [] as $coupon) {
            try {
                $this->sapClient->couponChangeState($coupon);
            } catch (\Throwable $e) {
                if (isDevelopment()) {
                    throw $e;
                }

                $this->sentryLogger->captureException($e);
            }
        }
    }

    public function addInfoAboutDiscountsToOrder(OrderEvent $event): void
    {
        sqlGetConnection()->transactional(function () use ($event) {
            $order = $event->getOrder();
            $data = [];
            if ($event->getCart()) {
                $data = $event->getCart()->getData('sap');
            }

            $usedDiscountItems = [];
            foreach ($data['discounts'] ?? [] as $promoId => $discount) {
                $order->logHistory(
                    sprintf('V objednávce byla použita sleva "%s"', $discount['name'])
                );

                $usedDiscountItems[] = $promoId;
            }

            if (!empty($usedDiscountItems)) {
                try {
                    sqlQueryBuilder()
                        ->insert('order_discounts_orders')
                        ->directValues(
                            [
                                'id_order' => $order->id,
                                'id_order_discount' => PricingUtil::getDefaultDiscountId(),
                            ]
                        )->execute();
                } catch (\Throwable $e) {
                }
            }
        });
    }

    public function clearCaches(OrderEvent $event): void
    {
        $this->pricingUtil->clearSAPPricingResult();
    }
}
