<?php

namespace KupShop\OrderDiscountBundle\Actions;

use KupShop\AdminBundle\Admin\ProductsFilter;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\OrderDiscountBundle\Entity\OrderDiscount;
use KupShop\OrderDiscountBundle\Util\DiscountUtil;
use KupShop\OrderingBundle\Entity\Purchase\DiscountPurchaseItem;
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;
use KupShop\OrderingBundle\Util\Purchase\PurchaseUtil;

class CheapestProductAction extends AbstractAction
{
    protected static $type = 'cheapest_product_discount';
    protected static $position = 35;
    protected $adminTemplate = 'actions/product_discount.tpl';

    protected $purchaseUtil;
    protected $discountUtil;

    public function __construct(PurchaseUtil $purchaseUtil, DiscountUtil $discountUtil)
    {
        $this->purchaseUtil = $purchaseUtil;
        $this->discountUtil = $discountUtil;
    }

    public function applyResult(PurchaseState &$purchaseState, OrderDiscount $orderDiscount, array $data)
    {
        $items = $this->purchaseUtil->getProductsApplicableByProductsFilter($purchaseState, $data['filter']);

        if (!empty($items)) {
            $data['id'] = $orderDiscount->getId();
            $discountName = $orderDiscount->getDisplayName();
            $note = $this->createItemNote($data, $discountName);
            $items = $this->sortByProductPrice($items);
            $cheapest = reset($items);

            $discountPrice = $this->discountUtil->calculateDiscountPrice($this->getProductPrice($cheapest), $data);

            if ($this->getDivideDiscountPrice($data)) {
                $data['unit'] = Contexts::get(CurrencyContext::class)->getActiveId();
                $data['discount'] = $discountPrice;

                $discountPrice = $this->discountUtil->divideDiscountPrice([$cheapest], $data, $discountName);
            }

            if ($discountPrice) {
                $discountPurchaseItem = new DiscountPurchaseItem(
                    $discountName,
                    $this->discountUtil->createDiscountPrice($discountPrice, $data['vat'] ?? null),
                    $orderDiscount->getId(),
                    $note
                );

                $purchaseState->addDiscount($discountPurchaseItem);

                if ($message = $data['messages']['success'] ?? '') {
                    $this->messages['success'] = $message;
                }
            }
        } else {
            if ($message = $data['messages']['warning'] ?? '') {
                $this->messages['warning'] = $message;
            }
        }
    }

    protected function sortByProductPrice($products)
    {
        uasort($products, function ($a, $b) {
            return $this->getProductPrice($a)->comp($this->getProductPrice($b));
        });

        return $products;
    }

    protected function getProductPrice($product): \Decimal
    {
        return $product->getPriceWithDiscountsWithVat()->div(toDecimal($product->getPieces()));
    }

    protected function getVars($vars): array
    {
        $vars = parent::getVars($vars);

        $vars['vats'] = \KupShop\KupShopBundle\Context\VatContext::getAdminVats();

        return $vars;
    }

    public function handleData($data)
    {
        $data = parent::handleData($data);
        $data['filter'] = ProductsFilter::cleanFilter($data['filter'] ?? []);

        return $data;
    }
}
