<?php

namespace CouponsPlus\App\Offers;

use CouponsPlus\App\Offers\Offer;
use CouponsPlus\Original\Collections\Collection;
use CouponsPlus\Original\Environment\Env;
use CouponsPlus\Original\Utilities\TypeChecker;
use CouponsPlus\App\Coupon\Abilities\DashboardCardData;

#[\AllowDynamicProperties]
Class OffersRegistrator
{
    use TypeChecker;

    private static $instance;

    private $offers = [];
    protected $stubs = [];

    public static function get()
    {
        if (!static::$instance) {
            static::$instance = new static;
        }

        return static::$instance;   
    }

    public function all()
    {
        return new Collection($this->offers);   
    }

    public function nonImplementedStubs()
    {
        return (new Collection($this->stubs))->filter(function (string $StubClass) : bool {
            return !$this->all()->hasKey(constant($StubClass . '::TYPE'));
        });

    }

    protected function __construct()
    {
        do_action(Env::idLowerCase(). '_register_offer_component', $this);
    }

    public function register(string $Offer)
    {
        $this->offers[$Offer::TYPE] = $this->expect($Offer)
                                           ->toBe(Offer::class);
    }

    public function registerStub(string $Offer)
    {
        $this->stubs[$Offer::TYPE] = $this->expect($Offer)
                                           ->toBe(DashboardCardData::class);
    }

    public function getOffersThatAlwaysRequireCheapestItemsFirst() : Collection
    {
        return $this->all()->filter(function (string $Offer) : bool {
            return $Offer::ITEMS_SET_REQUIRED_ORDER === Offer::ITEMS_SET_ORDER_CHEAPEST_FIRST;
        });
    }
}