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

use SabaiApps\Directories\Component\Form\Form;

/**
 * AbstractDatePickerField provides base logic for date picker form fields.
 * Handles initialization, rendering, and configuration of date picker UI elements.
 */
abstract class AbstractDatePickerField extends AbstractField {

	// Static property to store locales used by date pickers per form.
	protected static $_locales = array(), $_jsLoaded = array();

	/**
	 * Initializes the date picker field with settings and default values.
	 *
	 * @param string $name
	 * @param array  $data
	 * @param Form   $form
	 */
	public function formFieldInit( $name, array &$data, Form $form ) {
		if ( ! isset( $data['#id'] ) ) {
			$data['#id'] = $form->getFieldId( $name );
		}

		if ( ! array_key_exists( '#empty_value', $data ) ) {
			$data['#empty_value'] = null;
		}
		if ( ! isset( $data['#default_value'] ) ) {
			$data['#default_value'] = null;
		}

		// Define min/max date
		if ( isset( $data['#min_date'] ) && ! is_int( $data['#min_date'] ) ) {
			unset( $data['#min_date'] );
		}
		if ( isset( $data['#max_date'] ) ) {
			if ( ! is_int( $data['#max_date'] )
				|| ( isset( $data['#min_date'] ) && $data['#max_date'] < $data['#min_date'] )
			) {
				unset( $data['#max_date'] );
			}
		}

		// Set date locale for the field
		if ( ! isset( $data['#date_locale'] ) ) {
			$data['#date_locale'] = $this->_application->Form_Scripts_dateLocale();
		}
		if ( isset( $data['#date_locale'] ) ) {
			if ( ! $this->_application->Form_Scripts_isValidDateLocale( $data['#date_locale'] ) ) {
				$data['#date_locale'] = null;
			} else {
				self::$_locales[ $form->getId() ][] = $data['#date_locale'];
			}
		}

		// Register pre-render callback for the field
		$form->settings['#pre_render'][ __CLASS__ ] = array( $this, 'preRenderCallback' );
	}

	/**
	 * Renders the date picker field as HTML.
	 *
	 * @param array $data
	 * @param Form  $form
	 */
	public function formFieldRender( array &$data, Form $form ) {
		$data['#attributes']['data-calendar-options'] = json_encode( $this->_getCalendarOptions( $data ) );
		$input                                        = $this->_getDateInput( $data );
		if ( ! empty( $data['#row_col'] ) && $data['#row_col'] < 12 ) {
			$input = sprintf(
				'<div class="drts-row"><div class="drts-col-md-%1$d drts-view-filter-ignore">%2$s</div></div>',
				(int) $data['#row_col'],
				$input
			);
		}
		// Availale options can be found here: https://plugins.krajee.com/php-date-formatter#options
		$formatter_options = $this->_application->Filter(
			'form_field_datepicker_formatter_options',
			array(
				'dateSettings' => array(
					'months'      => $this->_application->getPlatform()->getMonthNames(),
					'monthsShort' => $this->_application->getPlatform()->getMonthNames( true ),
				),
			)
		);
		$html              = sprintf(
			'<div class="drts-form-datepicker-inputs" id="%1$s-inputs" data-date-format="%3$s" data-time-format="%4$s" data-formatter-options="%5$s">
    %2$s
    <div class="drts-form-datepicker-calendar" style="display:none;"></div>
</div>',
			$this->_application->H( $data['#id'] ),
			$input,
			$this->_application->H( strtr( $this->_application->getPlatform()->getDateFormat(), array( 'M' => 'F' ) ) ), // Use long month format for the date picker to avoid issues with different locales
			$this->_application->H( $this->_application->getPlatform()->getTimeFormat() ),
			! empty( $formatter_options ) ? $this->_application->H( $this->_application->System_Util_jsonEncode( $formatter_options ) ) : ''
		);
		$this->_render( $html, $data, $form );
	}

	/**
	 * Returns the HTML for the date input field.
	 *
	 * @param array $data
	 * @return string
	 */
	protected function _getDateInput( array $data ) {
		if ( ! isset( $data['#attributes']['placeholder'] ) ) {
			$data['#attributes']['placeholder'] = isset( $data['#placeholder'] ) ? $data['#placeholder'] : __( 'Select date', 'directories-pro' );
		}
		$add_clear = ! isset( $data['#add_clear'] ) || $data['#add_clear'];
		return sprintf(
			'<input readonly type="text" size="8" class="%2$sform-control drts-form-datepicker-date%5$s"%3$s />'
			. '<input type="hidden" name="%1$s" class="drts-form-datepicker-date-val" />%4$s',
			$data['#name'],
			DRTS_BS_PREFIX,
			$this->_application->Attr( $data['#attributes'] ),
			$add_clear ? '<i class="drts-clear fas fa-times-circle" data-clear></i>' : '',
			$add_clear ? ' drts-form-type-textfield-with-clear' : ''
		);
	}

	/**
	 * Returns the configuration options for the calendar widget.
	 *
	 * @param array $data
	 * @return array
	 */
	protected function _getCalendarOptions( array $data ) {
		return array(
			'type'     => 'default',
			'date'     => array(
				'min' => empty( $data['#min_date'] ) ? '1900-01-01' : $this->_application->getPlatform()->getDate( 'Y-m-d', $data['#min_date'] ),
				'max' => empty( $data['#max_date'] ) ? null : $this->_application->getPlatform()->getDate( 'Y-m-d', $data['#max_date'] ),
			),
			'settings' => array(
				'lang'       => $data['#date_locale'],
				'selection'  => array(
					'time' => empty( $data['#disable_time'] ) ? ( empty( $data['#time_12hr'] ) ? 24 : true ) : false,
				),
				'selected'   => array(
					'year' => empty( $data['#default_year'] ) ? null : $data['#default_year'],
				),
				'visibility' => array(
					'theme' => 'light',
				),
			),
		);
	}

	/**
	 * Pre-render callback to load scripts and initialize the date picker UI.
	 *
	 * @param Form $form
	 */
	public function preRenderCallback( $form ) {
		if ( ! empty( self::$_jsLoaded[ $form->getId() ] ) ) {
			return;
		}
		self::$_jsLoaded[ $form->getId() ] = true;

		// Load date picker scripts with the required locales.
		$this->_application->Form_Scripts_date(
			isset( self::$_locales[ $form->getId() ] ) ? self::$_locales[ $form->getId() ] : null // locale
		);
		// Add JavaScript to initialize the date picker on the client side.
		$form->settings['#js_ready'][] = sprintf(
			'(function() {
    $("#%s").find(".drts-form-datepicker-inputs").each(function(){
        DRTS.Form.field.datepicker($(this)); 
    });
})();',
			$form->getId()
		);
	}
}
