<?php
/**
 * Student booking shortcode.
 *
 * @package TutorHelper_Bookings
 */

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

/**
 * Renders the Core student booking form.
 */
final class TutorHelper_Student_Booking_Shortcode {

	/**
	 * Student booking shortcode name.
	 *
	 * @var string
	 */
	const SHORTCODE =
		'tutorhelper_student_booking';

	/**
	 * Register shortcode hooks.
	 *
	 * @return void
	 */
	public static function init() {
		add_shortcode(
			self::SHORTCODE,
			array(
				__CLASS__,
				'render',
			)
		);
	}

	/**
	 * Render the student booking form.
	 *
	 * @return string
	 */
	public static function render() {
		if ( ! is_user_logged_in() ) {
			$login_url =
				TutorHelper_Settings::
					get_login_url();

			$booking_url =
				TutorHelper_Settings::
					get_student_booking_url();

			if ( $booking_url ) {
				$login_url =
					add_query_arg(
						'redirect_to',
						$booking_url,
						$login_url
					);
			}

			return self::render_notice(
				__(
					'Please log in to request a lesson.',
					'tutorhelper-bookings'
				),
				'warning',
				$login_url,
				__(
					'Log in',
					'tutorhelper-bookings'
				)
			);
		}

		$viewer_user_id =
            get_current_user_id();

        $student =
            TutorHelper_Students::get_student(
                $viewer_user_id
            );

        $is_student =
            $student instanceof WP_User;

        $is_tutor_preview =
            current_user_can(
                'manage_options'
            );

        if (
            ! $is_student
            && ! $is_tutor_preview
        ) {
            return self::render_notice(
                __(
                    'Lesson requests are only available to registered students.',
                    'tutorhelper-bookings'
                ),
                'warning'
            );
        }

        $student_user_id =
            $is_student
                ? $viewer_user_id
                : 0;

		if ( $is_student ) {
            $booking_blocked =
                1 === absint(
                    get_user_meta(
                        $student_user_id,
                        TutorHelper_Students::
                            META_BOOKING_BLOCKED,
                        true
                    )
                );

            if ( $booking_blocked ) {
                $blocked_message =
                    sanitize_text_field(
                        get_user_meta(
                            $student_user_id,
                            TutorHelper_Students::
                                META_BOOKING_BLOCKED_MESSAGE,
                            true
                        )
                    );

                if ( '' === $blocked_message ) {
                    $blocked_message = __(
                        'Online lesson requests are not currently available for your account.',
                        'tutorhelper-bookings'
                    );
                }

                return self::render_notice(
                    $blocked_message,
                    'warning'
                );
            }
        }
        

		TutorHelper_Student_Booking_Frontend::
			enqueue_assets();

		$labels =
			TutorHelper_Student_Booking_Labels::
				get_all();

        $booking_types =
			self::get_public_booking_types(
				$student_user_id
			);
    

		ob_start();
		?>
		<section
            class="tutorhelper-student-booking<?php echo $is_tutor_preview && ! $is_student ? ' tutorhelper-student-booking--preview' : ''; ?>"
            data-tutorhelper-student-booking
            data-booking-mode="<?php echo esc_attr( $is_student ? 'student' : 'preview' ); ?>"
            data-booking-student-id="<?php echo esc_attr( $student_user_id ); ?>"
        >

        <?php if ( $is_tutor_preview && ! $is_student ) : ?>
            <div
                class="tutorhelper-student-booking__preview-notice"
                role="status"
            >
                <?php
                esc_html_e(
                    'Preview mode: this is how the booking form appears to students. No booking will be created.',
                    'tutorhelper-bookings'
                );
                ?>
            </div>
        <?php endif; ?>

			<header
				class="tutorhelper-student-booking__header"
			>
				<h2
					class="tutorhelper-student-booking__heading"
				>
					<?php
					echo esc_html(
						$labels['heading']
					);
					?>
				</h2>

				<p
					class="tutorhelper-student-booking__introduction"
				>
					<?php
					echo esc_html(
						$labels['introduction']
					);
					?>
				</p>
			</header>

			<div
				class="tutorhelper-student-booking__message"
				data-booking-message
				hidden
				role="status"
				aria-live="polite"
			></div>

			<form
				class="tutorhelper-student-booking__form"
				data-booking-form
				novalidate
			>
				<div
					class="tutorhelper-student-booking__selection-grid"
				>
					<section
						class="tutorhelper-student-booking__panel"
						aria-labelledby="tutorhelper-booking-service-heading"
					>
						<h3
							id="tutorhelper-booking-service-heading"
							class="tutorhelper-student-booking__panel-heading"
						>
							<?php
							echo esc_html(
								$labels[
									'select_service'
								]
							);
							?>
							<span
								class="tutorhelper-student-booking__required"
								aria-hidden="true"
							>*</span>
						</h3>

						<div
                            class="tutorhelper-student-booking__services"
                            data-booking-services
                        >
                            <?php if ( empty( $booking_types ) ) : ?>
                                <p
                                    class="tutorhelper-student-booking__placeholder"
                                >
                                    <?php
                                    esc_html_e(
                                        'No services are currently available for online booking.',
                                        'tutorhelper-bookings'
                                    );
                                    ?>
                                </p>
                            <?php else : ?>
                                <?php
                                foreach (
                                    $booking_types
                                        as $booking_type
                                ) :
                                    $booking_type_id =
                                        absint(
                                            $booking_type->id
                                        );

                                    $duration_minutes =
                                        absint(
                                            $booking_type
                                                ->duration_minutes
                                        );

                                    $price_minor_units =
										absint(
											$booking_type
												->price_minor_units
										);

									if ( $student_user_id ) {

										$pricing =
											TutorHelper_Booking_Records::
												resolve_pricing(
													$student_user_id,
													$booking_type_id,
													$duration_minutes
												);

										if ( ! is_wp_error( $pricing ) ) {
											$price_minor_units =
												absint(
													$pricing[
														'price_minor_units'
													]
												);
										}
									}

									$price_label =
										self::format_price(
											$price_minor_units
										);

                                    $locations =
                                        self::get_booking_type_locations(
                                            $booking_type
                                        );

                                    $primary_location =
                                        ! empty( $locations )
                                            ? $locations[0]
                                            : '';

                                    $location_label =
                                        $primary_location
                                            ? self::get_location_label(
                                                $primary_location
                                            )
                                            : '';

                                    $cancellations_allowed =
                                        1 === absint(
                                            $booking_type
                                                ->cancellations_allowed
                                        );

                                    $cancellation_notice_hours =
                                        absint(
                                            $booking_type
                                                ->cancellation_notice_hours
                                        );

                                    $colour =
                                        sanitize_hex_color(
                                            $booking_type->colour
                                        );

									$student_can_book =
										TutorHelper_Student_Booking_Access::
											can_book(
												$booking_type,
												$student_user_id
											);

									$unavailable_message =
										$student_can_book
											? ''
											: TutorHelper_Student_Booking_Access::
												get_unavailable_message(
													$booking_type,
													$student_user_id
												);

                                    if ( ! $colour ) {
                                        $colour = '#328bb8';
                                    }
                                    ?>
                                    <button
                                        type="button"
                                        class="tutorhelper-student-booking__service<?php echo $student_can_book ? '' : ' is-unavailable'; ?>"
                                        data-booking-service
                                        data-booking-type-id="<?php echo esc_attr( $booking_type_id ); ?>"
										data-booking-bookable="<?php echo esc_attr( $student_can_book ? '1' : '0' ); ?>"
										<?php disabled( ! $student_can_book ); ?>
                                        data-booking-title="<?php echo esc_attr( $booking_type->title ); ?>"
                                        data-booking-duration="<?php echo esc_attr( $duration_minutes ); ?>"
                                        data-booking-price="<?php echo esc_attr( $price_label ); ?>"
                                        data-booking-location-type="<?php echo esc_attr( $primary_location ); ?>"
                                        data-booking-location-label="<?php echo esc_attr( $location_label ); ?>"
                                        data-booking-cancellations-allowed="<?php echo esc_attr( $cancellations_allowed ? '1' : '0' ); ?>"
                                        data-booking-cancellation-notice-hours="<?php echo esc_attr( $cancellation_notice_hours ); ?>"
                                        style="--tutorhelper-service-colour: <?php echo esc_attr( $colour ); ?>;"
                                        aria-pressed="false"
                                    >
                                        <span
                                            class="tutorhelper-student-booking__service-title"
                                        >
                                            <?php
                                            echo esc_html(
                                                $booking_type->title
                                            );
                                            ?>
                                        </span>

                                        <span
                                            class="tutorhelper-student-booking__service-meta"
                                        >
                                            <?php
                                            printf(
												/* translators: 1: duration in minutes, 2: price. */
												esc_html__(
													'%1$d mins · %2$s',
													'tutorhelper-bookings'
												),
												esc_html(
													(string) $duration_minutes
												),
												esc_html( $price_label )
											);
                                            ?>
                                        </span>

                                        <?php
                                        if (
                                            ! empty(
                                                $booking_type
                                                    ->description
                                            )
                                        ) :
                                            ?>
                                            <span
                                                class="tutorhelper-student-booking__service-description"
                                            >
                                                <?php
                                                echo esc_html(
                                                    $booking_type
                                                        ->description
                                                );
                                                ?>
                                            </span>
                                        <?php endif; ?>

										<?php if (
											! $student_can_book
											&& $unavailable_message
										) : ?>

											<span
												class="tutorhelper-student-booking__service-access"
											>
												<?php
												echo esc_html(
													$unavailable_message
												);
												?>
											</span>

										<?php endif; ?>

                                    </button>
                                <?php endforeach; ?>
                            <?php endif; ?>
                        </div>
					</section>

					<section
						class="tutorhelper-student-booking__panel"
						aria-labelledby="tutorhelper-booking-date-heading"
					>
						<h3
							id="tutorhelper-booking-date-heading"
							class="tutorhelper-student-booking__panel-heading"
						>
							<?php
							echo esc_html(
								$labels['select_date']
							);
							?>
							<span
								class="tutorhelper-student-booking__required"
								aria-hidden="true"
							>*</span>
						</h3>

						<div
							class="tutorhelper-student-booking__calendar"
							data-booking-calendar
						>
							<p
								class="tutorhelper-student-booking__placeholder"
							>
								<?php
								esc_html_e(
									'Select a service to view available dates.',
									'tutorhelper-bookings'
								);
								?>
							</p>
						</div>
					</section>

					<section
						class="tutorhelper-student-booking__panel"
						aria-labelledby="tutorhelper-booking-time-heading"
					>
						<h3
							id="tutorhelper-booking-time-heading"
							class="tutorhelper-student-booking__panel-heading"
						>
							<?php
							echo esc_html(
								$labels['select_time']
							);
							?>
							<span
								class="tutorhelper-student-booking__required"
								aria-hidden="true"
							>*</span>
						</h3>

						<div
							class="tutorhelper-student-booking__times"
							data-booking-times
						>
							<p
								class="tutorhelper-student-booking__placeholder"
							>
								<?php
								esc_html_e(
									'Select a date to view available times.',
									'tutorhelper-bookings'
								);
								?>
							</p>
						</div>
					</section>
				</div>

				<section
					class="tutorhelper-student-booking__summary"
					aria-labelledby="tutorhelper-booking-summary-heading"
				>
					<h3
						id="tutorhelper-booking-summary-heading"
						class="tutorhelper-student-booking__summary-heading"
					>
						<?php
						esc_html_e(
							'Booking Summary',
							'tutorhelper-bookings'
						);
						?>
					</h3>

					<div
						class="tutorhelper-student-booking__summary-grid"
					>
						<div>
							<span
								class="tutorhelper-student-booking__summary-label"
							>
								<?php
								echo esc_html(
									$labels['service']
								);
								?>
							</span>

							<strong
								data-summary-service
							>
								<?php
								esc_html_e(
									'Not selected',
									'tutorhelper-bookings'
								);
								?>
							</strong>
						</div>

						<div>
							<span
								class="tutorhelper-student-booking__summary-label"
							>
								<?php
								esc_html_e(
									'Date',
									'tutorhelper-bookings'
								);
								?>
							</span>

							<strong
								data-summary-date
							>
								<?php
								esc_html_e(
									'Not selected',
									'tutorhelper-bookings'
								);
								?>
							</strong>
						</div>

						<div>
							<span
								class="tutorhelper-student-booking__summary-label"
							>
								<?php
								esc_html_e(
									'Time',
									'tutorhelper-bookings'
								);
								?>
							</span>

							<strong
								data-summary-time
							>
								<?php
								esc_html_e(
									'Not selected',
									'tutorhelper-bookings'
								);
								?>
							</strong>
						</div>

						<div>
							<span
								class="tutorhelper-student-booking__summary-label"
							>
								<?php
								esc_html_e(
									'Location',
									'tutorhelper-bookings'
								);
								?>
							</span>

							<strong
								data-summary-location
							>
								<?php
								esc_html_e(
									'Not selected',
									'tutorhelper-bookings'
								);
								?>
							</strong>
						</div>
					</div>

					<div
						class="tutorhelper-student-booking__policy"
					>
						<h4>
							<?php
							esc_html_e(
								'Cancellation policy',
								'tutorhelper-bookings'
							);
							?>
						</h4>

						<p
							data-booking-cancellation-policy
						>
							<?php
							esc_html_e(
								'The cancellation policy for your selected service will appear here.',
								'tutorhelper-bookings'
							);
							?>
						</p>

						<label
							class="tutorhelper-student-booking__policy-agreement"
						>
							<input
								type="checkbox"
								name="policy_agreed"
								value="1"
								required
							>

							<span>
								<?php
								esc_html_e(
									'I agree to the cancellation policy.',
									'tutorhelper-bookings'
								);
								?>
							</span>
						</label>
					</div>

					<input
						type="hidden"
						name="booking_type_id"
						value=""
						data-booking-type-id
					>

					<input
						type="hidden"
						name="booking_start"
						value=""
						data-booking-start
					>

					<input
						type="hidden"
						name="booking_end"
						value=""
						data-booking-end
					>

					<input
						type="hidden"
						name="timezone"
						value="<?php echo esc_attr( wp_timezone_string() ); ?>"
					>

					<input
						type="hidden"
						name="location_type"
						value=""
						data-booking-location-type
					>

					<div
						class="tutorhelper-student-booking__actions"
					>
						<button
							type="submit"
							class="tutorhelper-student-booking__submit"
							data-booking-submit
							<?php disabled( true ); ?>
						>
							<?php
							esc_html_e(
								'Request lesson',
								'tutorhelper-bookings'
							);
							?>
						</button>
					</div>
				</section>
			</form>

			
		</section>
		<?php

		return ob_get_clean();
	}

