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

namespace Hafenstudios\Leadlotse\Fields\Types;

use Hafenstudios\Core\Events\EventBus;
use Hafenstudios\Leadlotse\Fields\AbstractFieldType;
use Hafenstudios\Leadlotse\Fields\PhoneValidator;

defined( 'ABSPATH' ) || exit;

/**
 * Telefon-Feld. Der Rohwert wird beim Sanitizing in die normalisierte E.164-nahe
 * Form gebracht (nur fuehrendes Plus und Ziffern, 00 zu Plus) und in dieser Form
 * gespeichert. Die Validierung prueft die grobe Plausibilitaet (PhoneValidator)
 * und reicht das Ergebnis durch den Filter leadlotse_phone_validation, damit ein
 * spaeterer Nummer-vergeben-Dienst (HLR-Lookup, Pro) andocken kann.
 */
final class PhoneField extends AbstractFieldType {

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

	/**
	 * Ergaenzt die Standard-Render-Daten um die WhatsApp-Opt-in-Schluessel, damit
	 * der FormRenderer die Opt-in-Checkbox unter dem Telefon-Feld ausgeben kann.
	 *
	 * @param array<string, mixed> $field Felddefinition.
	 * @return array<string, mixed>
	 */
	public function render_data( array $field ): array {
		$data = parent::render_data( $field );
		if ( ! empty( $field['whatsapp_optin'] ) ) {
			$data['whatsapp_optin'] = true;
		}
		if ( isset( $field['whatsapp_optin_text'] ) ) {
			$data['whatsapp_optin_text'] = (string) $field['whatsapp_optin_text'];
		}
		return $data;
	}

	/**
	 * Bereinigt und normalisiert den Rohwert. Ein leeres (optionales) Feld bleibt
	 * leer, damit sich das bestehende Verhalten nicht aendert.
	 *
	 * @param mixed                $value Rohwert.
	 * @param array<string, mixed> $field Felddefinition.
	 * @return string
	 */
	public function sanitize( $value, array $field ) {
		$value = sanitize_text_field( (string) ( is_array( $value ) ? '' : $value ) );
		if ( '' === trim( $value ) ) {
			return '';
		}
		return PhoneValidator::normalize( $value );
	}

	/**
	 * @param mixed                $value Bereits normalisierter 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 ) ) {
			return null;
		}

		$number    = (string) $value;
		$plausible = PhoneValidator::is_plausible( $number );

		/**
		 * Erlaubt es, das Plausibilitaetsergebnis zu ueberschreiben. Andockpunkt fuer
		 * einen spaeteren Nummer-vergeben-Dienst (HLR-Lookup, Pro). Der zweite
		 * Parameter ist die bereits normalisierte Nummer.
		 *
		 * @param bool   $plausible Bisheriges Ergebnis.
		 * @param string $number    Normalisierte Telefonnummer.
		 */
		$plausible = (bool) EventBus::filter( 'leadlotse_phone_validation', $plausible, $number );

		if ( ! $plausible ) {
			return __( 'Diese Telefonnummer sieht nicht vollstaendig aus. Bitte pruefen Sie die Eingabe.', 'leadlotse' );
		}

		return null;
	}
}
