<?php

namespace CouponsPlus\App\Coupon\Tree\Sets;

use CouponsPlus\App\Conditions\CartItem;
use CouponsPlus\App\Conditions\ItemsSet;
use CouponsPlus\App\Coupon\Tree\Sets\Abilities\CartItemValueStrategy;
use CouponsPlus\App\Coupon\Tree\Sets\Abilities\AscendingItemsSetSorterInterface;
use CouponsPlus\App\Coupon\Tree\Sets\Abilities\DescendingItemsSetSorterInterface;


class ItemsSetSorter implements AscendingItemsSetSorterInterface, DescendingItemsSetSorterInterface
{
    protected CartItemValueStrategy $cartItemValueStrategy;

    public function __construct(CartItemValueStrategy $cartItemValueStrategy)
    {
        $this->cartItemValueStrategy = $cartItemValueStrategy;
    }

    public function sortAscending(ItemsSet $itemsSet): array
    {
        return $this->orderItemsByPrice($itemsSet, false);
    }

    public function sortDescending(ItemsSet $itemsSet): array
    {
        return $this->orderItemsByPrice($itemsSet, true);
    }

    /**
     * Helper method for ordering items by price
     */
    protected function orderItemsByPrice(ItemsSet $itemsSet, bool $descendingOrder = false) : array
    {
        $lineItems = $itemsSet->getItems()->asArray();

        // Sort line items by their individual product price
        // Use the same sorting logic as the price sorters but work on line items directly
        usort($lineItems, function(CartItem $itemOne, CartItem $itemTwo) use ($descendingOrder) : int {
            $priceOne =  (string) $this->cartItemValueStrategy->getValue($itemOne);
            $priceTwo =  (string) $this->cartItemValueStrategy->getValue($itemTwo);

            $scale = $this->cartItemValueStrategy->getScale();

            // Check if we're using cheapest (ascending) or most expensive (descending) sorter
            return $descendingOrder
                ? bccomp($priceTwo, $priceOne, $scale)  // Most expensive first
                : bccomp($priceOne, $priceTwo, $scale); // Cheapest first
        });

        return $lineItems;

    }
}