    /**
     * Return Booking Types available through the public form.
     *
     * @return array
     */
    private static function get_public_booking_types(
		$student_user_id = 0
	) {
		$booking_types =
			TutorHelper_Booking_Types::get_active();

		if ( ! is_array( $booking_types ) ) {
			return array();
		}

		return array_values(
			array_filter(
				$booking_types,
				static function (
					$booking_type
				) use (
					$student_user_id
				) {
					return
						TutorHelper_Student_Booking_Access::
							can_view(
								$booking_type,
								$student_user_id
							);
				}
			)
		);
	}

    /**
     * Return a Booking Type's supported locations.
     *
     * @param object $booking_type Booking Type record.
     *
     * @return array
     */
    private static function get_booking_type_locations(
        $booking_type
    ) {
        $locations = array();

        if (
            is_object( $booking_type )
            && ! empty(
                $booking_type->location_types
            )
        ) {
            $locations = explode(
                ',',
                $booking_type->location_types
            );
        }

        if (
            empty( $locations )
            && is_object( $booking_type )
            && ! empty(
                $booking_type->location_type
            )
        ) {
            $locations[] =
                $booking_type->location_type;
        }

        $locations = array_map(
            'sanitize_key',
            $locations
        );

        return array_values(
            array_unique(
                array_filter( $locations )
            )
        );
    }

