<?php
/**
 * GFB Calendar Field Class
 *
 * @package GFB.
 */
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
} 
//will continue from here 03 July 2023. In multiple day booking, in entries backend of gravity form only last date is showing not all dates are showing for multiple date.
if ( class_exists( 'GFForms' ) ) {

	class APBGF_Appointment_Calendar extends GF_Field {
		
		public $type = 'apbgf_appointment_calendar';      

		public function get_form_editor_field_title() {
			return esc_attr__( 'GFB Calendar', 'appointment-and-booking-for-gravity-forms' );
		}

		/*
		* Where to assign this widget
		*/
		public function get_form_editor_button() {
			return array(               
				'group' => 'apbgf_field',
				'text'  => $this->get_form_editor_field_title()
			);
		}
		/*
		* Add button to the group
		*/
		public function add_button( $field_groups ) {
			$field_groups = $this->apbgf_appointment_group( $field_groups );
			return parent::add_button( $field_groups );
		}
		/*
		* Add our group
		*/
		public function apbgf_appointment_group( $field_groups ) {
			foreach ( $field_groups as $field_group ) {
				if ( $field_group['name'] == 'apbgf_field' ) {
					return $field_groups;
				}
			}
			$field_groups[] = array(
				'name'   => 'apbgf_field',
				'label'  => __( 'GFB Field', 'appointment-and-booking-for-gravity-forms' ),
				'fields' => array()
			);

			return $field_groups;
		}

		/*
		* Widget settings
		*/
		public function get_form_editor_field_settings() {
			return array(               
				'label_setting',
				'size_setting',
				'css_class_setting',
				// 'rules_setting'      
			);
		}

		public function is_conditional_logic_supported() {
			return true;
		}

		/**
		 * Field Markup
		 */
		public function get_field_input( $form, $value = '', $entry = null ) {

			$form_id         = $form['id'];
			$lead_id         = isset($entry['id']) ? $entry['id'] : '';
			$is_entry_detail = $this->is_entry_detail();
			$id              = (int) $this->id;
			$fields = $form['fields'];
		
			
			$size = 'small';
			$class = '';
			$apbgf_settings = APBGF_Setting::get_settings();

			$location_val = is_array($value) && isset($value['location']) ? $value['location'] : '';
			$service_val = is_array($value) && isset($value['service']) ? $value['service'] : '';
			$service_other_val = is_array($value) && isset($value['service_other']) ? $value['service_other'] : '';
			$staff_val = is_array($value) && isset($value['staff']) ? $value['staff'] : '';
			$date_val = is_array($value) && isset($value['date']) ? $value['date'] : 0;
			$time_val = is_array($value) && isset($value['time']) ? $value['time'] : 0;
			$cost_val = is_array($value) && isset($value['cost']) ? $value['cost'] : 0;
			$slot_qty = is_array($value) && isset($value['slot']) ? $value['slot'] : 0;
			$total_id = 0;
			$multiple_booking =  0;
			$booking_type = is_array($value) && isset($value['apbgf_booking_type']) ? $value['apbgf_booking_type'] : '';

			$fields = GFAPI::get_fields_by_type( $form, array( 'total', 'apbgf_appointment_calendar' ), true );
			$service_category_val = array();
			foreach ( $fields as $field ) {
				
				if ( 'total' == $field->type ) {
					$total_id = $field->id;
				}

				if ( 'apbgf_appointment_calendar' == $field->type ) {

					// always make this field not required as we are checking calendar fields indvidually.
					$field->isRequired = false;
					GFAPI::update_form( $form );
					
					$size = $field->size;
					$class = $field->cssClass;

					if ( isset($field->apbgf_service_category_hide) && $field->apbgf_service_category_hide ) {
						$service_category_hide = $field->apbgf_service_category_hide;
					} else {
						$service_category_hide = false;
					}

					if ( empty($service_categoryval) && isset($field->apbgf_service_category) ) {
						$service_category_val = $field->apbgf_service_category;
					}

					if ( isset($field->apbgf_location_hide) && $field->apbgf_location_hide ) {
						$location_hide = $field->apbgf_location_hide;
					} else {
						$location_hide = true;
					}

					if ( empty($location_val) && isset($field->apbgf_location) ) {
						$location_val = $field->apbgf_location;
					}

					if ( isset($field->apbgf_service_hide) && $field->apbgf_service_hide ) {
						$service_hide = $field->apbgf_service_hide;
					} else {
						$service_hide = false;
					}

					if ( empty($service_val) && isset($field->apbgf_service) ) {
						$service_val = $field->apbgf_service;
					}

					if ( isset($field->apbgf_staff_hide) && $field->apbgf_staff_hide ) {
						$staff_hide = $field->apbgf_staff_hide;
					} else {
						$staff_hide = false;
					}

					if ( empty($staff_val) && isset($field->apbgf_staff) ) {
						$staff_val = $field->apbgf_staff;
					}
				}
			}

			ob_start();         

			if ( is_admin() && $this->is_entry_edit() ) {
				$appointmentData = gform_get_meta( $lead_id, $id, true );
				?>
				<p><?php esc_html_e('Booking fields are not editable', 'appointment-and-booking-for-gravity-forms'); ?></p>
				<input type='hidden' name='input_<?php echo esc_attr($id); ?>[service_category]' value='<?php echo esc_attr($appointmentData['service_category']); ?>'>
				<input type='hidden' name='input_<?php echo esc_attr($id); ?>[location]' value='<?php echo esc_attr($appointmentData['location']); ?>'>
				<input type='hidden' name='input_<?php echo esc_attr($id); ?>[service]' value='<?php echo esc_attr($appointmentData['service']); ?>'>
				<input type='hidden' name='input_<?php echo esc_attr($id); ?>[service_other]' value='<?php echo esc_attr($appointmentData['service_other']); ?>'>
				<input type='hidden' name='input_<?php echo esc_attr($id); ?>[staff]' value='<?php echo esc_attr($appointmentData['staff']); ?>'>
				<input type='hidden' name='input_<?php echo esc_attr($id); ?>[date]' value='<?php echo esc_attr($appointmentData['date']); ?>'>
				<input type='hidden' name='input_<?php echo esc_attr($id); ?>[time]' value='<?php echo esc_attr($appointmentData['time']); ?>'>
				<input type='hidden' name='input_<?php echo esc_attr($id); ?>[slot]' value='<?php echo esc_attr($appointmentData['slot']); ?>'>
				<input type='hidden' name='input_<?php echo esc_attr($id); ?>[cost]' value='<?php echo esc_attr($appointmentData['cost']); ?>'>
				<?php
			} else if ( ! is_admin() ) {

				


				$all_locations = APBGF_Location::all_location();
			
				?>
					<div style="margin-bottom: 15px; <?php echo ( true === $location_hide ) ? 'display: none' : ''; ?>" class="ginput_container ginput_container_select ginput_container_apbgf_appointment_calendar" id="gf_apbgf_appointment_calendar_<?php echo esc_attr($form_id); ?>">
						<select class="<?php echo esc_attr($size) . ' ' . esc_attr($class); ?> apbgf_location" id="apbgf_location_<?php echo esc_attr($form_id); ?>">
							<option value="all"><?php echo esc_html($apbgf_settings['apbgf_label_location']); ?></option>
							<?php
								echo '<option value="' . esc_attr($all_locations->ID) . '" ' . selected($all_locations->ID, $location_val, false) . '>' . esc_attr($all_locations->post_title) . '</option>';
							?>
						</select>
					</div>
					<?php
				
				
				
				$all_categories = APBGF_Service::all_categories(); 
				
					if ( is_array( $all_categories ) && count( $all_categories ) > 0 ) {
						?>
					<div style="margin-bottom: 15px; <?php echo ( true === $service_category_hide ) ? 'display: none' : ''; ?>" class="ginput_container ginput_container_select ginput_container_apbgf_appointment_calendar" id="gf_apbgf_appointment_calendar_<?php echo esc_attr($form_id); ?>">
						<select class="<?php echo esc_attr($size) . ' ' . esc_attr($class); ?> apbgf_service_category" id="apbgf_service_category_<?php echo esc_attr($form_id); ?>">
							<option value="0"><?php echo esc_html($apbgf_settings['apbgf_label_category']); ?></option>
							<?php
							if (is_array($service_category_val) && !empty($service_category_val)) {
								foreach ( $all_categories as $category ) {
									
									if (in_array('0', $service_category_val) || in_array($category->term_id, $service_category_val)) {
										?>
										<option value="<?php echo esc_attr($category->term_id); ?>" <?php echo esc_attr ( selected(in_array($category->term_id, $service_category_val), true, false)); ?> > <?php echo esc_html($category->name); ?> </option>
										<?php
									}
								}
							}
							?>
						</select>
					</div>
						<?php
					}


				$all_service = APBGF_Service::all_service();
				//$all_service = APBGF_Service::apbgf_get_services_by_location_noajax($location_val);                    
					if ( is_array( $all_service ) && count( $all_service ) > 0 ) {
						?>
					<div style="margin-bottom: 15px; <?php echo ( true === $service_hide ) ? 'display: none' : ''; ?>" class="ginput_container ginput_container_select ginput_container_apbgf_appointment_calendar" id="gf_apbgf_appointment_calendar_<?php echo esc_attr($form_id); ?>">
						<select class="<?php echo esc_attr($size) . ' ' . esc_attr($class); ?> apbgf_service" id="apbgf_service_<?php echo esc_attr($form_id); ?>">
							<option value="all"><?php echo esc_html($apbgf_settings['apbgf_label_service']); ?></option>
							<?php
							foreach ($all_service as $value) {
								echo '<option value="' . esc_attr($value->ID) . '" ' . selected($value->ID, $service_val, false) . '>' . esc_attr($value->post_title) . '</option>';
							}
							?>
						</select>
					</div>
					<?php
				}

				// $all_staff = APBGF_Staff::all_staff();
			$all_staff = APBGF_Staff::apbgf_get_staff_by_service_and_location_noajax($service_val, $location_val);
					if ( is_array( $all_staff ) && count( $all_staff ) > 0 ) {                  
						?>
				<div style="margin-bottom: 15px; <?php echo ( true === $staff_hide ) ? 'display: none' : ''; ?>" class="ginput_container ginput_container_select ginput_container_apbgf_appointment_calendar" id="gf_apbgf_appointment_calendar_<?php echo esc_attr($form_id); ?>">
					<select class="<?php echo esc_attr($size) . ' ' . esc_attr($class); ?> apbgf_staff" id="apbgf_staff_<?php echo esc_attr($form_id); ?>">
						<option value="all"><?php echo esc_html($apbgf_settings['apbgf_label_staff']); ?></option>
						<?php
						foreach ($all_staff as $value) {
							$user_id = get_post_meta( $value->ID, 'wp_user', true );                
							$userdata = get_userdata( $user_id );
							if ( $userdata ) {
								$staff_name = APBGF_Staff::get_staff_display_name( $value->ID );
								if ( ! empty( $staff_name ) ) {
									echo '<option value="' . esc_attr($value->ID) . '" ' . selected($value->ID, $staff_val, false) . '>' . esc_html($staff_name) . '</option>';
								}
							}
						}
						?>
					</select>
				</div>
						<?php
					}
				wp_nonce_field('apbgf-form-submit-nonce', 'apbgf-booking-form-nonce');
					?>
			<div style="margin-bottom: 15px;" class="ginput_container ginput_container_select ginput_container_apbgf_appointment_calendar" id="gf_apbgf_appointment_calendar_<?php echo esc_attr($form_id); ?>">
				<div id="apbgf-fancy-calendar">
					<?php
					APBGF_Calendar::render_frontend( $form_id );
					?>
				</div>
				<div id="apbgf_selected_bookings"></div>
				<input type="hidden" id="apbgf_form_id" name="apbgf_form_id" class="apbgf_form_id" value="<?php echo esc_attr($form_id); ?>" />
				<input type="hidden" id="apbgf_hdn_service_category_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[service_category]" class="apbgf_service_category_input" value="<?php echo esc_attr( is_array( $service_category_val ) && ! empty( $service_category_val ) ? reset( $service_category_val ) : '' ); ?>" />
				<input type="hidden" id="apbgf_hdn_location_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[location]" class="apbgf_location_input" value="<?php echo esc_attr($location_val); ?>" />
				<input type="hidden" id="apbgf_hdn_service_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[service]" class="apbgf_service_input" value="<?php echo esc_attr($service_val); ?>" />
				<input type="hidden" id="apbgf_hdn_staff_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[staff]" class="apbgf_staff_input" value="<?php echo esc_attr($staff_val); ?>" />
				<input type="hidden" id="apbgf_date_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[date]" class="apbgf_date_input" value="<?php echo esc_attr($date_val); ?>" />
				<input type="hidden" id="apbgf_time_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[time]" class="apbgf_time_input" value="<?php echo esc_attr($time_val); ?>" />
				<input type="hidden" id="apbgf_slot_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[slot]" class="apbgf_slot_input" value="<?php echo esc_attr($slot_qty); ?>" />
				<input type="hidden" id="apbgf_cost_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[cost]" class="apbgf_cost_input" value="<?php echo esc_attr($cost_val); ?>" />            		
				<input type="hidden" id="apbgf_booking_type_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[apbgf_booking_type]" value="<?php echo esc_attr($booking_type); ?>" />
				<input type="hidden" id="apbgf_total_field_id_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[total_id]" value="<?php echo esc_attr($total_id); ?>" />
				<input type="hidden" id="apbgf_is_multiple_booking_<?php echo esc_attr($form_id); ?>" name="input_<?php echo esc_attr($id); ?>[is_multiple_booking]" value="<?php echo esc_attr($multiple_booking); ?>" />
			</div>
			<?php	
			} else {
				?>

			


			<div style="display:none; margin-bottom: 15px;" class="ginput_container ginput_container_select ginput_container_apbgf_appointment_calendar" id="gf_apbgf_appointment_calendar_<?php echo esc_attr($form_id); ?>">
				<select class="<?php echo esc_attr($size); ?>">
					<option value="all"><?php echo esc_html($apbgf_settings['apbgf_label_location']); ?></option>	        		
				</select>
			</div>	

			<div style="margin-bottom: 15px;" class="ginput_container ginput_container_select ginput_container_apbgf_appointment_calendar" id="gf_apbgf_appointment_calendar_<?php echo esc_attr($form_id); ?>">
				<select class="<?php echo esc_attr($size); ?>">
					<option value="all"><?php echo esc_html($apbgf_settings['apbgf_label_category']); ?></option>
				</select>
			</div>
			
			<div style="margin-bottom: 15px;" class="ginput_container ginput_container_select ginput_container_apbgf_appointment_calendar" id="gf_apbgf_appointment_calendar_<?php echo esc_attr($form_id); ?>">		        	
				<select class="<?php echo esc_attr($size); ?>">
					<option value="all"><?php echo esc_html($apbgf_settings['apbgf_label_service']); ?></option>	        		
				</select>
			</div>
			<div style="margin-bottom: 15px;" class="ginput_container ginput_container_select ginput_container_apbgf_appointment_calendar" id="gf_apbgf_appointment_calendar_<?php echo esc_attr($form_id); ?>">
				<select class="<?php echo esc_attr($size); ?>">
					<option value="all"><?php echo esc_html($apbgf_settings['apbgf_label_staff']); ?></option>	        		
				</select>		        	
			</div>
			<div style="margin-bottom: 15px;" class="ginput_container ginput_container_select ginput_container_apbgf_appointment_calendar" id="gf_apbgf_appointment_calendar_<?php echo esc_attr($form_id); ?>">
				<?php echo esc_html__('Calendar will be display on front-end.', 'appointment-and-booking-for-gravity-forms'); ?>
			</div>
			<?php
			}

		return ob_get_clean();
		}

		/**
		 * Is Entry Edit
		 */
		public function is_entry_edit() {
			if ( rgget( 'page' ) == 'gf_entries' && rgget( 'view' ) == 'entry' && rgpost( 'screen_mode' ) == 'edit' ) {
				return true;
			}

			return false;
		}

		/**
		 * gfb Validation Failed
		 */
		public function gfbValidationFailed( $message = '' ) {
			$this->validationFailed( $message );
			return false;           
		}

		/**
		 * Validation Failed
		 */
		private function validationFailed( $message = '' ) {
			$this->failed_validation = true;        
			$this->validation_message = empty( $this->errorMessage ) ? $message : $this->errorMessage;
		}

		/**
		 * Validation
		 */
		public function validate( $value, $form ) {         

			$form_id = absint( $form['id'] );
			$fields = $form['fields'];
			$location_hide = false;
			foreach ( $fields as $field) {
				if ( 'apbgf_appointment_calendar' === $field->type ) {                    

					if ( isset($field->apbgf_location_hide) && $field->apbgf_location_hide ) {
						$location_hide = $field->apbgf_location_hide;
					}

					break;
				}
			}

			if ( is_array( $value ) ) {
				$location_condition = isset( $value['location'] ) && ! empty( $value['location'] ) && 'all' != $value['location'] && 'no' != $value['location'] ? true : false;
				$service_condition = isset( $value['service'] ) && ! empty( $value['service'] ) && 'all' != $value['service'] && 'no' != $value['service'] ? true : false;              
				$staff_condition = isset( $value['staff'] ) && ! empty( $value['staff'] ) && 'all' != $value['staff'] && 'no' != $value['staff'] ? true : false;
				$date_condition = isset( $value['date'] ) && ! empty( $value['date'] ) && '' != $value['date'] ? true : false;
				$time_condition = isset( $value['time'] ) && ! empty( $value['time'] ) && '' != $value['time'] ? true : false;
				$slot_condition = isset( $value['slot'] ) && ! empty( $value['slot'] ) && '' != $value['slot'] ? true : false;
				
				do_action('apbgf_booking_appointment_validate_before', $value, $form, $this);

				if ( !$location_hide && !$location_condition ) {
					$this->validationFailed( __('Location field is required.', 'appointment-and-booking-for-gravity-forms') );
					return;
				}

				if ( !$service_condition ) {
					$this->validationFailed( __('Service field is required.', 'appointment-and-booking-for-gravity-forms') );
					return;
				}

				if ( !$staff_condition ) {
					$this->validationFailed( __('Staff field is required.', 'appointment-and-booking-for-gravity-forms') );
					return;
				}

				if ( !$date_condition && !$time_condition ) {
					$this->validationFailed( __('Appointment Date & Time is required.', 'appointment-and-booking-for-gravity-forms') );
					return;
				}
				
				if ( !$slot_condition ) {
					$this->validationFailed( __('Slot cannot be less than 1.', 'appointment-and-booking-for-gravity-forms') );
					return;
				} else {
					$staffData = APBGF_Staff::get_staff_by_id( $value['staff'] );
					$daySName = strtolower( gmdate('D', strtotime($value['date']) ) );
					if ( isset( $staffData['timeslots'] ) && is_array( $staffData['timeslots'] ) && count( $staffData['timeslots'] ) > 0 ) {
						#continue.
						$staff_timeslots = $staffData['timings'];
						if ( isset( $staffData['booking_type'] ) && 'fullday' == $staffData['booking_type'] ) { //check if is fullday booking type

							$multiple_booking = false;
							$total_slots_consumed = (int) APBGF_Appointment::apbgf_all_appointment_by_date_time( $value['staff'], $value['date'], '00:00 - 23:59', 'fullday', $value['service'], $value['location'] );
							$slot_capacity = (int) $staff_timeslots[ $daySName ]['capacity'];
							$remaining_capacity = $slot_capacity - $total_slots_consumed;   
	
							
						} else { //custom slots
							$total_slots_consumed = (int) APBGF_Appointment::apbgf_all_appointment_by_date_time( $value['staff'], $value['date'], $value['time'], 'custom', $value['service'], $value['location'] );
							$slot_capacity = (int) $staff_timeslots[ $daySName ]['capacity'];
							$remaining_capacity = $slot_capacity - $total_slots_consumed;
						}

						$apbgf_setting = APBGF_Setting::get_settings();


						// this block will work only if it is not multiple day booking.
						if ( $value['slot'] > $remaining_capacity && '1' != $value['is_multiple_booking'] ) {
							$this->validationFailed( __('Slot capacity exceeded.', 'appointment-and-booking-for-gravity-forms') );
							return;
						}
					}                   
				}

				do_action('apbgf_booking_appointment_validate_after', $value, $form, $this);              
			}
		}

		/**
		* Make this function as void() so double meta should not saved.
		*/
		public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {           

			#continue
			if ( is_array( $value ) ) {             

				return $value;
			}

			return $value;
		}

		/**
		* Show service title entry single
		*/
		public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {  

			if ( !is_array($value) ) {
				$value = unserialize($value);
			}
			
			// phpcs:ignore
			$lead_id = isset($_GET['lid']) ? absint(wp_unslash( $_GET['lid'] ) ) : 0;

			$appointment_id = gform_get_meta( $lead_id, 'apbgf_appointment', true );
			$date = get_post_meta( $appointment_id, 'date', true );

			$service_other = ( is_array($value) && isset( $value['service_other'] ) && ! empty( $value['service_other'] ) ) ? $value['service_other'] : '';

			if ( is_array( $date ) ) {
				$value['date'] = $date;
			}           

			$html = '';
			if ( is_array( $value ) ) { 
				foreach ( $value as $k => $val ) {
					if ( 'location' == $k && 'all' != $val ) {
						// Translators: 1%$s is Location Name
						$html .= sprintf(esc_html__('Location Name: %1$s', 'appointment-and-booking-for-gravity-forms'), get_the_title($val));
						$html .= '<br/>';
						// Translators: 1%$s is Location ID
						$html .= sprintf(esc_html__('Location ID: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
						$html .= '<br/><br/>';
					}

					if ( 'service' == $k ) {
						// Translators: 1%$s is Service Name
						$html .= sprintf(esc_html__('Service Name: %1$s', 'appointment-and-booking-for-gravity-forms'), get_the_title($val));
						$html .= '<br/>';
						// Translators: 1%$s is Service ID
						$html .= sprintf(esc_html__('Service ID: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
						if ( $service_other != '' ) {
							$html .= '<br/>';
							// Translators: 1%$s is for Other
							$html .= sprintf(esc_html__('Other: %1$s', 'appointment-and-booking-for-gravity-forms'), $service_other);
						}
						$html .= '<br/><br/>';
					}                   

					if ( 'staff' == $k ) {
						// Translators: 1%$s is for Staff Name
						$html .= sprintf(esc_html__('Staff Name: %1$s', 'appointment-and-booking-for-gravity-forms'), get_the_title($val));
						$html .= '<br/>';
						// Translators: 1%$s is for Staff ID
						$html .= sprintf(esc_html__('Staff ID: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
						$html .= '<br/><br/>';
					}

					if ( 'date' == $k ) {
						
						if ( is_array($val) ) {
							foreach ( $val as $val ) {
								$val = apply_filters('apbgf_entry_value_date_format', $val );
								// Translators: 1%$s is for Appointment Date
								$html .= sprintf(esc_html__('Appointment Date: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
								$html .= '<br/>';
							}
						} else {
							$val = apply_filters('apbgf_entry_value_date_format', $val );
							// Translators: 1%$s is for Appointment Date
							$html .= sprintf(esc_html__('Appointment Date: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
							$html .= '<br/>';
						}                   
					}

					if ( 'time' == $k ) {
						$val = apply_filters('apbgf_entry_value_time_format', $val );
						if ( isset($value['apbgf_booking_type']) && 'fullday' === $value['apbgf_booking_type'] ) {
							// Translators: 1%$s is for Appointment Time
							$html .= sprintf(esc_html__('Appointment Time: %1$s', 'appointment-and-booking-for-gravity-forms'), esc_html__('Fullday', 'appointment-and-booking-for-gravity-forms'));
						} else {
							// Translators: 1%$s is for Appointment Time
							$html .= sprintf(esc_html__('Appointment Time: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);   
						}
						$html .= '<br/><br/>';
					}

					if ( 'slot' == $k ) {
						// Translators: 1%$s is for Slot Capacity
						$html .= sprintf(esc_html__('Slot Capacity: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);                  
						$html .= '<br/><br/>';
					}

					if ( 'cost' == $k && true === apply_filters('apbgf_show_price_details', true) ) {
						// Translators: 1%$s is for Total Cost
						$html .= sprintf(esc_html__('Total Cost: %1$s', 'appointment-and-booking-for-gravity-forms'), apbgf_price_format($val));
						$html .= '<br/>';
					}
				}
				
				return $html;
			}

			return $value;
		}

		/**
		* Merge tag, on notifications, confirmations
		*/
		public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {

			$data = !empty( rgpost('input_' . $input_id) ) ? rgpost('input_' . $input_id) : array();      

			if (!empty( $data ) ) { 
				$value = apply_filters('apbgf_get_value_merge_tag', rgpost('input_' . $input_id));
				$service_other = ( isset( $value['service_other'] ) && ! empty( $value['service_other'] ) ) ? $value['service_other'] : '';
				do_action( 'apbgf_get_value_merge_tag', $value );
			}

			$html = '';
			if ( 'location' == $modifier ) {

				// Translators: 1%$s is for Location Name
				$html  .= sprintf(__('Location Name: %1$s', 'appointment-and-booking-for-gravity-forms'), get_the_title($value['location']));
				$html .= '<br/>';
				// Translators: 1%$s is for Location ID
				$html .= sprintf(esc_html__('Location ID: %1$s', 'appointment-and-booking-for-gravity-forms'), $value['location']);
				return $html;

			} else if ( 'service' == $modifier ) {

				// Translators: 1%$s is for Service Name
				$html .= sprintf(esc_html__('Service Name: %1$s', 'appointment-and-booking-for-gravity-forms'), get_the_title($value['service']));
				$html .= '<br/>';
				// Translators: 1%$s is for Service ID
				$html .= sprintf(esc_html__('Service ID: %1$s', 'appointment-and-booking-for-gravity-forms'), $value['service']);
				if ( $value['service_other'] != '' ) {
					$html .= '<br/>';
					// Translators: 1%$s is for Other
					$html .= sprintf(esc_html__('Other: %1$s', 'appointment-and-booking-for-gravity-forms'), $value['service_other']);
				}
				return $html;

			} else if ( 'staff' == $modifier ) {

				// Translators: 1%$s is for Staff Name
				$html .= sprintf(esc_html__('Staff Name: %1$s', 'appointment-and-booking-for-gravity-forms'), get_the_title($value['staff']));
				$html .= '<br/>';
				// Translators: 1%$s is for Staff ID
				$html .= sprintf(esc_html__('Staff ID: %1$s', 'appointment-and-booking-for-gravity-forms'), $value['staff']);
				return $html;

			} else if ( 'date' == $modifier ) {

				if ( isset( $data['apbgf_selected_dates'] ) && is_array($data['apbgf_selected_dates']) && count($data['apbgf_selected_dates']) > 0 ) {
					foreach ( $data['apbgf_selected_dates'] as $val ) {
						$val = apply_filters('apbgf_entry_value_date_format', $val );
					   // Translators: 1%$s is for Appointment Date
					   $html .= sprintf(esc_html__('Appointment Date: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
					}
				} else {
					$val = apply_filters('apbgf_entry_value_date_format', $value['date'] );
					   // Translators: 1%$s is for Appointment Date
					   $html .= sprintf(esc_html__('Appointment Date: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
				}
				return $html;

			} else if ( 'time' == $modifier ) {

				$val = apply_filters('apbgf_entry_value_time_format', $value['time'] );
				if ( isset($value['apbgf_booking_type']) && 'fullday' === $value['apbgf_booking_type'] ) {
					   // Translators: 1%$s is for Appointment Time
					   $html .= sprintf(esc_html__('Appointment Time: %1$s', 'appointment-and-booking-for-gravity-forms'), esc_html__('Fullday', 'appointment-and-booking-for-gravity-forms'));
				} else {
					   // Translators: 1%$s is for Appointment Time
					   $html .= sprintf(esc_html__('Appointment Time: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);   
				}
				return $html;
			} else if ( 'slot' == $modifier ) {
					// Translators: 1%$s is for Slot Capacity
					 return sprintf(esc_html__('Slot Capacity: %1$s', 'appointment-and-booking-for-gravity-forms'), $value['slot']);

			} else if ( 'cost' == $modifier ) {
					// Translators: 1%$s is for Total Cost
					return sprintf(esc_html__('Total Cost: %1$s', 'appointment-and-booking-for-gravity-forms'), apbgf_price_format($value['cost']));
			}

			
			if ( is_array( $value ) ) { 
				foreach ( $value as $k => $val ) {
					if ( 'location' == $k && 'all' != $val ) {
						// Translators: 1%$s is for Location Name
						$html .= sprintf(esc_html__('Location Name: %1$s', 'appointment-and-booking-for-gravity-forms'), get_the_title($val));
						$html .= '<br/>';
						// Translators: 1%$s is for Location ID
						$html .= sprintf(esc_html__('Location ID: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
						$html .= '<br/><br/>';
					}

					if ( 'service' == $k ) {
						// Translators: 1%$s is for Service Name
						$html .= sprintf(esc_html__('Service Name: %1$s', 'appointment-and-booking-for-gravity-forms'), get_the_title($val));
						$html .= '<br/>';
						// Translators: 1%$s is for Service ID
						$html .= sprintf(esc_html__('Service ID: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
						if ( $service_other != '' ) {
							$html .= '<br/>';
							// Translators: 1%$s is for other service
							$html .= sprintf(esc_html__('Other: %1$s', 'appointment-and-booking-for-gravity-forms'), $service_other);
						}
						$html .= '<br/><br/>';
					}

					if ( 'staff' == $k ) {
						// Translators: 1%$s is Staff Name
						$html .= sprintf(esc_html__('Staff Name: %1$s', 'appointment-and-booking-for-gravity-forms'), get_the_title($val));
						$html .= '<br/>';
						// Translators: 1%$s is Staff ID
						$html .= sprintf(esc_html__('Staff ID: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
						$html .= '<br/><br/>';
					}

					if ( 'date' == $k ) {
						
						if ( isset( $data['apbgf_selected_dates'] ) && is_array($data['apbgf_selected_dates']) && count($data['apbgf_selected_dates']) > 0 ) {
							foreach ( $data['apbgf_selected_dates'] as $val ) {
								$val = apply_filters('apbgf_entry_value_date_format', $val );
								// Translators: 1%$s is appointment date
								$html .= sprintf(esc_html__('Appointment Date: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
								$html .= '<br/>';
							}
						} else {
							$val = apply_filters('apbgf_entry_value_date_format', $val );
							// Translators: 1%$s is appointment date
							$html .= sprintf(esc_html__('Appointment Date: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);
							$html .= '<br/>';
						}                   
					}

					if ( 'time' == $k ) {
						$val = apply_filters('apbgf_entry_value_time_format', $val );
						if ( isset($value['apbgf_booking_type']) && 'fullday' === $value['apbgf_booking_type'] ) {
						// Translators: 1%$s is appointment time
						$html .= sprintf(esc_html__('Appointment Time: %1$s', 'appointment-and-booking-for-gravity-forms'), esc_html__('Fullday', 'appointment-and-booking-for-gravity-forms'));
						} else {
							// Translators: 1%$s is appointment time
							$html .= sprintf(esc_html__('Appointment Time: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);     
						}
						$html .= '<br/><br/>';
					}

					if ( 'slot' == $k ) {
						// Translators: 1%$s is the slot capacity 
						$html .= sprintf(esc_html__('Slot Capacity: %1$s', 'appointment-and-booking-for-gravity-forms'), $val);                     
						$html .= '<br/><br/>';
					}

					if ( 'cost' == $k && true === apply_filters('apbgf_show_price_details', true) ) {
						// Translators: 1%$s is the total cost
						$html .= sprintf(esc_html__('Total Cost: %1$s', 'appointment-and-booking-for-gravity-forms'), apbgf_price_format($val));
						$html .= '<br/><br/>';
					}
				}
			}

			return $html;
		}
		
		public function get_form_inline_script_on_page_render( $form ) {
			$fields = $form['fields'];
			$form_id = absint( $form['id'] );
			$id = '';
			$apbgf_settings = APBGF_Setting::get_settings();
			$flag = false;
			$apbgf_location = '';
			$apbgf_service = '';
			$apbgf_staff = '';
			$apbgf_service_category = '';

			foreach ( $fields as $field ) {
				if ( 'apbgf_appointment_calendar' === $field->type ) {
					$id = $field->id;
					$apbgf_location = $field->apbgf_location;
					$apbgf_service_category = $field->apbgf_service_category;
					$apbgf_service = $field->apbgf_service;
					$apbgf_staff = $field->apbgf_staff;
					$flag = true;
					break;
				}
			}

			if ( $flag ) {
			
				// Register and enqueue placeholder style
				wp_register_style( 'apbgf-calendar-field', false );
				wp_enqueue_style( 'apbgf-calendar-field' );

				// Output inline dynamic CSS using PHP variables
				$custom_css = '
					:root {
						--apbgf-cal-bg-gradient1: ' . esc_attr( $apbgf_settings['apbgf_cal_gradient_color_top'] ) . ';
						--apbgf-cal-bg-gradient2: ' . esc_attr( $apbgf_settings['apbgf_cal_gradient_color_bottom'] ) . ';
						--apbgf-cal-border-color: ' . esc_attr( $apbgf_settings['apbgf_cal_border_color'] ) . ';
						--apbgf-cal-header-bg-color: ' . esc_attr( $apbgf_settings['apbgf_cal_header_bg_color'] ) . ';
						--apbgf-cal-header-txt-color: ' . esc_attr( $apbgf_settings['apbgf_cal_header_text_color'] ) . ';
						--apbgf-cal-txt-color: ' . esc_attr( $apbgf_settings['apbgf_cal_text_color'] ) . ';
						--apbgf-cal-sel-day-txt-color: ' . esc_attr( $apbgf_settings['apbgf_cal_selected_text_color'] ) . ';
						--apbgf-cal-sel-day-bg-color: ' . esc_attr( $apbgf_settings['apbgf_cal_selected_text_bg_color'] ) . ';
						--apbgf-cal-avl-day-txt-color: ' . esc_attr( $apbgf_settings['apbgf_cal_available_days_text_color'] ) . ';
						--apbgf-cal-avl-day-bg-color: ' . esc_attr( $apbgf_settings['apbgf_cal_available_days_bg_color'] ) . ';
						--apbgf-cal-hol-day-txt-color: ' . esc_attr( $apbgf_settings['apbgf_cal_holiday_days_text_color'] ) . ';
						--apbgf-cal-hol-day-bg-color: ' . esc_attr( $apbgf_settings['apbgf_cal_holiday_days_bg_color'] ) . ';
					}
					.apbgf-table-container .apbgf-cal-table,
					.apbgf-table-container #apbgf-timeslots-table-container {
						background-image: linear-gradient(var(--apbgf-cal-bg-gradient1), var(--apbgf-cal-bg-gradient2)) !important;
					}
					.apbgf-cal-container .apbgf-cal-table {
						color: var(--apbgf-cal-txt-color);
						font-size: 13px;
						width: 100%;
						max-width: 560px;
						max-height: 372px;
						box-shadow: 0px 8px 59px -13px rgb(0 0 0 / 21%);
					}
					.apbgf-cal-container h3 {
						background: var(--apbgf-cal-header-bg-color)!important;
						color: var(--apbgf-cal-header-txt-color)!important;
						border: 1px solid var(--apbgf-cal-border-color)!important;
						border-bottom: 0!important;
						font-size: 13px;
						border-radius: 0!important;
					}
					.apbgf-cal-container .apbgf-month-changer {
						color: var(--apbgf-cal-header-txt-color)!important;
						font-size: 13px;
					}
					.apbgf-cal-table-bordered tbody tr td {
						border: 0.5px solid var(--apbgf-cal-border-color)!important;
						width: 80px;
					}
					.apbgf-cal-table-bordered thead tr {
						background: var(--apbgf-cal-header-bg-color)!important;
						color: var(--apbgf-cal-header-txt-color)!important;
						border-left: 1px solid var(--apbgf-cal-border-color)!important;
						border-right: 1px solid var(--apbgf-cal-border-color)!important;
					}
					.apbgf-cal-table-bordered thead tr th {
						border: 0!important;
						padding: 12px!important;
						font-weight: normal!important;
					}
					.apbgf-cal-table-bordered thead tr th:first-child {
						border-left: 0.5px solid var(--apbgf-cal-border-color)!important;
					}
					.apbgf-cal-table-bordered thead tr th:last-child {
						border-right: 0.5px solid var(--apbgf-cal-border-color)!important;
					}
				';

				wp_add_inline_style( 'apbgf-calendar-field', wp_strip_all_tags( $custom_css ) );

				// Determine asset suffixes
				$minimized = defined('APBGF_LIVE_MODE') && APBGF_LIVE_MODE ? '.min' : '';
				$clear_cache = defined('APBGF_LIVE_MODE') && APBGF_LIVE_MODE ? '' : '?t=' . gmdate('ymdhis');

				// Enqueue styles
				wp_enqueue_style( 'apbgf-font-awesome-style-min', esc_url( APBGF_ADMIN_CSS_URL ) . 'font-awesome/font-awesome.min.css', array(), APBGF_VERSION . $clear_cache, 'all' );
				wp_enqueue_style( 'apbgf-font-awesome-style', esc_url( APBGF_ADMIN_CSS_URL ) . 'font-awesome/font-awesome-fonts.css', array( 'apbgf-font-awesome-style-min' ), APBGF_VERSION . $clear_cache, 'all' );
				wp_enqueue_style( 'apbgf-calendar-style', APBGF_ADMIN_CSS_URL . 'apbgf-calendar-style' . $minimized . '.css', array(), APBGF_VERSION . $clear_cache, 'all' );

				// Enqueue and localize calendar script
				wp_register_script( 'apbgf-calendar-script', APBGF_ADMIN_JS_URL . 'apbgf-calendar-script' . $minimized . '.js', array( 'jquery' ), APBGF_VERSION . $clear_cache, true );
				wp_localize_script( 'apbgf-calendar-script', 'apbgf_calendar', array(
					'ajaxurl' => admin_url( 'admin-ajax.php' ),
					'nonce'   => wp_create_nonce( 'appointment-and-booking-for-gravity-forms' ),
					'prior_months' => $apbgf_settings['apbgf_prior_months_book_appointment'],
					'show_timeslot' => $apbgf_settings['apbgf_show_timeslot'],
				) );
				wp_enqueue_script( 'apbgf-calendar-script' );

				// Enqueue and localize common script
				$input = rgpost( 'input_' . $id );
				wp_register_script( 'apbgf-common-script', APBGF_COMMON_URL . 'apbgf-common-script' . $minimized . '.js', array( 'jquery' ), APBGF_VERSION . $clear_cache, true );
				wp_localize_script( 'apbgf-common-script', 'apbgf_common', array(
					'ajaxurl'  => admin_url( 'admin-ajax.php' ),
					'nonce'    => wp_create_nonce( 'appointment-and-booking-for-gravity-forms' ),
					'form_id'  => $form_id,
					'prior_months' => $apbgf_settings['apbgf_prior_months_book_appointment'],
					'is_admin' => 'no',
					'loadingText' => __( 'loading...', 'appointment-and-booking-for-gravity-forms' ),
					'all_service_category_text' => isset( $apbgf_settings['apbgf_label_category'] ) ? $apbgf_settings['apbgf_label_category'] : '',
					'no_service_category_text'  => __( 'No Service Category Found', 'appointment-and-booking-for-gravity-forms' ),
					'all_service_text'          => isset( $apbgf_settings['apbgf_label_service'] ) ? $apbgf_settings['apbgf_label_service'] : '',
					'no_service_text'           => __( 'No Service Found', 'appointment-and-booking-for-gravity-forms' ),
					'all_location_text'         => isset( $apbgf_settings['apbgf_label_location'] ) ? $apbgf_settings['apbgf_label_location'] : '',
					'no_location_text'          => __( 'No Location Found', 'appointment-and-booking-for-gravity-forms' ),
					'all_staff_text'            => isset( $apbgf_settings['apbgf_label_staff'] ) ? $apbgf_settings['apbgf_label_staff'] : '',
					'no_staff_text'             => __( 'No Staff Found', 'appointment-and-booking-for-gravity-forms' ),
					'default_location'          => is_array( $input ) && isset( $input['location'] ) ? sanitize_text_field( $input['location'] ) : $apbgf_location,
					'default_service'           => is_array( $input ) && isset( $input['service'] ) ? sanitize_text_field( $input['service'] ) : $apbgf_service,
					'default_staff'             => is_array( $input ) && isset( $input['staff'] ) ? sanitize_text_field( $input['staff'] ) : $apbgf_staff,
					'default_service_category'  => is_array( $input ) && isset( $input['service_category'] ) ? sanitize_text_field( $input['service_category'] ) : $apbgf_service_category,
				) );
				wp_enqueue_script( 'apbgf-common-script' );
			}
		}


		public function get_form_editor_inline_script_on_page_render() {
			$script ="			
			gform.addFilter('gform_form_editor_can_field_be_added', function (canFieldBeAdded, type) {				
				if (type == 'apbgf_appointment_calendar') {					
					if (GetFieldsByType(['apbgf_appointment_calendar']).length > 0) {
						alert(" . json_encode( esc_html__( 'Only one Booking Appointment Calendar field can be added to the form', 'appointment-and-booking-for-gravity-forms' ) ) . ');
						return false;
					}
				}
				return canFieldBeAdded;
			});' . PHP_EOL;

			return $script;
		}
	} // end class
	GF_Fields::register( new APBGF_Appointment_Calendar() );
} // end if
