<?php

/**
 * Address Field
 *
 * @package AmbassadorHub\CustomFields
 */

namespace AmbassadorHub\Fields\Fields;

use AmbassadorHub\Fields\FieldFactory;

use function esc_html;

/**
 * Class representing an address custom field.
 */
final class AddressField extends AbstractField {


	/**
	 * Get the settings fields for this checkbox field.
	 *
	 * @return array
	 */
	public function get_settings_fields(): array {

		$address_fields = self::get_sub_fields();
		$default_fields = self::get_default_sub_fields();

		$fields = array();

		foreach ( $address_fields as $field ) {
			$fields[] = array(
				'type'  => 'checkbox',
				'id'    => 'address_field_' . $field['id'],
				'label' => $field['label'],
				'value' => in_array( $field['id'], $default_fields, true ) ? '1' : '0',
			);
		}

		$fields[] = array(
			'type'        => 'dropdown',
			'id'          => 'address_country_default',
			'label'       => __( 'Default Country', 'ambassadorhub' ),
			'options'     => self::get_country_options(),
			'value'       => 'NL',
			'description' => __( 'Default country (Uses as country when country field is not shown)', 'ambassadorhub' ),
		);

		return $fields;
	}


	/**
	 * Get default address fields.
	 *
	 * @return array Default address field names.
	 */
	public static function get_default_sub_fields(): array {
		$defaults = array(
			'street',
			'housenumber',
			'housenumber_suffix',
			'postal_code',
			'city',
		);

		/**
		 * Filter the default address fields for custom address field types.
		 *
		 * @since 0.1.0
		 *
		 * @param array $defaults Default address field names.
		 */
		return apply_filters( 'ambh_default_address_fields', $defaults );
	}

	/**
	 * Get all available address field options (for UI).
	 *
	 * @return array Address field options with labels.
	 */
	public static function get_address_field_options(): array {
		$options = array(
			'street'             => __( 'Street', 'ambassadorhub' ),
			'housenumber'        => __( 'House Number', 'ambassadorhub' ),
			'housenumber_suffix' => __( 'House Number Suffix', 'ambassadorhub' ),
			'postal_code'        => __( 'Postal Code', 'ambassadorhub' ),
			'city'               => __( 'City', 'ambassadorhub' ),
			'state'              => __( 'State/Province', 'ambassadorhub' ),
			'country'            => __( 'Country', 'ambassadorhub' ),
		);

		/**
		 * Filter the available address field options.
		 *
		 * @since 0.1.0
		 *
		 * @param array $options Address field options with labels.
		 */
		return apply_filters( 'ambh_address_field_options', $options );
	}

	public function get_sub_fields() {

		return array(
			array(
				'id'       => 'street',
				'label'    => __( 'Street', 'ambassadorhub' ),
				'type'     => 'text',
				'required' => true,
			),
			array(
				'id'         => 'housenumber',
				'label'      => __( 'House Number', 'ambassadorhub' ),
				'type'       => 'number',
				'required'   => true,
				'attributes' => array(
					'min' => 1,
				),
			),
			array(
				'id'       => 'housenumber_suffix',
				'label'    => __( 'House Number Suffix', 'ambassadorhub' ),
				'type'     => 'text',
				'required' => false,
			),
			array(
				'id'       => 'postal_code',
				'label'    => __( 'Postal Code', 'ambassadorhub' ),
				'type'     => 'text',
				'required' => true,
			),
			array(
				'id'       => 'city',
				'label'    => __( 'City', 'ambassadorhub' ),
				'type'     => 'text',
				'required' => true,
			),
			array(
				'id'       => 'state',
				'label'    => __( 'State/Province', 'ambassadorhub' ),
				'type'     => 'text',
				'required' => false,
			),
			array(
				'id'       => 'country',
				'label'    => __( 'Country', 'ambassadorhub' ),
				'type'     => 'dropdown',
				'required' => true,
				'options'  => self::get_country_options(),
			),
		);
	}

