<?php

namespace CouponsPlus\App\Conditions\BuiltIn\Filters;

use CouponsPlus\App\Conditions\Filter;
use CouponsPlus\App\Conditions\CartItem;
use CouponsPlus\App\Conditions\ItemsSet;
use CouponsPlus\Original\Environment\Env;
use CouponsPlus\Original\Collections\Collection;
use CouponsPlus\App\Coupon\Tree\Data\SelectOption;
use CouponsPlus\App\Conditions\IntersectionFilter;
use CouponsPlus\App\Validators\InclusionValueValidator;
use CouponsPlus\App\Conditions\Utilities\ProductUtilities;
use CouponsPlus\App\Coupon\Tree\Data\Abilities\PreloadableData;

#[\AllowDynamicProperties]
Class InBrands extends Filter implements PreloadableData
{
	const TYPE = 'InBrands';
	const SET = IntersectionFilter::class;

	public static function getName() : string
	{
		return __('Brands', 'coupons-plus-for-woocommerce');
	}

	/**
	 * Examples:
	 *  VALID:
	 *   -allowed one category, not nmixed with other filter, pass many items of that (like 3) but the result will only contain 1
	 *   -MAXIMUM of 1 item, passed 3, the result is still one and valid.
	 *   -allowed 2 brands, not mixed with other filter (in the passed items example, only pass items from one category so as to make clear that is *either* category and not BOTH)
	 *   -allowed 2 categpries + quantity: 2 | pass 1 item of each to make clear they both sum 2 and thus they pass
	 *   -exclude category
	 *
	 *
	 *  INVALID
	 *   -allowed one catgeory, no items from that categpry were passed
	 *   -allowed one category + quantity: 2 | passed only 1
	 */
	public static function getDescription() : string
	{
		return '';
	}

	public static function getOptions() : Collection
	{
		return InclusionValueValidator::getOptions(
            $expectedValues = [
                'meta' => [
                    'name' => __('Brands', 'coupons-plus-for-woocommerce'),
                ],
                'allowed' => [
                    'type' => 'remote',
                    'category' => 'brands',
                    'where' => 'rest.WooCommerce',
                    'path' => 'products/brands',
                    'searchArgumentName' => 'search',
                    'excludeIdsArgumentName' => 'exclude',
                    'arguments' => [
                        'context' => 'edit',
                    ]
                ]
            ],
            $inclusionType = [
                'meta' => [
                    'extraLabels' => [
                        'allowed' => [
                            'placeholder' => __('Search brands to include...', 'coupons-plus-for-woocommerce'),
                            'aboveList' => __('Will pick items in any of these brands:', 'coupons-plus-for-woocommerce')
                        ],
                        'forbidden' => [
                            'placeholder' => __('Search brands to exclude...', 'coupons-plus-for-woocommerce'),
                            'aboveList' => __('Will pick items in any brands except these:', 'coupons-plus-for-woocommerce')
                        ]
                    ],
                    'notes' => [
                        'allowed' => [
                            'id' => 'InCategories.inclusionType',
                            'title' => __('Any combination of brands', 'coupons-plus-for-woocommerce'),
                            'content' => [
                                __('Will take any combination of products in the specified brands.', 'coupons-plus-for-woocommerce'),
                                __('Not all of the specified brands must be present in the cart, only one (or more) of them.', 'coupons-plus-for-woocommerce'),
                            ]
                        ],
                        'forbidden' => [
                            'id' => 'InCategories.inclusionType',
                            'title' => __('Any combination of brands except those specified', 'coupons-plus-for-woocommerce'),
                            'content' => [__('Will take products in any brands that are not in any of the specified brands.', 'coupons-plus-for-woocommerce')]
                        ],
                    ]
                ]
            ]
		);
	}

    public static function preloadedData() : Collection
    {
        return new Collection([
            'category' => 'brands',
            'data' => function (array $ids) : array {
                // convert the ids into formatted data from the database
                return Collection::create($ids)->map(function (int $id): SelectOption {
                    $term = get_term($id, 'product_brand');

                    return new SelectOption(
                        $id, // id
                        $id,// value
                        $term->name//label
                    );
                })->asArray();
            }
        ]);
    }


    public function onOptionsLoaded()
	{
		do_action(Env::getWithPrefix('IDsLoaded'), [
			'type' => 'productBrands',
			'ids' => $this->options->expectedValues
		]);
	}

	public function filterSet(ItemsSet $itemsSet) : ItemsSet
	{
		(object) $inclusionValueValidator = new InclusionValueValidator($this->options->asArray());

		return new ItemsSet($itemsSet->getItems()->filter(function(CartItem $cartItem) use ($inclusionValueValidator) : bool {
			(object) $originalFinalproductUtilities = new ProductUtilities($cartItem->getProductUtilities()->getOrignalFinalProduct());

			$inclusionValueValidator->setValueToValidate(
				$originalFinalproductUtilities->getAllTranslationBrandIdsWithAncestors()
			);


			return $inclusionValueValidator->isValid();
		})->asArray());
	}
}