<?php

namespace CouponsPlus\App\Coupon;

use CouponsPlus\App\Conditions\ItemsSet;
use CouponsPlus\App\Coupon\Abilities\CouponModel;
use CouponsPlus\App\Coupon\Coupon;
use CouponsPlus\App\Coupon\Rows;
use CouponsPlus\App\Coupon\Tree\Factories\ConditionFilterOrOfferFromDataFactory;
use CouponsPlus\App\Coupon\Tree\Factories\OfferSetsFromDataFactory;
use CouponsPlus\App\Coupon\Tree\Finders\ProductionGroveOffersDataFinderFactory;
use CouponsPlus\App\Offers\Abilities\Offers;
use CouponsPlus\App\Offers\OffersSet;
use CouponsPlus\App\Offers\OffersSetCollection;
use CouponsPlus\Original\Environment\Env;

class RowsCouponModel implements CouponModel
{
    const TYPE = 'rows';

    private $coupon;
    protected $JSONOptions;

    public function __construct(Coupon $coupon)
    {
        $this->coupon = $coupon;

        $this->JSONOptions = json_decode(
            $this->coupon->getClassic()->get_meta(
                Env::getWithPrefix('rows')
            ) ?? '{}'
        );
    } 

    public function getModelType(): string
    {
        return static::TYPE;        
    } 

    public function hasConfigurationContent(): bool
    {
        if (!$this->hasRows() || empty($this->JSONOptions)) {
            return false;
        }

        return $this->JSONOptions !== '{}'; 
    } 

    /**
     * there's some duplication with the tree model, it was Copied as it was for backwards compatibility
     */
    public function isValid(): bool
    {
        (object) $offers = $this->getOffers();
        (boolean) $isInvalid = $offers->canBeApplied()? false : !$this->coupon->hasClassicDicounts();

        return !$isInvalid;
    } 

    /**
     * @return OffersSetCollection|OffersSet
     */
    public function getOffers()
    {
        return $this->getRows()->findOffers(ItemsSet::createFromAllCartItems());
    }

    /**
     * Get offers evaluated against order items instead of cart items.
     * Used when applying coupons in admin order editing context.
     */
    public function getOffersForOrder(\WC_Order $order): Offers
    {
        $orderItemsSet = ItemsSet::createFromOrderItems($order);

        return $this->getRows()->findOffers($orderItemsSet);
    }

    public function hasRows() : bool
    {
        return $this->getRows()->hasAny();   
    }

    protected function getRows() : Rows
    {
        return Rows::createFromOptions(
            $this->JSONOptions,
            $this->coupon->getClassic()
        );
    }
}