<?php

namespace KupShop\POSBundle\EventListener;

use KupShop\KupShopBundle\Context\PosContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\OrderingBundle\Util\Purchase\PurchaseUtil;
use KupShop\POSBundle\Event\PosOrderEvent;
use KupShop\POSBundle\Util\PosWarehouseUtil;
use Query\Operator;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Contracts\Service\Attribute\Required;

class PosOrderEventListener implements EventSubscriberInterface
{
    #[Required]
    public PosWarehouseUtil $posWarehouseUtil;
    #[Required]
    public PurchaseUtil $purchaseUtil;

    public static function getSubscribedEvents()
    {
        $events[PosOrderEvent::PURCHASE_STATE_CHECK] = [
            ['checkPurchaseStateStockIn', 200],
        ];

        $events[PosOrderEvent::PURCHASE_STATE_ORDER_CREATED] = [
            ['handleOrderCreatedFromPurchaseState', 200],
        ];

        return $events;
    }

    /** @throws \Exception */
    public function checkPurchaseStateStockIn(PosOrderEvent $event): void
    {
        if (findRight('POS_PURCHASE_SKIP_PIECES_CHECK') && !isSuperuser() && !isFunctionalTests()) {
            return;
        }

        $previousPurchaseState = null;
        if ($event->getOrder()) {
            $previousPurchaseState = $this->purchaseUtil->createStateFromOrder($event->getOrder());
        }

        $this->posWarehouseUtil->checkPurchaseStateItemsStockIn(
            purchaseState: $event->getPurchaseState(),
            pos: Contexts::get(PosContext::class)->getActive(),
            previousPurchaseState: $previousPurchaseState
        );
    }

    public function handleOrderCreatedFromPurchaseState(PosOrderEvent $event)
    {
        $order = $event->getOrder();
        if ($event->isOrderNew()) {
            // Associate serial numbers with order item
            if (findModule(\Modules::PRODUCTS_SERIAL_NUMBERS)) {
                foreach ($order->items as $item) {
                    $note = $item['note'] ?? [];
                    sqlQueryBuilder()
                        ->update('products_serial_numbers')
                        ->set('id_order_item', $item['id'])
                        ->andWhere(Operator::inStringArray(array_keys($note['serial_numbers'] ?? []), 'serial_number'))
                        ->execute();
                }
            }

            $order->logHistory('Vytvořeno v pokladně');
        } else {
            $order->logHistory('Aktualizováno v pokladně');
        }
    }
}
