<?php

namespace Simplyin\Simplyin_W_Plugin\Admin\Template_Components;

class Select {

	/**
	 * @var Select_Item[]
	 */
	private array $options = [];

	private array $available_options = [];

	private array $selected_options = [];

	private string $label;
	private string $name;
	private string $option_id;
	private string $class       = '';
	private string $label_class = '';
	private bool $value_as_key  = false;
	private bool $multiple      = false;


	public function __construct() {
	}

	/**
	 * @return array
	 */
	public function get_options(): array {
		return $this->options;
	}

	public function get_available_options(): array {
		return $this->available_options;
	}

	public function get_selected_options(): array {
		return $this->selected_options;
	}

	private function map_options( $value_as_key = false ) {
		foreach ( $this->available_options as $key => $value ) {
			if ( in_array( $value_as_key ? $value : $key, $this->selected_options, true ) ) {
				$this->options[ $value_as_key ? $value : $key ] = new Select_Item(
					$key,
					$value,
					true
				);
			} else {
				$this->options[ $value_as_key ? $value : $key ] = new Select_Item(
					$key,
					$value,
					false
				);
			}
		}
	}

	public function print_html( bool $return = false ): string {
		$this->map_options();
		$multiple_val = $this->is_multiple();

		$output = sprintf(
			'<select name="%s" id="%s" class="%s" %s>',
			$this->get_field_name(),
			$this->get_name(),
			$this->get_class(),
			$multiple_val ? sprintf( 'multiple="%s"', true ) : ''
		);

		foreach ( $this->get_options() as $option ) {
			$output .= sprintf(
				'<option value="%s" %s >%s</option>',
				$option->get_id(),
				$option->print_selected(),
				$option->get_name(),
			);
		}

		$output .= '</select>';

		if ( $return ) {
			return $output;
		}

		echo wp_kses(
			$output,
			[
				'select' => [
					'name'     => [],
					'id'       => [],
					'class'    => [],
					'multiple' => [],
				],
				'option' => [
					'value'    => [],
					'selected' => [],
				],
			]
		);

		return '';
	}

	public function print_label_html( bool $return = false ): string {
		$output = sprintf(
			'<label for="%s" class="%s simply_mapping_label">%s</label>',
			$this->get_name(),
			$this->get_label_class(),
			$this->get_label()
		);

		if ( $return ) {
			return $output;
		}

		echo wp_kses(
			$output,
			[
				'label' => [
					'for'   => [],
					'class' => [],
				],
			]
		);

		return '';
	}

	private function get_field_name(): string {
		$name = $this->get_name();
		if ( $this->is_multiple() ) {
			$name .= '[]';
		}

		return $name;
	}


	public function get_label(): string {
		return $this->label;
	}

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

	public function get_class(): string {
		if ( '' === $this->class ) {
			return sanitize_html_class( sprintf( '%s_select', $this->name ) );
		}

		return $this->class;
	}

	public function get_label_class(): string {

		if ( '' === $this->label_class ) {
			return sanitize_html_class( sprintf( '%s_label', $this->name ) );
		}

		return $this->label_class;
	}

	public function is_value_as_key(): bool {
		return $this->value_as_key;
	}

	public function is_multiple(): bool {
		return $this->multiple;
	}

	public function set_multiple( bool $multiple ): void {
		$this->multiple = $multiple;
	}

	public function set_value_as_key( bool $value_as_key ): void {
		$this->value_as_key = $value_as_key;
	}

	public function set_label_class( string $label_class ): void {
		$this->label_class = $label_class;
	}

	public function set_class( string $class ): void {
		$this->class = $class;
	}

	public function set_options( array $options ): void {
		$this->options = $options;
	}

	public function set_available_options( array $available_options ): void {
		$this->available_options = $available_options;
	}

	public function set_selected_options( array $selected_options ): void {
		$this->selected_options = $selected_options;
	}

	public function set_label( string $label ): void {
		$this->label = $label;
	}

	public function set_name( string $name ): void {
		$this->name = $name;
	}

	public function get_option_id(): string {
		return $this->option_id;
	}

	public function set_option_id( string $option_id ): void {
		$this->option_id = $option_id;
	}
}
