<?php

namespace CouponsPlus\App\Coupon\Tree\Factories;

use AllowDynamicProperties;
use CouponsPlus\App\Conditions\BuiltIn\Filters\NoItems;
use CouponsPlus\App\Coupon\CardData;
use CouponsPlus\App\Coupon\TestableData;
use CouponsPlus\App\Coupon\Tree\Abilities;
use CouponsPlus\App\Coupon\Tree\Abilities\ErrorHandler;
use CouponsPlus\App\Coupon\Tree\Factories\ConditionFilterOrOfferFromDataFactory;
use CouponsPlus\App\Coupon\Tree\Factories\ContextFromTestableGroupDataFactory;
use CouponsPlus\App\Coupon\Tree\Factories\FilterableGroupFactory;
use CouponsPlus\App\Coupon\Tree\Factories\OnErrorJSONFactory;
use CouponsPlus\App\Coupon\Tree\Factories\TestableGroupDataFromJSONFactory;
use CouponsPlus\App\Coupon\Tree\Factories\TestableGroupDataFromStandardObjectFactory;
use CouponsPlus\App\Coupon\Tree\Factories\TestableGroupFactoryFromData;
use CouponsPlus\App\Coupon\Tree\TestableGroup;
use CouponsPlus\App\Coupon\Tree\TestableGroupData;
use CouponsPlus\Original\Collections\MappedObject;
use WC_Coupon;

#[AllowDynamicProperties]
class StandaloneProductionTestableGroupFactory
{
    public function __construct(WC_Coupon $classicCoupon)
    {
        $this->testableGroupDataFactory = new OnErrorJSONFactory(
            new TestableGroupDataFromJSONFactory(
                new TestableGroupDataFromStandardObjectFactory
            )
        );

        $this->testableGroupFactory = new TestableGroupFactoryFromData(
            new FilterableGroupFactory,
            new ContextFromTestableGroupDataFactory(
                new ConditionFilterOrOfferFromDataFactory($classicCoupon)
            )
        );

        $this->testableGroupDataFactory->setErrorHandler(new Class Implements ErrorHandler {
            public function onError(\Throwable $exception) : Abilities\TestableGroupData
            {
                return new TestableGroupData(
                    $type = 'AND',
                    $mode = 'filter',
                    $children = [
                        new TestableGroupData(
                            $type = 'context',
                            $mode = 'filter',
                            $children = [
                                new TestableData(
                                    $testableType = 'filter',
                                    new CardData(
                                        $type = NoItems::TYPE,
                                        $options = new MappedObject([])
                                    )
                                )
                            ]
                        ),
                    ]
                );
            } 
        });        
    } 

    public function create(string $json) : TestableGroup
    {
        return $this->testableGroupFactory->create(
            $this->testableGroupDataFactory->create(
                $json
            )
        );
    }
}