<?php

declare(strict_types=1);

namespace ShopManagerPro\Filters\DTO\Generated;

class Filter {
	private static array $schema = ['type' => 'object', 'additionalProperties' => false, 'required' => ['id', 'name', 'conditions'], 'properties' => ['id' => ['type' => 'integer'], 'name' => ['type' => 'string'], 'conditions' => ['type' => 'array', 'items' => ['type' => 'object', 'additionalProperties' => false, 'required' => ['field', 'operator', 'value', 'not', 'combinator', 'enabled'], 'properties' => ['field' => ['type' => 'object', 'additionalProperties' => false, 'required' => ['type', 'key'], 'properties' => ['type' => ['type' => 'string', 'enum' => ['acf', 'basic', 'defaultTaxonomy', 'germanMarket', 'customMeta', 'productAttribute']], 'key' => ['type' => 'string']]], 'operator' => ['type' => 'string', 'enum' => ['contains', 'empty', 'ends_with', 'equals', 'greater_than_or_equal', 'greater_than', 'in', 'less_than_or_equal', 'less_than', 'starts_with']], 'value' => ['type' => ['string', 'number', 'boolean', 'array', 'null']], 'not' => ['type' => 'boolean'], 'combinator' => ['type' => 'string', 'enum' => ['AND', 'OR']], 'enabled' => ['type' => 'boolean']]]]]];
	private int $id;
	private string $name;
	private array $conditions;

	public function __construct(int $id, string $name, array $conditions) {
		$this->id = $id;
		$this->name = $name;
		$this->conditions = $conditions;
	}

	public function getId(): int {
		return $this->id;
	}

	public function getName(): string {
		return $this->name;
	}

	public function getConditions(): array {
		return $this->conditions;
	}

	public function withId(int $id): self {
		$validator = new \JsonSchema\Validator();
		$validator->validate($id, self::$schema['properties']['id']);
		if (!$validator->isValid()) {
			throw new \InvalidArgumentException($validator->getErrors()[0]['message']);
		} $clone = clone $this;
		$clone->id = $id;

		return $clone;
	}

	public function withName(string $name): self {
		$validator = new \JsonSchema\Validator();
		$validator->validate($name, self::$schema['properties']['name']);
		if (!$validator->isValid()) {
			throw new \InvalidArgumentException($validator->getErrors()[0]['message']);
		} $clone = clone $this;
		$clone->name = $name;

		return $clone;
	}

	public function withConditions(array $conditions): self {
		$clone = clone $this;
		$clone->conditions = $conditions;

		return $clone;
	}

	public static function buildFromInput(array|object $input, bool $validate = true): Filter {
		$input = is_array($input) ? \JsonSchema\Validator::arrayToObjectRecursive($input) : $input;
		if ($validate) {
			static::validateInput($input);
		} $id = (int) $input->{'id'};
		$name = $input->{'name'};
		$conditions = array_map(fn (array|object $i): FilterConditionsItem => FilterConditionsItem::buildFromInput($i, validate: $validate), $input->{'conditions'});
		$obj = new self($id, $name, $conditions);

		return $obj;
	}

	public function toJson(): array {
		$output = [];
		$output['id'] = $this->id;
		$output['name'] = $this->name;
		$output['conditions'] = array_map(fn (FilterConditionsItem $i) => $i->toJson(), $this->conditions);

		return $output;
	}

	public static function validateInput(array|object $input, bool $return = false): bool {
		$validator = new \JsonSchema\Validator();
		$input = is_array($input) ? \JsonSchema\Validator::arrayToObjectRecursive($input) : $input;
		$validator->validate($input, self::$schema);
		if (!$validator->isValid() && !$return) {
			$errors = array_map(function (array $e): string { return $e['property'].': '.$e['message']; }, $validator->getErrors());
			throw new \InvalidArgumentException(join(', ', $errors));
		}

return $validator->isValid();
	}

	public function __clone() {
		$this->conditions = array_map(fn (FilterConditionsItem $i) => clone $i, $this->conditions);
	}
}
