<?php

namespace Planaday\Config\OptionTypes;

/**
 * @template T
 * @template TDefault
 */
abstract class Option {
	/** @var string */
	protected $index;

	/** @var string */
	protected $title;

	/** @var string */
	protected $description;

	/** @var null|T */
	protected $value;

	/** @var TDefault */
	protected $defaultValue;

	/**
	 * @param string $index
	 * @param string $title
	 * @param string $description
	 * @param null|T $value
	 * @param TDefault $defaultValue
	 */
	public function __construct(string $index, string $title, string $description, $value, $defaultValue ) {
		$this->index       = $index;
		$this->title       = $title;
		$this->description = $description;
		$this->value        = $value;
		$this->defaultValue = $defaultValue;
	}

	abstract function getType(): string;

	public function getIndex(): string {
		return $this->index;
	}

	public function getTitle(): string {
		return $this->title;
	}

	public function getDescription(): string {
		return $this->description;
	}

	/**
	 * @template TDefaultOverride
	 * @param TDefaultOverride $defaultOverride
	 *
	 * @return (TDefaultOverride is null ? T|TDefault : T|TDefaultOverride)
	 */
	public function getValue($defaultOverride = null) {
		return $this->value ?? $defaultOverride ?? $this->defaultValue;
	}

	/**
	 * @return TDefault
	 */
	public function getDefaultValue() {
		return $this->defaultValue;
	}

	public function isSet():bool {
		return $this->value !== null;
	}

	/**
	 * @param T $newValue
	 *
	 * @return void
	 */
	public function updateValue($newValue):void {
		$this->value = $newValue;
	}
}