<?php
namespace SmartSlotAppointmentScheduler;

use SmartSlotAppointmentScheduler\Schedule_Posttype;

if (! defined('ABSPATH')) {
	exit;
}

if (!class_exists('\SmartSlotAppointmentScheduler\Schedule_Settings')) {

	/**
	 * Class to create fields for the settings page with HTML structures.
	 */
	class Schedule_Settings {

		static $settings;
		static $settings_base;

		/**
		 * Register the settings for the schedule post type.
		 *
		 * @return void
		 */
		public static function setup() {
			self::$settings_base = 'booking_';

			/*
			 * Define a constant for the settings prefix to avoid hardcoding it
			 * multiple times. This makes it easier to change the prefix in the future.
			 */
			if (!defined('SMARTSLOT_PREFIX')) {
				define('SMARTSLOT_PREFIX', 'smartslot_appointment_scheduler_');
			}

			add_action('admin_init', array(__CLASS__, 'init'));
			add_action('admin_init', array(__CLASS__, 'register_settings'));
		}

		/**
		 * Initialise settings.
		 *
		 * @return void
		 */
		public static function init() {
			self::$settings = self::settings_fields();
		}

		/**
		 * Build settings fields.
		 *
		 * @return array Fields to be displayed on settings page.
		 */
		public static function settings_fields() {
			$settings['settings'] = [
				'title'       => __('Schedule Settings', 'smartslot-appointment-scheduler'),
				'description' => __('Fields to update for Appointment Booking.', 'smartslot-appointment-scheduler'),
				'fields'      => [
					[
						'id'          => 'schedule_time_slot_interval',
						'label'       => __('Time Slot Interval', 'smartslot-appointment-scheduler'),
						'description' => __('Mention it in minutes (min: 15 & max: 60)', 'smartslot-appointment-scheduler'),
						'type'        => 'number',
						'default'     => '30',
						'step'        => '15',
						'min'         => '15',
						'max'         => '60',
					],
					[
						'id'          => 'schedule_business_hour_start_time',
						'label'       => __('Starting Time of Working Hours', 'smartslot-appointment-scheduler'),
						'type'        => 'time',
						'default'     => '09:00',
					],
					[
						'id'          => 'schedule_business_hour_end_time',
						'label'       => __('Ending Time of Working Hours', 'smartslot-appointment-scheduler'),
						'type'        => 'time',
						'default'     => '18:00',
					],
					[
						'id'          => 'schedule_business_holidays',
						'label'       => __('Add Holidays', 'smartslot-appointment-scheduler'),
						'type'        => 'repeater_date',
						'default'     => '',
					],
					[
						'id'          => 'schedule_on_business_days',
						'label'       => __('Add Working Schedule', 'smartslot-appointment-scheduler'),
						'type'        => 'select',
						'options'     => [
							'all_days_open'              => 'Open All Days',
							'sunday_closed'              => 'Sundays: Closed',
							'weekends_closed'            => 'Weekends: Closed',
							'alternate_saturdays_closed' => '2nd & 4th Sat: Closed',
						],
						'default'     => 'weekends_closed',
					],
					[
						'id'          => 'schedule_success_url',
						'label'       => __('Success Page URL', 'smartslot-appointment-scheduler'),
						'type'        => 'text',
						'default'     => '',
						'placeholder' => 'https://example.com/success',
					],
					[
						'id'          => 'schedule_token_length',
						'label'       => __('Booking ID Length', 'smartslot-appointment-scheduler'),
						'type'        => 'number',
						'default'     => '3',
						'step'        => '1',
						'min'         => '3',
						'max'         => '6',
						'description' => __('Minimum value 3, Maximum value 6', 'smartslot-appointment-scheduler'),
					],
					[
						'id'          => 'schedule_appintment_token_prefix',
						'label'       => __('Booking Prefix', 'smartslot-appointment-scheduler'),
						'type'        => 'text',
						'default'     => 'token',
					],
					[
						'id'          => 'schedule_appintment_email_from',
						'label'       => __('Sender Email', 'smartslot-appointment-scheduler'),
						'type'        => 'email',
						'placeholder' => 'test@example.com',
						'default'     => '',
					],
					[
						'id'          => 'schedule_appintment_email_subject',
						'label'       => __('Email Subject', 'smartslot-appointment-scheduler'),
						'type'        => 'text',
						'placeholder' => 'Email subject for appointment booking',
						'default'     => '',
					],
					[
						'id'          => 'schedule_email_content',
						'label'       => __('Email Template', 'smartslot-appointment-scheduler'),
						'type'        => 'textarea',
						'rows'        => '5',
						'cols'        => '100',
						'description' => __('Values you can use: {name}, {date_time}, {token_number}.', 'smartslot-appointment-scheduler'),
						'default'     => 'Hi {name}, Your booking has been successfully confirmed. Here are your booking details: Date & Time: {date_time} Booking ID: {token_number}. If you need to make any changes, please contact us.',
					],
					[
						'id'          => 'schedule_appintment_email_footer',
						'label'       => __('Email Footer', 'smartslot-appointment-scheduler'),
						'type'        => 'text',
						'placeholder' => __('You can use this to add signature or contact details.', 'smartslot-appointment-scheduler'),
						'default'     => '',
						'description' => __('Use <br> to break to the next Line.', 'smartslot-appointment-scheduler'),
					],
				],
			];

			// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- Dynamic hook with proper plugin prefix via constant.
			$settings = apply_filters(SMARTSLOT_PREFIX . 'settings_fields', $settings);

			return $settings;
		}

		/**
		 * Register plugin settings.
		 *
		 * @return void
		 */
		public static function register_settings() {

			if (!is_array(self::$settings)) {
				return;
			}

			foreach (self::$settings as $section => $data) {

				add_settings_section(
					$section,
					$data['title'],
					[__CLASS__, 'settings_section'],
					Schedule_Posttype::SLUG . '_settings',
					[
						'before_section' => '<div class="tab-content" id="' . esc_attr($section) . '">',
						'after_section'  => '</div>',
					]
				);

				foreach ($data['fields'] as $field) {

					$option_name = self::$settings_base . $field['id'];

					register_setting(
						Schedule_Posttype::SLUG . '_settings',
						$option_name,
						[
							'sanitize_callback' => function ($input) use ($field) {

								if ('schedule_appintment_email_footer' === $field['id']) {
									return wp_kses(
										$input,
										[
											'br' => [],
										]
									);
								}

								switch ($field['type']) {

									case 'text':
										// Handle URL fields separately.
										if (strpos($field['id'], 'url') !== false) {
											return esc_url_raw($input);
										}

										return sanitize_text_field($input);

									case 'email':
										return sanitize_email($input);

									case 'number':
										return absint($input);

									case 'textarea':
										return sanitize_textarea_field($input);

									case 'select':
										return sanitize_text_field($input);

									case 'checkbox':
										return ($input === 'on') ? 'on' : '';

									case 'repeater_date':
										if (!is_array($input)) {
											return [];
										}

										return array_filter(
											array_map(
												function ($date) {
													$date = sanitize_text_field($date);

													// Validate YYYY-MM-DD format.
													return preg_match('/^\d{4}-\d{2}-\d{2}$/', $date) ? $date : '';
												},
												$input
											)
										);

									default:
										return sanitize_text_field($input);
								}
							},
						]
					);

					add_settings_field(
						$field['id'],
						$field['label'],
						[__CLASS__, 'display_field'],
						Schedule_Posttype::SLUG . '_settings',
						$section,
						['field' => $field]
					);
				}
			}
		}

		/**
		 * Setting section description.
		 *
		 * @param array $section Section data.
		 * @return void
		 */
		public static function settings_section($section) {
			$description = !empty(self::$settings[$section['id']]['description'])
				? wp_kses_post(self::$settings[$section['id']]['description'])
				: '';

			printf(
				'<p class="%s">%s</p>' . "\n",
				esc_attr($section['id']),
				esc_attr($description)
			);
		}

		/**
		 * Generate HTML for displaying fields.
		 *
		 * @param array $args Field data.
		 * @return void
		 */
		public static function display_field($args) {
			$field = $args['field'];

			$option_name = self::$settings_base . $field['id'];
			$option = get_option($option_name);
			$placeholder = isset($field['placeholder']) ? $field['placeholder'] : '';
			$description = isset($field['description']) ? wp_kses_post($field['description']) : '';

			$data = '';

			if (isset($field['default'])) {
				$data = $field['default'];

				if ($option !== false && $option !== '') {
					$data = $option;
				}
			}

			switch ($field['type']) {

				case 'text':
				case 'password':
				case 'time':
				case 'email':
					echo sprintf(
						'<input id="%s" type="%s" name="%s" placeholder="%s" value="%s"/><br/>' . "\n",
						esc_attr($field['id']),
						esc_attr($field['type']),
						esc_attr($option_name),
						esc_attr($placeholder),
						esc_attr($data)
					);
					break;

				case 'number':
					echo sprintf(
						'<input id="%s" type="%s" name="%s" placeholder="%s" value="%s" step="%s" min="%s" max="%s" /><br/>' . "\n",
						esc_attr($field['id']),
						esc_attr($field['type']),
						esc_attr($option_name),
						esc_attr($placeholder),
						esc_attr($data),
						esc_attr($field['step']),
						esc_attr($field['min']),
						esc_attr($field['max'])
					);
					break;

				case 'text_secret':
					echo sprintf(
						'<input id="%s" type="text" name="%s" placeholder="%s" value=""/>' . "\n",
						esc_attr($field['id']),
						esc_attr($option_name),
						esc_attr($placeholder)
					);
					break;

				case 'textarea':
					echo sprintf(
						'<textarea id="%s" rows="%s" cols="%s" name="%s" placeholder="%s">%s</textarea><br/>' . "\n",
						esc_attr($field['id']),
						esc_attr($field['rows']),
						esc_attr($field['cols']),
						esc_attr($option_name),
						esc_attr($placeholder),
						esc_textarea($data)
					);
					break;

				case 'checkbox':
					$checked = $option === 'on' ? 'checked="checked"' : '';

					echo sprintf(
						'<input id="%s" type="checkbox" name="%s" %s />' . "\n",
						esc_attr($field['id']),
						esc_attr($option_name),
						esc_attr($checked)
					);
					break;

				case 'checkbox_multi':
					foreach ($field['options'] as $k => $v) {
						$checked = in_array($v, (array) $data, true);

						echo sprintf(
							'<label for="%s" class="checkbox-options"><input type="checkbox" %s name="%s[]" value="%s" id="%s" /> %s</label> ',
							esc_attr($field['id'] . '_' . $k),
							checked($checked, true, false),
							esc_attr($option_name),
							esc_attr($v),
							esc_attr($field['id'] . '_' . $k),
							esc_html($v)
						);
					}
					break;

				case 'radio':
					foreach ($field['options'] as $k => $v) {
						$checked = $k === $data;

						echo sprintf(
							'<label for="%s" class="radio-options"><input type="radio" %s name="%s" value="%s" id="%s" /> %s</label> ',
							esc_attr($field['id'] . '_' . $k),
							checked($checked, true, false),
							esc_attr($option_name),
							esc_attr($k),
							esc_attr($field['id'] . '_' . $k),
							esc_html($v)
						);
					}
					break;

				case 'select':
					echo sprintf(
						'<select class="woo-select2" name="%s" id="%s">',
						esc_attr($option_name),
						esc_attr($field['id'])
					);

					foreach ($field['options'] as $k => $v) {
						$selected = $k === $data;

						echo sprintf(
							'<option %s value="%s">%s</option>',
							selected($selected, true, false),
							esc_attr($k),
							esc_html($v)
						);
					}

					echo '</select> ';
					break;

				case 'select_multi':
					echo sprintf(
						'<select class="woo-select2" name="%s[]" id="%s" multiple="multiple">',
						esc_attr($option_name),
						esc_attr($field['id'])
					);

					foreach ($field['options'] as $k => $v) {
						$selected = in_array($k, (array) $data, true);

						echo sprintf(
							'<option %s value="%s">%s</option>',
							selected($selected, true, false),
							esc_attr($k),
							esc_html($v)
						);
					}

					echo '</select> ';
					break;

				case 'color':
					echo '<div class="color-picker" style="position:relative;">';

					echo sprintf(
						'<input type="text" name="%s" class="color" value="%s" />',
						esc_attr($option_name),
						esc_attr($data)
					);

					echo '<div style="position:absolute;background:#FFF;z-index:99;border-radius:100%;" class="colorpicker"></div>';
					echo '</div>';
					break;

				case 'repeater_date':
					$values = get_option($option_name, []);

					if (!is_array($values)) {
						$values = [];
					}

					echo '<div class="repeater-wrapper" data-name="' . esc_attr($option_name) . '[]" style="margin-bottom:10px;">';

					if (!empty($values)) {
						foreach ($values as $val) {
							echo '<div class="repeater-row" style="margin-bottom:10px;">';

							echo '<input type="date" class="date-field" name="' . esc_attr($option_name) . '[]" value="' . esc_attr($val) . '" />';

							echo '<button type="button" class="button remove-row">' . esc_html__('Remove', 'smartslot-appointment-scheduler') . '</button>';

							echo '</div>';
						}
					}

					echo '</div>';

					echo '<button type="button" class="button add-row">' . esc_html__('Add Date', 'smartslot-appointment-scheduler') . '</button>';
					break;
			}

			// Add the description after the input fields.
			if ($description) {
				echo sprintf(
					'<br/><span class="description">%s</span>',
					esc_html($description)
				);
			}
		}

		/**
		 * Load settings page content.
		 *
		 * @return void
		 */
		public static function settings_page() {
			settings_errors();

			?>
			<div class="wrap" id="<?php echo esc_attr(Schedule_Posttype::SLUG . '_settings'); ?>">
				<h2><?php esc_html_e('Booking Manager Settings', 'smartslot-appointment-scheduler'); ?></h2>

				<form method="post" action="options.php" enctype="multipart/form-data">
					<div class="clear"></div>

					<?php
					settings_fields(Schedule_Posttype::SLUG . '_settings');
					do_settings_sections(Schedule_Posttype::SLUG . '_settings');
					submit_button();
					?>
				</form>
			</div>
			<?php
		}

		/**
		 * Save all default settings during plugin activation.
		 *
		 * @return void
		 */
		public static function save_default_settings() {

			self::$settings_base = 'booking_';

			if (!defined('SMARTSLOT_PREFIX')) {
				define('SMARTSLOT_PREFIX', 'smartslot_appointment_scheduler_');
			}

			self::init();

			if (empty(self::$settings) || !is_array(self::$settings)) {
				return;
			}

			foreach (self::$settings as $section) {

				if (empty($section['fields'])) {
					continue;
				}

				foreach ($section['fields'] as $field) {

					$option_name = self::$settings_base . $field['id'];

					if (get_option($option_name, null) === null) {

						add_option(
							$option_name,
							$field['default'] ?? ''
						);
					}
				}
			}
		}
	}

	add_action('init', ['\SmartSlotAppointmentScheduler\Schedule_Settings', 'setup'], 11);
}
