<?php
namespace SabaiApps\Directories\Component\Form\Field;

use SabaiApps\Directories\Component\Form\Form;

/**
 * AddressField provides a composite field for entering address information.
 * Handles initialization, rendering, and value processing for address subfields.
 */
class AddressField extends FieldsetField {

	/**
	 * Initializes the Address field with child fields for address components.
	 *
	 * @param string $name
	 * @param array  $data
	 * @param Form   $form
	 */
	public function formFieldInit( $name, array &$data, Form $form ) {
		$data = array(
			'#tree'     => true,
			'#children' => array(
				0 => $this->_getFormFields( $data, $form ),
			),
			'#group'    => true,
		) + $data;

		parent::formFieldInit( $name, $data, $form );
	}

	/**
	 * Returns the array of form fields for address components.
	 *
	 * @param array $data
	 * @param Form  $form
	 * @return array
	 */
	protected function _getFormFields( array $data, Form $form ) {
		$title_or_description = '#title';
		$street_attr          = isset( $data['#attr_street'] ) ? $data['#attr_street'] : array();
		if ( isset( $data['#class_street'] ) ) {
			$street_attr['class'] = $data['#class_street'];
		}
		$ret = array(
			'street' => array(
				$title_or_description => array_key_exists( '#title_street', $data ) ? $data['#title_street'] : __( 'Address Line 1', 'directories-pro' ),
				'#type'               => 'textfield',
				'#attributes'         => $street_attr,
				'#default_value'      => isset( $data['#default_value']['street'] ) ? $data['#default_value']['street'] : null,
				'#weight'             => 1,
			),
		);
		if ( empty( $data['#disable_street2'] ) ) {
			$ret['street2'] = array(
				$title_or_description => array_key_exists( '#title_street2', $data ) ? $data['#title_street2'] : __( 'Address Line 2', 'directories-pro' ),
				'#type'               => 'textfield',
				'#attributes'         => isset( $data['#class_street2'] ) ? array( 'class' => $data['#class_street2'] ) : array(),
				'#required'           => ! empty( $data['#require_street2'] ),
				'#default_value'      => isset( $data['#default_value']['street2'] ) ? $data['#default_value']['street2'] : null,
				'#weight'             => 2,
			);
		}
		if ( isset( $data['#city_type'] )
			&& $data['#city_type'] !== 'disabled'
		) {
			$attr        = isset( $data['#class_city'] ) ? array( 'class' => $data['#class_city'] ) : array();
			$ret['city'] = array(
				$title_or_description => array_key_exists( '#title_city', $data ) ? $data['#title_city'] : __( 'City', 'directories-pro' ),
				'#attributes'         => isset( $data['#city'] ) ? array( 'data-default-value' => $data['#city'] ) + $attr : $attr,
				'#weight'             => 3,
			);
			if ( ! empty( $data['#city_type'] ) ) {
				$options      = $data['#city_type'] !== 'select'
					? $this->_application->callHelper( $data['#city_type'] )
					: ( isset( $data['#cities']['options'] ) ? $data['#cities']['options'] : array() );
				$ret['city'] += array(
					'#type'          => 'select',
					'#options'       => array( '' => '' ) + (array) $options,
					'#default_value' => isset( $data['#default_value']['city'] ) ? $data['#default_value']['city'] : ( isset( $data['#cities']['default'][0] ) ? $data['#cities']['default'][0] : null ),
					'#empty_value'   => '',
				);
			} else {
				$ret['city'] += array(
					'#type'          => 'textfield',
					'#default_value' => isset( $data['#default_value']['city'] ) ? $data['#default_value']['city'] : ( isset( $data['#city'] ) ? $data['#city'] : null ),
				);
			}
			if ( isset( $data['#province_type'] )
				&& $data['#province_type'] !== 'disabled'
			) {
				$ret['city']['#prefix'] = '<div class="' . DRTS_BS_PREFIX . 'row"><div class="' . DRTS_BS_PREFIX . 'col-sm-6">';
				$ret['city']['#suffix'] = '</div>';
			}
		} elseif ( isset( $data['#city'] ) ) {
			// Add hidden field for geolocation search
			$ret['city'] = array(
				'#type'   => 'markup',
				'#value'  => sprintf( '<input class="%1$s" type="hidden" value="%2$s" data-default-value="%2$s" />', isset( $data['#class_city'] ) ? $data['#class_city'] : '', $this->_application->H( $data['#city'] ) ),
				'#weight' => 5,
			);
		}
		if ( isset( $data['#province_type'] )
			&& $data['#province_type'] !== 'disabled'
		) {
			$attr            = isset( $data['#class_province'] ) ? array( 'class' => $data['#class_province'] ) : array();
			$ret['province'] = array(
				$title_or_description => array_key_exists( '#title_province', $data ) ? $data['#title_province'] : __( 'State / Province / Region', 'directories-pro' ),
				'#attributes'         => isset( $data['#province'] ) ? array( 'data-default-value' => $data['#province'] ) + $attr : $attr,
				'#weight'             => 4,
			);
			if ( ! empty( $data['#province_type'] ) ) {
				$options          = $data['#province_type'] !== 'select'
					? $this->_application->callHelper( $data['#province_type'] )
					: ( isset( $data['#provinces']['options'] ) ? $data['#provinces']['options'] : array() );
				$ret['province'] += array(
					'#type'          => 'select',
					'#options'       => array( '' => '' ) + (array) $options,
					'#default_value' => isset( $data['#default_value']['province'] ) ? $data['#default_value']['province'] : ( isset( $data['#provinces']['default'][0] ) ? $data['#provinces']['default'][0] : null ),
					'#empty_value'   => '',
				);
			} else {
				$ret['province'] += array(
					'#type'          => 'textfield',
					'#default_value' => isset( $data['#default_value']['province'] ) ? $data['#default_value']['province'] : ( isset( $data['#province'] ) ? $data['#province'] : array() ),
				);
			}
			if ( isset( $data['#city_type'] )
				&& $data['#city_type'] !== 'disabled'
			) {
				$ret['province']['#prefix'] = '<div class="' . DRTS_BS_PREFIX . 'col-sm-6">';
				$ret['province']['#suffix'] = '</div></div>';
			}
		} elseif ( isset( $data['#province'] ) ) {
			// Add hidden field for geolocation search
			$ret['province'] = array(
				'#type'   => 'markup',
				'#value'  => sprintf( '<input class="%1$s-hidden" type="hidden" value="%2$s" data-default-value="%2$s" />', isset( $data['#class_province'] ) ? $data['#class_province'] : '', $this->_application->H( $data['#province'] ) ),
				'#weight' => 5,
			);
		}
		if ( isset( $data['#zip_type'] )
			&& $data['#zip_type'] !== 'disabled'
		) {
			$attr       = isset( $data['#class_zip'] ) ? array( 'class' => $data['#class_zip'] ) : array();
			$ret['zip'] = array(
				$title_or_description => array_key_exists( '#title_zip', $data ) ? $data['#title_zip'] : __( 'Postal / Zip Code', 'directories-pro' ),
				'#attributes'         => isset( $data['#zip'] ) ? array( 'data-default-value' => $data['#zip'] ) + $attr : $attr,
				'#weight'             => 5,
			);
			if ( ! empty( $data['#zip_type'] ) ) {
				$options     = $data['#zip_type'] !== 'select'
					? $this->_application->callHelper( $data['#zip_type'] )
					: ( isset( $data['#zips']['options'] ) ? $data['#zips']['options'] : array() );
				$ret['zip'] += array(
					'#type'          => 'select',
					'#options'       => array( '' => '' ) + (array) $options,
					'#default_value' => isset( $data['#default_value']['zip'] ) ? $data['#default_value']['zip'] : ( isset( $data['#zips']['default'][0] ) ? $data['#zips']['default'][0] : array() ),
					'#empty_value'   => '',
				);
			} else {
				$ret['zip'] += array(
					'#type'          => 'textfield',
					'#default_value' => isset( $data['#default_value']['zip'] ) ? $data['#default_value']['zip'] : ( isset( $data['#zip'] ) ? $data['#zip'] : null ),
				);
			}
			if ( isset( $data['#country_type'] )
				&& $data['#country_type'] !== 'disabled'
			) {
				$ret['zip']['#prefix'] = '<div class="' . DRTS_BS_PREFIX . 'row"><div class="' . DRTS_BS_PREFIX . 'col-6">';
				$ret['zip']['#suffix'] = '</div>';
			}
		} elseif ( isset( $data['#zip'] ) ) {
			// Add hidden field for geolocation search
			$ret['zip'] = array(
				'#type'   => 'markup',
				'#value'  => sprintf( '<input class="%1$s-hidden" type="hidden" value="%2$s" data-default-value="%2$s" />', isset( $data['#class_zip'] ) ? $data['#class_zip'] : '', $this->_application->H( $data['#zip'] ) ),
				'#weight' => 5,
			);
		}
		if ( isset( $data['#country_type'] )
			&& $data['#country_type'] !== 'disabled'
		) {
			$attr           = isset( $data['#class_country'] ) ? array( 'class' => $data['#class_country'] ) : array();
			$ret['country'] = array(
				$title_or_description => array_key_exists( '#title_country', $data ) ? $data['#title_country'] : __( 'Country', 'directories-pro' ),
				'#attributes'         => isset( $data['#country'] ) ? array( 'data-default-value' => $data['#country'] ) + $attr : $attr,
				'#weight'             => 6,
			);
			if ( ! empty( $data['#country_type'] ) ) {
				if ( $data['#country_type'] === 'select' ) {
					$options = isset( $data['#countries']['options'] ) ? $data['#countries']['options'] : $this->_application->System_Countries();
				} else {
					$options = $this->_application->callHelper( $data['#country_type'] );
				}
				$ret['country'] += array(
					'#type'          => 'select',
					'#options'       => array( '' => '' ) + (array) $options,
					'#default_value' => isset( $data['#default_value']['country'] ) ? $data['#default_value']['country'] : ( isset( $data['#countries']['default'][0] ) ? $data['#countries']['default'][0] : null ),
					'#empty_value'   => '',
				);
			} else {
				$ret['country'] += array(
					'#type'          => 'textfield',
					'#default_value' => isset( $data['#default_value']['country'] ) ? $data['#default_value']['country'] : ( isset( $data['#country'] ) ? $data['#country'] : null ),
				);
			}
			if ( isset( $data['#zip_type'] )
				&& $data['#zip_type'] !== 'disabled'
			) {
				$ret['country']['#prefix'] = '<div class="' . DRTS_BS_PREFIX . 'col-6">';
				$ret['country']['#suffix'] = '</div></div>';
			}
		} elseif ( isset( $data['#country'] ) ) {
			// Add hidden field for geolocation search
			$ret['country'] = array(
				'#type'   => 'markup',
				'#value'  => sprintf( '<input class="%1$s-hidden" type="hidden" value="%2$s" data-default-value="%2$s" />', isset( $data['#class_country'] ) ? $data['#class_country'] : '', $this->_application->H( $data['#country'] ) ),
				'#weight' => 6,
			);
		}

		return $ret;
	}

	/**
	 * Handles value processing and normalization for the Address field on submit.
	 *
	 * @param mixed $value
	 * @param array $data
	 * @param Form  $form
	 */
	public function formFieldSubmit( &$value, array &$data, Form $form ) {
		parent::formFieldSubmit( $value, $data, $form );

		if ( $form->hasError() ) {
			return;
		}

		$value = array_filter( $value );

		foreach ( array( 'city', 'province', 'zip', 'country' ) as $key ) {
			if ( isset( $data[ '#' . $key . '_type' ] )
				&& $data[ '#' . $key . '_type' ] === 'disabled'
				&& isset( $data[ '#' . $key ] )
				&& strlen( (string) $data[ '#' . $key ] )
			) {
				$value[ $key ] = $data[ '#' . $key ];
			}
		}
	}
}