    /**
     * Format a Booking Type price for display.
     *
     * This is presentation only. Core lesson requests do not take payment.
     *
     * @param int $price_minor_units Price in minor currency units.
     *
     * @return string
     */
    private static function format_price(
        $price_minor_units
    ) {
        $price_minor_units =
            absint( $price_minor_units );

        if ( 0 === $price_minor_units ) {
            return __(
                'Free',
                'tutorhelper-bookings'
            );
        }

        $currency =
            TutorHelper_Currency::get_currency();

        $currency_details =
            TutorHelper_Currency::get_currency_details(
                $currency
            );

        $decimal_places =
            TutorHelper_Currency::get_decimal_places(
                $currency
            );

        $divisor = 10 ** $decimal_places;

        $amount = number_format_i18n(
            $price_minor_units / $divisor,
            $decimal_places
        );

        $symbol = isset(
            $currency_details['symbol']
        )
            ? sanitize_text_field(
                $currency_details['symbol']
            )
            : $currency;

        $position = isset(
            $currency_details['symbol_position']
        )
            ? sanitize_key(
                $currency_details[
                    'symbol_position'
                ]
            )
            : 'before';

        return 'after' === $position
            ? $amount . $symbol
            : $symbol . $amount;
    }

    /**
     * Return a readable location label.
     *
     * @param string $location Location identifier.
     *
     * @return string
     */
    private static function get_location_label(
        $location
    ) {
        $labels = array(
            'online' => __(
                'Online',
                'tutorhelper-bookings'
            ),

            'phone' => __(
                'Phone',
                'tutorhelper-bookings'
            ),

            'in_person' => __(
                'In person',
                'tutorhelper-bookings'
            ),

            'custom' => __(
                'Custom location',
                'tutorhelper-bookings'
            ),

            'other' => __(
                'Other',
                'tutorhelper-bookings'
            ),
        );

        $location = sanitize_key(
            $location
        );

        return isset( $labels[ $location ] )
            ? $labels[ $location ]
            : ucwords(
                str_replace(
                    '_',
                    ' ',
                    $location
                )
            );
    }


	/**
	 * Render a front-end booking notice.
	 *
	 * @param string $message Notice message.
	 * @param string $type    Notice type.
	 *
	 * @return string
	 */
	private static function render_notice(
		$message,
		$type = 'info',
		$action_url = '',
		$action_label = ''
	) {
		$action_html = '';

		if (
			$action_url
			&& $action_label
		) {
			$action_html =
				sprintf(
					'<p><a class="tutorhelper-student-booking-notice__action" href="%1$s">%2$s</a></p>',
					esc_url(
						$action_url
					),
					esc_html(
						$action_label
					)
				);
		}

		return sprintf(
			'<div class="tutorhelper-student-booking-notice tutorhelper-student-booking-notice--%1$s" role="status"><p>%2$s</p>%3$s</div>',
			esc_attr(
				sanitize_html_class(
					$type
				)
			),
			esc_html(
				$message
			),
			$action_html
		);
	}
}
