<?php

namespace KupShop\OrderingBundle;

use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Price\Price;
use KupShop\KupShopBundle\Util\Price\PriceUtil;
use KupShop\OrderingBundle\Entity\Order;
use KupShop\OrderingBundle\Util\Order\OrderItemInfo;

class OrderDelivery
{
    private $contextManager;

    /**
     * @var OrderItemInfo
     */
    private $orderItemInfo;

    public function __construct(ContextManager $contextManager)
    {
        $this->contextManager = $contextManager;
    }

    /**
     * @required
     */
    public function setOrderItemInfo(OrderItemInfo $orderItemInfo)
    {
        $this->orderItemInfo = $orderItemInfo;
    }

    public function recalculateDelivery(\Order $order, $id_delivery)
    {
        return $this->contextManager->activateOrder($order, function () use ($order, $id_delivery) {
            if (findModule('deliveries')) {
                $delivery = $order->getDeliveryType($id_delivery)->getDelivery();
                $totalPriceForDelivery = \DecimalConstants::zero();
                // SUB_FREE_DELIVERY_NO_DISCOUNT - Počítá cenu pro dopravu zdarma před odečtením slev
                $free_delivery_no_discount = findModule(\Modules::DELIVERY_TYPES, \Modules::SUB_FREE_DELIVERY_NO_DISCOUNT);
                foreach ($order->fetchItems() as $item) {
                    $type = $this->orderItemInfo->getItemType($item);
                    if ($type == $this->orderItemInfo::TYPE_PRODUCT) {
                        $totalPriceForDelivery = $totalPriceForDelivery->add($item['total_price']['value_with_vat']);
                    }
                    if (!$free_delivery_no_discount && ($type == $this->orderItemInfo::TYPE_DISCOUNT || $type == $this->orderItemInfo::TYPE_COUPON)) {
                        $totalPriceForDelivery = $totalPriceForDelivery->add($item['total_price']['value_with_vat']);
                    }
                }

                // call accept on delivery before getPrice call
                $freeDelivery = returnSQLResult("SELECT oi.id FROM {$order->items_table} oi
				LEFT JOIN products p ON p.id=oi.id_product
				WHERE oi.id_order=:id_order AND FIND_IN_SET('Z', p.campaign) > 0", ['id_order' => $order->id]);
                $priceUtil = ServiceContainer::getService(PriceUtil::class);
                $delivery->accept(
                    new Price($totalPriceForDelivery, $priceUtil->getCurrencyById($order->currency), 0),
                    $freeDelivery
                );

                $delivery->getPrice();
                if ($delivery->exception) {
                    throw $delivery->exception;
                }
            }

            if ($order->changeDeliveryType($id_delivery)) {
                return true;
            }

            return false;
        });
    }

    public function getDeliveryTypePrice(Order $order)
    {
        foreach ($order->getItems() as $item) {
            if (!$item->getIdProduct() && $item->getPiecePrice()) {
                return $item->getPiecePrice();
            }
        }

        return \DecimalConstants::zero();
    }
}