	/**
	 * Get available country options for country dropdowns.
	 *
	 * @return array Country options with country codes as keys and names as values.
	 */
	public static function get_country_options(): array {
		$countries = array(
			'US' => __( 'United States', 'ambassadorhub' ),
			'GB' => __( 'United Kingdom', 'ambassadorhub' ),
			'NL' => __( 'Netherlands', 'ambassadorhub' ),
			'DE' => __( 'Germany', 'ambassadorhub' ),
			'FR' => __( 'France', 'ambassadorhub' ),
			'IT' => __( 'Italy', 'ambassadorhub' ),
			'ES' => __( 'Spain', 'ambassadorhub' ),
			'BE' => __( 'Belgium', 'ambassadorhub' ),
			'AT' => __( 'Austria', 'ambassadorhub' ),
			'CH' => __( 'Switzerland', 'ambassadorhub' ),
		);

		/**
		 * Filter the available country options.
		 *
		 * @since 0.1.0
		 *
		 * @param array $countries Country options with country codes as keys.
		 */
		return apply_filters( 'ambh_country_options', $countries );
	}


	/**
	 * Constructor.
	 *
	 * Initializes the address field with ID and label.
	 *
	 * @since 1.0.0
	 */
	public function __construct() {
		$this->id    = 'address';
		$this->label = __( 'Address', 'ambassadorhub' );

		parent::__construct();
	}

	/**
	 * Sanitize an address value (array of address parts).
	 *
	 * @param mixed $value The raw value to sanitize.
	 *
	 * @return array The sanitized address value.
	 */
	public function sanitize_value( $value ) {
		if ( is_array( $value ) ) {
			return array_map( 'sanitize_text_field', (array) $value );
		}
		return array();
	}

	public function validate_settings( array $settings ): void {
		$selected_fields = array_filter(
			$settings,
			static function ( $value, $key ) {
				return str_starts_with( $key, 'address_field_' ) && ! empty( $value );
			},
			ARRAY_FILTER_USE_BOTH
		);

		if ( empty( $selected_fields ) ) {
			throw new \InvalidArgumentException( esc_html__( 'Please select at least one address field.', 'ambassadorhub' ) );
		}

		if ( ! empty( $settings['address_field_country'] ) && empty( $settings['address_country_default'] ) ) {
			throw new \InvalidArgumentException( esc_html__( 'Default country must be set when country field is selected.', 'ambassadorhub' ) );
		}
	}



	public function render_field_label( array $field, $id, $label ): void {
		// No label for the main field, as subfields have their own labels.
	}

	/**
	 * Render frontend input for address fields.
	 *
	 * @param array  $field         Field definition.
	 * @param string $id            HTML id attribute.
	 * @param string $name          HTML name attribute.
	 * @param string $value         Current value (unused).
	 * @param string $placeholder   Placeholder text.
	 * @param string $required_attr Required attribute string.
	 * @param string $class_attr    CSS class attribute string.
	 *
	 * @return void
	 */
	public function render_field_input(
		array $field,
		string $id,
		string $name,
		string|array $value,
		string $placeholder,
		bool $required,
		string $class_attr
	): void {
		$settings        = $field['settings'] ?? array();
		$selected_fields = array_filter(
			$settings,
			static function ( $setting_value, $key ) {
				return str_starts_with( $key, 'address_field_' ) && ! empty( $setting_value );
			},
			ARRAY_FILTER_USE_BOTH
		);

		$address_fields = self::get_sub_fields();

		// Filter to only include selected fields
		$address_fields = array_filter(
			$address_fields,
			static function ( $subfield ) use ( $selected_fields ) {
				return in_array( 'address_field_' . $subfield['id'], array_keys( $selected_fields ), true );
			}
		);

		echo '<fieldset>';
		echo '<legend>' . esc_html( $field['label'] ?? $this->label ) . '</legend>';

		foreach ( $address_fields as $subfield ) {

			$sub_value = $value[ $subfield['id'] ] ?? '';
			if ( 'country' === $subfield['id'] && empty( $sub_value ) ) {
				$sub_value = $settings['address_country_default'] ?? '';
			}

			echo '<div class="ambassador-account__form-group">';

			$custom_field = FieldFactory::create( $subfield['type'] );
			$sub_id       = $id . '_' . $subfield['id'];

			$custom_field->render_field_label(
				$subfield,
				$sub_id,
				$subfield['label']
			);

			$custom_field->render_field_input(
				$subfield,
				$sub_id,
				$name . '[' . $subfield['id'] . ']',
				(string) $sub_value,
				'',
				$required && $subfield['required'],
				$class_attr
			);

			echo '</div>';
		}
		echo '</fieldset>';
	}
}
