<?php
/**
 * @package Hafenstudios\Leadlotse
 */

namespace Hafenstudios\Leadlotse\Fields\Types;

use Hafenstudios\Leadlotse\Fields\AbstractFieldType;

defined( 'ABSPATH' ) || exit;

/**
 * Auswahl-Feld (Dropdown oder Radio, je nach display-Einstellung).
 * Der eingereichte Wert muss einer der definierten Optionen entsprechen.
 */
final class SelectField extends AbstractFieldType {

	public function key(): string {
		return 'select';
	}

	/**
	 * @param mixed                $value Wert.
	 * @param array<string, mixed> $field Felddefinition.
	 * @return string|null
	 */
	public function validate( $value, array $field ): ?string {
		$error = $this->validate_required( $value, $field );
		if ( null !== $error ) {
			return $error;
		}
		if ( ! $this->is_empty( $value ) && ! in_array( (string) $value, $this->option_values( $field ), true ) ) {
			return sprintf(
				/* translators: %s: Feldname */
				__( 'Die Auswahl im Feld "%s" ist ungueltig. Bitte waehlen Sie einen der angebotenen Werte.', 'leadlotse' ),
				(string) ( $field['label'] ?? '' )
			);
		}
		return null;
	}

	/**
	 * @param array<string, mixed> $field Felddefinition.
	 * @return array<string, mixed>
	 */
	public function render_data( array $field ): array {
		$data            = parent::render_data( $field );
		$data['options'] = $this->options( $field );
		$data['display'] = in_array( (string) ( $field['display'] ?? 'dropdown' ), array( 'dropdown', 'radio' ), true )
			? (string) ( $field['display'] ?? 'dropdown' )
			: 'dropdown';
		return $data;
	}

	/**
	 * Normalisierte Optionsliste: [ ['value' => ..., 'label' => ...], ... ].
	 *
	 * @param array<string, mixed> $field Felddefinition.
	 * @return array<int, array{value:string,label:string}>
	 */
	private function options( array $field ): array {
		$options = array();
		foreach ( (array) ( $field['options'] ?? array() ) as $option ) {
			if ( is_array( $option ) ) {
				$value = (string) ( $option['value'] ?? ( $option['label'] ?? '' ) );
				$label = (string) ( $option['label'] ?? $value );
			} else {
				$value = (string) $option;
				$label = (string) $option;
			}
			if ( '' !== $value ) {
				$options[] = array(
					'value' => $value,
					'label' => $label,
				);
			}
		}
		return $options;
	}

	/**
	 * Nur die gueltigen Options-Werte.
	 *
	 * @param array<string, mixed> $field Felddefinition.
	 * @return array<int, string>
	 */
	private function option_values( array $field ): array {
		return array_map(
			static function ( array $option ): string {
				return $option['value'];
			},
			$this->options( $field )
		);
	}
}
