<?php

namespace CouponsPlus\App\Coupon\Tree\ItemSetsToDiscount;

use CouponsPlus\App\Conditions\ItemsSet;
use CouponsPlus\App\Coupon\Tree\Abilities\ItemToDiscount;

class ItemsSetToDiscount
{
    /**
     * @readonly
     */
    public ItemsSet $itemsSet;
    /**
     * @readonly
     */
    public ItemToDiscount $productToDiscount;

    public function __construct(ItemsSet $itemsSet, ItemToDiscount $productToDiscount)
    {
        $this->itemsSet = $itemsSet;
        $this->productToDiscount = $productToDiscount;
    }

    /**
     * This wil check if the items in the set fill the desired discount quantity.
     * eg: if we want to discount 3 items, and we have 2, this will return false.
     */
    public function canFillTheRequiredQuantity() : bool
    {
        return $this->productToDiscount->getDiscountOptions()->canFillQuantity($this->itemsSet->getTotalQuantity());
    }

    public function canPartiallyFillTheRequiredQuantity() : bool
    {
        if (!$this->itemsSet->getTotalQuantity()) {
            return false;
        }

        // ok so the itemsset does have items!
        return $this->areMissing();

    }

    public function getMissingQuantity() : int
    {
        /**
         * Always return 0 even if we have more then the required quantity.
         */
        if ($this->canFillTheRequiredQuantity()) {
            return 0;
        }

        if (is_int($this->productToDiscount->getDiscountOptions()->quantity)) {
            // should be changed later to support more types
            return $this->productToDiscount->getDiscountOptions()->quantity - $this->itemsSet->getTotalQuantity();
        }
        // again to be changed later
        return 0;
    }

    public function getItemSetWithExactQuantityRequired(): ItemsSet
    {
        if ($this->canFillTheRequiredQuantity()) {
            // only get the actual quantity needed for discounting
            if (is_int($this->productToDiscount->getDiscountOptions()->quantity)) {
                if ($this->itemsSet->getTotalQuantity() === $this->productToDiscount->getDiscountOptions()->quantity) {
                    return $this->itemsSet;
                }
            } else {
                // this is advanced, and so the quantity varies, for now we only support "any"
                return $this->itemsSet;
            }
        }

        return new ItemsSet([]);
    }

    public function areMissing(): bool
    {
        if (is_int($this->productToDiscount->getDiscountOptions()->quantity)) {
            return $this->itemsSet->getTotalQuantity() < $this->productToDiscount->getDiscountOptions()->quantity;
        }

        // should be changed later to support more types
        return false;
    }
}