<?php

namespace KupShop\ProductSetsBundle\EventListener;

use KupShop\KupShopBundle\Event\CronEvent;
use KupShop\ProductSetsBundle\Utils\MultiSetUtil;
use KupShop\StoresBundle\Utils\StoresInStore;
use Query\Operator;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class CronListener implements EventSubscriberInterface
{
    protected ?StoresInStore $storesInStore;

    public function __construct(
        private readonly MultiSetUtil $multiSets,
    ) {
    }

    public static function getSubscribedEvents()
    {
        $actions = [
            ['setInstore', 200],
        ];

        if (findModule(\Modules::PRODUCTS, \Modules::SUB_SETS) === 'js_multisets') {
            $actions[] = ['calculateMultisetFromPrice', 200];
        }

        return [
            CronEvent::RUN_NORMAL => $actions,
        ];
    }

    public function setInstore(): void
    {
        $query = sqlQueryBuilder()
            ->update('products')
            ->set('in_store', ':inStore')
            ->andWhere('id = :idProduct');

        foreach ($this->multiSets->getInStore() as $inStore) {
            $query->setParameters([
                'idProduct' => $inStore['id_product'],
                'inStore' => $inStore['in_store'],
            ]);

            $query->execute();

            if (findModule(\Modules::STORES) && $mainStoreId = $this->storesInStore->getMainStoreId()) {
                $this->storesInStore->updateStoreItem(
                    [
                        'id_product' => $inStore['id_product'],
                        'id_variation' => null,
                        'id_store' => $mainStoreId,
                        'quantity' => $inStore['in_store'],
                    ], false);

                $this->storesInStore->recalcInStoreFromStores(
                    fn ($qb) => Operator::equals(['p.id' => $inStore['id_product']]),
                    // Vlastne nic nevyfiltruje, protoze ty setovy nemaj varianty, ale nechci ted upravovat vnitrek recalcInStoreFromStores
                    // aby se tam zbytecne nevolaly varianty, tak aspon takhle.
                    fn ($qb) => Operator::equals(['pv.id_product' => $inStore['id_product']]),
                );
            }
        }
    }

    public function calculateMultisetFromPrice(): void
    {
        $query = sqlQueryBuilder()
            ->update('products')
            ->set('price', ':newPrice')
            ->andWhere('id = :idProduct');

        foreach ($this->multiSets->getPriceFrom() as $multisetPrice) {
            $query->setParameters([
                'idProduct' => $multisetPrice['id_product'],
                'newPrice' => $multisetPrice['price'],
            ]);

            $query->execute();
        }
    }

    /**
     * @required
     */
    public function setStoresInStore(?StoresInStore $storesInStore): void
    {
        $this->storesInStore = $storesInStore;
    }
}
