<?php
/**
 * Student single-lesson request service.
 *
 * @package TutorHelper_Bookings
 */

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

/**
 * Validates and creates one Core student lesson request.
 */
final class TutorHelper_Student_Booking_Request {

	/**
	 * Create one student lesson request.
	 *
	 * Expected data:
	 *
	 * - booking_type_id
	 * - booking_start
	 * - booking_end
	 * - timezone
	 * - location_type
	 * - location_details, optional
	 * - notes, optional
	 *
	 * @param array $data            Submitted request data.
	 * @param int   $student_user_id Student requesting the lesson.
	 *
	 * @return array|WP_Error
	 */
	public static function create(
		$data,
		$student_user_id
	) {
		$data = is_array( $data )
			? $data
			: array();

		$student_user_id =
			absint( $student_user_id );

		if ( ! $student_user_id ) {
			return new WP_Error(
				'tutorhelper_student_booking_login_required',
				__(
					'You must be logged in to request a lesson.',
					'tutorhelper-bookings'
				)
			);
		}

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

		if ( ! $student instanceof WP_User ) {
			return new WP_Error(
				'tutorhelper_student_booking_not_allowed',
				__(
					'Your account is not registered as a TutorHelper student.',
					'tutorhelper-bookings'
				)
			);
		}

		$booking_type_id = isset(
			$data['booking_type_id']
		)
			? absint(
				$data['booking_type_id']
			)
			: 0;

		if ( ! $booking_type_id ) {
			return new WP_Error(
				'tutorhelper_student_booking_type_missing',
				__(
					'Select a lesson type.',
					'tutorhelper-bookings'
				)
			);
		}

		$booking_type =
			TutorHelper_Booking_Types::get_by_id(
				$booking_type_id
			);

		if ( ! $booking_type ) {
			return new WP_Error(
				'tutorhelper_student_booking_type_not_found',
				__(
					'The selected lesson type could not be found.',
					'tutorhelper-bookings'
				)
			);
		}

		if (
			! TutorHelper_Student_Booking_Access::
				can_book(
					$booking_type,
					$student_user_id
				)
		) {
			return new WP_Error(
				'tutorhelper_student_booking_type_unavailable',
				__(
					'The selected lesson type is not available for your account.',
					'tutorhelper-bookings'
				)
			);
		}

		$booking_start = isset(
			$data['booking_start']
		)
			? sanitize_text_field(
				$data['booking_start']
			)
			: '';

		$booking_end = isset(
			$data['booking_end']
		)
			? sanitize_text_field(
				$data['booking_end']
			)
			: '';

		$timezone = isset(
			$data['timezone']
		)
			? sanitize_text_field(
				$data['timezone']
			)
			: wp_timezone()->getName();

		$location_type = isset(
			$data['location_type']
		)
			? sanitize_key(
				$data['location_type']
			)
			: '';

        $tutor_user_id =
            TutorHelper_Booking_Tutor_Resolver::
                resolve(
                    $student_user_id,
                    $booking_type_id
                );

        if ( is_wp_error( $tutor_user_id ) ) {
            return $tutor_user_id;
        }

		$evaluation =
			TutorHelper_Booking_Conditions::
				evaluate(
					array(
						'tutor_user_id' =>
							$tutor_user_id,

						'booking_type_id' =>
							$booking_type_id,

						'booking_start' =>
							$booking_start,

						'booking_end' =>
							$booking_end,

						'timezone' =>
							$timezone,

						'location_type' =>
							$location_type,

						'exclude_booking_id' =>
							0,
					)
				);

		if ( is_wp_error( $evaluation ) ) {
			return $evaluation;
		}

		/*
		 * Students cannot override public booking restrictions.
		 *
		 * Tutor-created bookings may treat several conditions as warnings,
		 * but a student request must use a fully advertised, available slot.
		 */
		$booking_date =
            substr(
                $booking_start,
                0,
                10
            );

        $available_slots =
            TutorHelper_Student_Booking_Slots::
                get_for_date(
                    $tutor_user_id,
                    $booking_type_id,
                    $booking_date
                );

        if ( is_wp_error( $available_slots ) ) {
            return $available_slots;
        }

        $matching_slot = null;

        foreach ( $available_slots as $available_slot ) {
            if (
                ! is_array( $available_slot )
                || empty( $available_slot['start'] )
                || empty( $available_slot['end'] )
            ) {
                continue;
            }

            if (
                $booking_start
                    === sanitize_text_field(
                        $available_slot['start']
                    )
                && $booking_end
                    === sanitize_text_field(
                        $available_slot['end']
                    )
                && $location_type
                    === sanitize_key(
                        $available_slot[
                            'location_type'
                        ]
                    )
            ) {
                $matching_slot =
                    $available_slot;

                break;
            }
        }

        if ( null === $matching_slot ) {
            return new WP_Error(
                'tutorhelper_student_booking_slot_unavailable',
                __(
                    'This lesson time is no longer available. Please choose another slot.',
                    'tutorhelper-bookings'
                )
            );
        }

		$booking_id =
			TutorHelper_Booking_Records::create(
				array(
					'booking_type_id' =>
						$booking_type_id,

					'student_user_id' =>
						$student_user_id,

					'tutor_user_id' =>
						$tutor_user_id,

					'booking_start' =>
						$booking_start,

					'booking_end' =>
						$booking_end,

					'timezone' =>
						$timezone,

					'location_type' =>
						$location_type,

					'location_details' =>
						isset(
							$data[
								'location_details'
							]
						)
							? sanitize_textarea_field(
								$data[
									'location_details'
								]
							)
							: '',

					'notes' =>
						isset( $data['notes'] )
							? sanitize_textarea_field(
								$data['notes']
							)
							: '',

					'source' =>
						TutorHelper_Booking_Records::
							SOURCE_STUDENT,

					'status' =>
						TutorHelper_Booking_Records::
							STATUS_UNCONFIRMED,

                    'skip_payment' =>
                            true,

					'payment_method' =>
						TutorHelper_Booking_Records::
							PAYMENT_METHOD_FREE,

					'payment_status' =>
						TutorHelper_Booking_Records::
							PAYMENT_STATUS_NOT_REQUIRED,
				)
			);

		if ( is_wp_error( $booking_id ) ) {
			return $booking_id;
		}

		$booking =
			TutorHelper_Booking_Records::get_by_id(
				$booking_id
			);

		if ( ! $booking ) {
			return new WP_Error(
				'tutorhelper_student_booking_record_missing',
				__(
					'Your lesson request was saved but could not be retrieved.',
					'tutorhelper-bookings'
				)
			);
		}

		TutorHelper_Logger::success(
			'Student lesson request created.',
			array(
				'booking_id' =>
					absint( $booking_id ),

				'student_user_id' =>
					$student_user_id,

				'tutor_user_id' =>
					$tutor_user_id,

				'booking_type_id' =>
					$booking_type_id,
			)
		);

		return array(
			'booking_id' =>
				absint( $booking_id ),

			'booking' =>
				$booking,

			'status' =>
				sanitize_key(
					$booking->status
				),

			'source' =>
				sanitize_key(
					$booking->source
				),

			'payment_method' =>
				sanitize_key(
					$booking
						->payment_method
				),

			'payment_status' =>
				sanitize_key(
					$booking
						->payment_status
				),
		);
	}
}
