<?php

namespace Planaday\Utility\FormBuilder\InputFields;

use Planaday\Utility\FormBuilder\DataType;
use Planaday\Utility\FormBuilder\DataTypes\IntType;
use Planaday\Utility\FormBuilder\InputField;

/**
 * @implements InputField<int|float>
 */
class NumberInput implements InputField {
	use BasicInputField;

	protected null|float|int $min = null;
	protected null|float|int $max = null;
	protected null|float|int $step = null;

	/**
	 * @param DataType<int|float> $type
	 */
	public function __construct(DataType $type = new IntType()) {
		$this->dataType = $type;
	}

	public function getMin(): null|int|float {
		return $this->min;
	}

	public function getMax(): null|int|float {
		return $this->max;
	}

	public function getStep(): null|int|float {
		return $this->step;
	}

	public function setMin(null|int|float $min): self{
		$this->min = $min;
		return $this;
	}

	public function setMax(null|int|float $max): self{
		$this->max = $max;
		return $this;
	}

	public function setStep(null|int|float $step): self{
		$this->step = $step;
		return $this;
	}

	public function setValue( mixed $value, bool $callSetCallback = true): void {
		$value = $this->dataType->sanitize($value);

		if (($this->min ?? null) !== null && $value < $this->min) {
			$value = $this->min;
		}
		if (($this->max ?? null) !== null && $value > $this->max) {
			$value = $this->max;
		}

		$this->value = $value;
		if ($this->setCallback !== null && $callSetCallback) ($this->setCallback)($this->value);
	}

	public function getImplJson(): array {
		return [
			"type" => 'number',
			"min" => $this->min,
			"max" => $this->max,
			"step" => $this->step,
		];
	}
}