<?php

use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\OrderingBundle\Util\Order\OrderItemEditTrait;
use KupShop\OrderingBundle\Util\Order\OrderItemInfo;
use KupShop\OrderingBundle\Util\Order\ReplacementInfo;
use KupShop\OrderingBundle\Util\Order\ReplacementUtil;

$main_class = 'Replacement';

class Replacement extends Window
{
    use DatabaseCommunication;
    use OrderItemEditTrait;

    protected $replacementInfo;

    public function __construct()
    {
        $this->replacementInfo = ServiceContainer::getService(ReplacementInfo::class);
    }

    public function get_vars()
    {
        $vars = parent::get_vars();
        $ID = $this->getID();
        $products = [];
        $fields = 'oi.id, p.title as product_title, pv.title as variation_title, oi.id_product, oi.id_variation, oi.pieces, oi.piece_price, oi.total_price, oi.descr, oi.tax, oi.note as item_note, COALESCE(pv.ean, p.ean) ean';

        global $cfg;
        if (!empty($cfg['Modules']['products_variations']['variationCode'])) {
            $fields .= ', COALESCE(pv.code, p.code) code';
        } else {
            $fields .= ', p.code code';
        }

        if (!empty($cfg['Modules']['products']['note'])) {
            $fields .= ', COALESCE(pv.note, p.note) note_';
        } else {
            $fields .= ", '' as note_";
        }

        if (findModule('kupkolo')) {
            $order = 'oi.id_product IS NULL ASC, ABS(oi.total_price) DESC, oi.id';
        } else {
            $order = 'oi.id';
        }

        $SQL = sqlQuery("SELECT {$fields}
							FROM ".getTableName('order_items').' oi
							LEFT JOIN '.getTableName('products').' p ON p.id=oi.id_product
							LEFT JOIN '.getTableName('products_variations')." pv ON pv.id=oi.id_variation
							WHERE oi.id_order='".$ID."'
							ORDER BY {$order}");

        $p = new Product();

        foreach ($SQL as $row) {
            $item_note = $p->parseNote($row['item_note']);
            if (($item_note['item_type'] ?? '') == 'rounding') {
                continue;
            }
            $row['item_note'] = $p->printNote($item_note);
            $products[] = $row;
        }
        $order = new Order();
        $order->createFromDB($ID);

        $pageVars['data']['id'] = $ID;
        $pageVars['acn'] = 'return';
        $pageVars['data']['order_no'] = $order->order_no;
        $pageVars['data']['date_handle'] = $order->date_handle;
        $vars['products'] = $products;

        $pageVars['order'] = $order;

        if (findModule('price_levels')) {
            $pageVars['price_level'] = User::getUserPriceLevel($order->id_user);
        }

        if (findModule(Modules::RETURNS)) {
            $r = sqlQueryBuilder()->select('ri.id_return')
                ->from('order_items', 'oi')
                ->join('oi', 'return_items', 'ri', 'ri.id_item=oi.id')
                ->where(\Query\Operator::equals(['oi.id_order' => $order->id]))
                ->groupBy('ri.id_return')
                ->execute()
                ->fetchAllAssociative();
            $pageVars['existingReturnIds'] = $r;
        }

        $vars['body'] = $pageVars;

        return $vars;
    }

    public function handleReturn()
    {
        $replacementUtil = ServiceContainer::getService(ReplacementUtil::class);

        $data = $this->getData();

        if (findModule(Modules::RETURNS)) {
            /** @var \KupShop\ReturnsBundle\Util\ReturnsUtil $returnsUtil */
            $returnsUtil = ServiceContainer::getService(\KupShop\ReturnsBundle\Util\ReturnsUtil::class);
            $reasons = array_keys($returnsUtil->getReasons());
            $reasonId = end($reasons);
            $order = $this->prepareOrder($this->getID());

            $returnItems = [];
            $replacementItems = [];
            foreach ($data['items'] as $key => $item) {
                if ($key > 0 && $item['pieces'] > 0) {
                    $item['return_reason'] = $reasonId;
                    $returnItems[$key] = $item;
                } elseif ($key < 0 && empty($item['delete'])) {
                    $replacementItems[] = [
                        'id_product' => $item['id_product'],
                        'id_variation' => empty($item['id_variation']) ? null : $item['id_variation'],
                        'pieces' => $item['pieces'],
                    ];
                }
            }
            if (empty($returnItems)) {
                $this->redirect(['ErrStr' => 'Nejsou zadány produkty k vrácení', 'acn' => 'add']);
            }

            $returnId = $returnsUtil->createReturn('', $returnItems, $replacementItems, 'Vratka vytvořena z objednávky č. '.$order->order_no, false);

            $returnsUtil = ServiceContainer::getService(\KupShop\ReturnsBundle\Util\ReturnsUtil::class);
            $returnsUtil->recalculate($returnId);

            $return = $returnsUtil->getReturn($returnId);
            if ($return->isReplacement()) {
                $returnsUtil->createOrder($return);
            }

            $this->redirect(['s' => 'Returns.php', 'acn' => 'edit', 'ID' => $returnId]);
        }

        $order = $replacementUtil->createReturnOrder($this->getID(), $data['items'], $data['products'] ?? []);

        $this->redirect(['s' => 'orders.php', 'acn' => 'edit', 'ID' => $order->id, 'force_resize' => '1']);
    }

    public function handleReturnAll()
    {
        $replacementUtil = ServiceContainer::getService(ReplacementUtil::class);

        if (findModule(Modules::RETURNS)) {
            /** @var \KupShop\ReturnsBundle\Util\ReturnsUtil $returnsUtil */
            $returnsUtil = ServiceContainer::getService(\KupShop\ReturnsBundle\Util\ReturnsUtil::class);

            $deliveryInfo = ServiceContainer::getService(\KupShop\OrderingBundle\Util\Order\DeliveryInfo::class);
            $order = new \Order();
            $order->createFromDB($this->getID());
            $deliveryItem = $deliveryInfo->getDeliveryItem($order);

            $returnId = sqlGetConnection()->transactional(function () use ($deliveryItem, $returnsUtil) {
                $qb = sqlQueryBuilder()->select('oi.id, oi.pieces')->from('order_items', 'oi')
                    ->where(\Query\Operator::equals(['oi.id_order' => $this->getID()]))
                    ->andWhere("NOT COALESCE(JSON_CONTAINS(oi.note, '\"".OrderItemInfo::TYPE_ROUNDING."\"', '$.item_type'), FALSE)");

                $reasons = array_keys($returnsUtil->getReasons());
                $reasonId = end($reasons);

                $items = [];
                foreach ($qb->execute()->fetchAll() as $item) {
                    // Skip delivery - will add later
                    if ($deliveryItem == $item['id']) {
                        continue;
                    }

                    if ($item['pieces'] > 0) {
                        $item['return_reason'] = $reasonId;
                        $items[$item['id']] = $item;
                    }
                }

                $order = $this->prepareOrder($this->getID());

                return $returnsUtil->createReturn(
                    '',
                    $items,
                    [],
                    'Vratka vytvořena z objednávky č. '.$order->order_no,
                    false
                );
            });

            // Oznacim si ze vracim vse, abych vedel, ze mam vratit i postovny
            if ($deliveryItem) {
                $returnsUtil->getReturn($returnId)->setCustomDataValue('return_delivery', true);
            }

            $returnsUtil = ServiceContainer::getService(\KupShop\ReturnsBundle\Util\ReturnsUtil::class);
            $returnsUtil->recalculate($returnId);
            $this->redirect(['s' => 'Returns.php', 'acn' => 'edit', 'ID' => $returnId]);
        }

        $order = $replacementUtil->createOrder($this->getID());
        $replacementUtil->orderChangeStatus($this->getID(), $order);

        sqlGetConnection()->transactional(function () use ($order, $replacementUtil) {
            $query = 'SELECT oi.id_product, oi.id_variation, oi.pieces, oi.note, oi.descr, oi.piece_price, oi.total_price, tax
	                    FROM '.getTableName('order_items')." oi
	                    WHERE oi.id_order={$this->getID()} AND oi.total_price > 0";
            $SQL = sqlQuery($query);

            foreach ($SQL as $row) {
                if (!empty($row['id_product'])) {
                    $replacementUtil->returnItem($order, $row);
                } else {
                    $order->insertNonItem($order->id, -$row['total_price'], $row['piece_price'], -$row['pieces'], $row['tax'], $row['descr'], $row['note']);
                }
            }

            $order->recalculate();
        });

        $this->redirect(['s' => 'orders.php', 'acn' => 'edit', 'ID' => $order->id, 'force_resize' => '1']);
    }

    public function prepareOrder($orderId)
    {
        $order = new Order();
        $order->createFromDB($orderId);

        return $order;
    }

    /*
     * Hotfix, aby když je zapnutej novej modul vratky, tak šly otevřit vratky i bez starýho
     * - bez tohohle to vrací "nemá dostatečný práva", protože neni zapnutej starej modul.
     * */
    public function tryRights($acn = '')
    {
        if (findModule(Modules::RETURNS)) {
            return;
        }

        parent::tryRights($acn);
    }
}
