<?php

namespace Planaday\Utility\FormBuilder\Conditions;

use Planaday\Utility\FormBuilder\Condition;
use Planaday\Utility\FormBuilder\InputField;

class InputValueCondition implements Condition {

	protected mixed $targetValue = null;
	protected bool $equals = false;
	protected bool $strict = false;
	protected bool $greaterThan = false;
	protected bool $smallerThan = false;
	protected bool $not = false;
	protected bool $fallbackOutcome = true;

	public function __construct(
		protected InputField $input
	) {}

	public function value(mixed $targetValue): static{
		$this->targetValue = $targetValue;
		return $this;
	}

	public function strict(): static{
		$this->strict = true;
		return $this;
	}

	public function equals(): static{
		$this->equals = true;
		return $this;
	}

	public function greaterThan(): static{
		$this->greaterThan = true;
		return $this;
	}

	public function smallerThan(): static{
		$this->smallerThan = true;
		return $this;
	}

	public function not(): static{
		$this->not = true;
		return $this;
	}

	public function check(): bool {
		$value = $this->input->getValue();

		$result = true;

		if ($this->equals) {
			if ($this->strict) {
				$result = $value === $this->targetValue;
			} else {
				$result = $value == $this->targetValue;
			}
		}

		if ($this->greaterThan) {
			$result = $result && $value > $this->targetValue;
		}

		if ($this->smallerThan) {
			$result = $result && $value < $this->targetValue;
		}

		if ($this->not) {
			$result = !$result;
		}

		return $result;
	}

	/**
	 * Set whether the condition should return true or false if the input is filtered out
	 */
	public function setFallbackOutcome( bool $fallbackOutcome ): static {
		$this->fallbackOutcome = $fallbackOutcome;
		return $this;
	}

	public function jsonSerialize(): array {
		if ( !$this->input->isPastFilter() ){
			return [
				'type' => 'condition',
				'value' => $this->fallbackOutcome
			];
		}

		return [
			'type' => 'inputValueCondition',
			'targetValue' => $this->targetValue,
			'equals' => $this->equals,
			'strict' => $this->strict,
			'greaterThan' => $this->greaterThan,
			'smallerThan' => $this->smallerThan,
			'not' => $this->not,
			'field' => $this->input->getItemId()
		];
	}
}