<?php

declare(strict_types=1);

namespace External\ZNZBundle\Overrides\EventSubscriber;

use KupShop\OrderingBundle\Event\OrderItemEvent;
use Query\Operator;

/**
 * Override of `\KupShop\OrderingBundle\EventListener\OrderItemListener`.
 */
class OrderItemSubscriber extends \KupShop\OrderingBundle\EventListener\OrderItemListener
{
    /**
     * Produktovy set nerozdelujeme. Pouze si k hlavnimu produktu setu ulozime info pro synchronizaci, ale pro e-shop
     * zustava set jako jedna polozka.
     */
    protected function SplitSetItemDefault(OrderItemEvent $event)
    {
        $product = $event->getProduct();
        $product->fetchSets(true);

        if (!$product->sets) {
            return;
        }

        $data = $event->getData();
        $row = $data['row'];

        $itemRow = sqlQueryBuilder()
            ->select('*')
            ->from('order_items')
            ->where(Operator::equals(['id' => $row['id']]))
            ->sendToMaster()
            ->execute()->fetchAssociative();

        $itemPieces = toDecimal($row['pieces']);
        $totalPiecePriceOriginal = toDecimal($itemRow['piece_price'])->addVat($itemRow['tax']);

        $setPriceRates = $product->getData()['setInfo']['setPrices'] ?? [];

        $setData = [];
        // pripravim si set data, ktere ulozim k produktu - abych to potom mohl pouzit v synchronizaci
        foreach ($product->sets as $setProduct) {
            $setKey = $setProduct->id;
            if ($setProduct instanceof \Variation) {
                $setKey .= '/'.$setProduct->variationId;
            }

            $setPieces = toDecimal($setProduct['set_pieces'])->mul($itemPieces);
            $setPiecePrice = \DecimalConstants::zero();
            if ($priceRate = ($setPriceRates[$setKey] ?? null)) {
                $setPiecePrice = $totalPiecePriceOriginal->mul(toDecimal($priceRate))->div(toDecimal($setProduct['set_pieces']));
            }

            $setData[$setKey] = [
                'pieces' => $setPieces,
                'piecePrice' => $setPiecePrice->asFloat(),
                'totalPrice' => $setPiecePrice->mul($setPieces)->asFloat(),
            ];
        }

        // aktualizuju note field na polozce objednavky
        sqlGetConnection()->transactional(function () use ($row, $setData) {
            $itemData = sqlQueryBuilder()
                ->select('note')
                ->from('order_items')
                ->where(Operator::equals(['id' => $row['id']]))
                ->execute()->fetchOne();

            $itemData = json_decode($itemData ?: '', true) ?: [];

            $itemData['setData'] = $setData;

            sqlQueryBuilder()
                ->update('order_items')
                ->directValues(['note' => json_encode($itemData)])
                ->where(Operator::equals(['id' => $row['id']]))
                ->execute();
        });
    }
}
