<?php

namespace KupShop\OrderDiscountBundle\Actions;

use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\OrderDiscountBundle\Entity\OrderDiscount;
use KupShop\OrderingBundle\Entity\Purchase\DiscountPurchaseItem;
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;

class NthProductAction extends CheapestProductAction
{
    protected static $type = 'nth_product_discount';
    protected static $position = 36;
    protected $adminTemplate = 'actions/nth_product_discount.tpl';

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

        $n = $data['n'];
        $total_count = ($data['total_count'] ?? false);
        if ($total_count == 'Y') {
            $totalPieces = 0;
            foreach ($items as $purchaseItem) {
                $totalPieces += $purchaseItem->getPieces();
            }

            if ($totalPieces < $n) {
                $items = [];
            }
        } else {
            foreach ($items as $key => $purchaseItem) {
                if ($purchaseItem->getPieces() < $n) {
                    unset($items[$key]);
                }
            }
        }

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

            $totalDiscountPrice = toDecimal(0);
            if ($total_count == 'Y') {
                $items = $this->sortByProductPrice($items);
                $m = intdiv($totalPieces, $n);
                while ($m > 0) {
                    $cheapest = array_shift($items);
                    $pieces = $cheapest->getPieces();
                    if ($pieces <= $m) {
                        $m -= $pieces;
                    } else {
                        $pieces = $m;
                        $m = 0;
                    }

                    $discountPrice = $this->discountUtil->calculateDiscountPrice($this->getProductPrice($cheapest)->mul(toDecimal($pieces)), $data);
                    if ($discountPrice) {
                        $totalDiscountPrice = $totalDiscountPrice->add($discountPrice);
                    }
                }
            } else {
                foreach ($items as $purchaseItem) {
                    $pieces = $purchaseItem->getPieces();
                    $pieces = intdiv($pieces, $n);

                    $discountPrice = $this->discountUtil->calculateDiscountPrice($this->getProductPrice($purchaseItem)->mul(toDecimal($pieces)), $data);
                    if ($discountPrice) {
                        $totalDiscountPrice = $totalDiscountPrice->add($discountPrice);
                    }
                }
            }

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

                $totalDiscountPrice = $this->discountUtil->divideDiscountPrice($discount_items, $data, $discountName);
            }

            if (!$totalDiscountPrice->isZero()) {
                $discountPurchaseItem = new DiscountPurchaseItem(
                    $discountName,
                    $this->discountUtil->createDiscountPrice($totalDiscountPrice),
                    $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;
            }
        }
    }
}
