<?php

namespace KupShop\WarehouseBundle\EventListener;

use KupShop\CatalogBundle\Util\Product\ProductPriceWeigher;
use KupShop\WarehouseBundle\Event\WarehouseProductEvent;
use KupShop\WarehouseBundle\Exception\WarehouseBaseException;
use KupShop\WarehouseBundle\Util\StoreItemWorker;
use Query\Operator;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class WarehouseInStoreListener implements EventSubscriberInterface
{
    /**
     * @var StoreItemWorker
     */
    protected $storeItemWorker;

    /**
     * @var ProductPriceWeigher
     */
    protected $productPriceWeigher;

    public static function getSubscribedEvents()
    {
        return [
            WarehouseProductEvent::IN_STORE_PRODUCT => [
                ['inStoreProduct', 100],
                ['checkInStore', 250],
            ],
        ];
    }

    public function inStoreProduct(WarehouseProductEvent $event)
    {
        $itemRow = $event->getStoreInItemRow();
        $storeItem = $event->getStoreItem();

        $tablePosition = $this->storeItemWorker->getPositionIdByCode($event->getStoreInPosition());

        $this->productPriceWeigher->updatePurchasePrice($itemRow);

        $this->storeItemWorker->createStoreItem($storeItem, $itemRow['quantity'], $tablePosition, ['stock_in' => true], true);
    }

    public function checkInStore(WarehouseProductEvent $event)
    {
        $itemRow = $event->getStoreInItemRow();

        if ($itemRow['quantity'] < 0) {
            $whereBatch = (findModule(\Modules::PRODUCTS_BATCHES)) ? ['id_product_batch' => $itemRow['id_product_batch']] : [];
            $piecesOnTable = (int) sqlQueryBuilder()
                ->select('pieces')
                ->from('warehouse_products')
                ->andWhere(
                    Operator::equalsNullable(
                        [
                            'id_product' => $itemRow['id_product'],
                            'id_variation' => $itemRow['id_variation'],
                            'id_position' => $this->storeItemWorker->getPositionIdByCode($event->getStoreInPosition()),
                        ] + $whereBatch
                    )
                )
                ->execute()
                ->fetchColumn();

            if (!$piecesOnTable || abs($piecesOnTable) < abs($itemRow['quantity'])) {
                $itemRow['product']->createFromDB();
                throw new WarehouseBaseException("Na {$event->getStoreInPosition()} je pouze {$piecesOnTable}ks produktu {$itemRow['product']->title} !");
            }
        }
    }

    /**
     * @required
     */
    public function setStoreItemWorker(StoreItemWorker $storeItemWorker): void
    {
        $this->storeItemWorker = $storeItemWorker;
    }

    /**
     * @required
     */
    public function setProductPriceWeigher(ProductPriceWeigher $productPriceWeigher)
    {
        $this->productPriceWeigher = $productPriceWeigher;
    }
}
