<?php

declare(strict_types=1);

namespace External\PompoBundle\Resources\script;

use KupShop\AdminBundle\Util\Script\Script;
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Price\Price;
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
use KupShop\OrderingBundle\OrderList\OrderList;
use Query\Operator;
use Query\QueryBuilder;

class FixRemovedItemsScript extends Script
{
    protected static $name = '[pompo] Opravit polozky v objednavkach';

    protected function run(array $arguments)
    {
        $orderList = ServiceContainer::getService(OrderList::class);
        $orderList
            ->fetchItems()
            ->andSpec(function (QueryBuilder $qb) {
                $qb->join('o', 'orders_history', 'oh', 'oh.id_order = o.id');

                return Operator::like(['oh.comment' => '%Změny položek v objednávce%']);
            });

        foreach ($orderList->getOrders() as $order) {
            $originalStates = $order->getData('orderOriginalStates');
            if (empty($originalStates)) {
                continue;
            }

            $originalState = reset($originalStates);
            if (empty($originalState)) {
                continue;
            }

            $updated = false;

            // insert items
            foreach ($originalState as $item) {
                // pokud polozka uz existuje, tak ji skipnu
                if ($order->fetchItems()[$item['id']] ?? false) {
                    continue;
                }

                $totalPrice = $item['price'] ?? null;
                $vat = $item['vat'] ?? null;
                if ($totalPrice === null && $item['productId']) {
                    $productPrice = $this->getProductPrice($order, $item['productId']);
                    $totalPrice = $productPrice->getPriceWithoutVat()->mul(toDecimal($item['pieces']))->asFloat();
                    $vat = $productPrice->getVat();
                }

                sqlQueryBuilder()
                    ->insert('order_items')
                    ->directValues(
                        [
                            'id' => $item['id'],
                            'id_order' => $order->id,
                            'id_product' => $item['productId'],
                            'id_variation' => null,
                            'pieces' => $item['pieces'],
                            'pieces_reserved' => $item['pieces'],
                            'piece_price' => toDecimal($totalPrice)->div(toDecimal($item['pieces'])),
                            'total_price' => $totalPrice,
                            'tax' => $vat,
                            'descr' => $item['name'],
                        ]
                    )->execute();

                $updated = true;
            }

            if ($updated) {
                $order->recalculate();
            }
        }
    }

    private function getProductPrice(\Order $order, int $productId): Price
    {
        $price = $this->getContextManager()->activateOrder($order, function () use ($productId) {
            $product = new \Product();
            $product->createFromDB($productId);

            return $product->getProductPrice();
        });

        return PriceCalculator::convert($price, Contexts::get(CurrencyContext::class)->getOrDefault($order->getCurrency()));
    }

    private function getContextManager(): ContextManager
    {
        static $contextManager;

        if (!$contextManager) {
            $contextManager = ServiceContainer::getService(ContextManager::class);
        }

        return $contextManager;
    }
}

return FixRemovedItemsScript::class;
