<?php declare(strict_types = 1);

namespace idoit\Module\SyneticsFlows\Filter;

use idoit\Module\SyneticsFlows\Serialization\Serializer;

class AttributeFilter
{
    /**
     * @var string|null
     */
    private ?string $attribute = null;

    /**
     * @var CategoryFilter|null
     */
    private ?CategoryFilter $categoryFilter = null;

    private ?bool $excludeReadOnly = false;

    /**
     * @param string $id
     *
     * @return self
     */
    public static function factory(string $id): AttributeFilter
    {
        $filter = new self();
        [$category, $attribute] = explode('.', $id);

        $filter->setAttribute($attribute);
        $filter->setCategoryFilter($category);

        return $filter;
    }

    /**
     * @return string|null
     */
    public function getAttribute(): ?string
    {
        return $this->attribute;
    }

    /**
     * @param string $attribute
     *
     * @return $this
     */
    public function setAttribute(string $attribute): AttributeFilter
    {
        $this->attribute = $attribute;

        return $this;
    }

    /**
     * @param string $categoryConstant
     *
     * @return $this
     */
    public function setCategoryFilter(string $categoryConstant): AttributeFilter
    {
        $categoryFilter = new CategoryFilter();
        $categoryFilter->setCategories([$categoryConstant]);
        $this->categoryFilter = $categoryFilter;

        return $this;
    }

    /**
     * @return CategoryFilter|null
     */
    public function getCategoryFilter(): ?CategoryFilter
    {
        return $this->categoryFilter;
    }

    /**
     * @return bool|null
     */
    public function isExcludeReadOnly(): ?bool
    {
        return $this->excludeReadOnly;
    }

    /**
     * @param string|null $params
     *
     * @return AttributeFilter
     */
    public static function fromParams(?string $params): AttributeFilter
    {
        $result = new AttributeFilter();
        try {
            $result = Serializer::fromJson(AttributeFilter::class, json_decode($params, true));
        } catch (Throwable) {
            // fallback
        }
        return $result;
    }
}
