<?php
/**
 * Booking tutor resolution service.
 *
 * @package TutorHelper_Bookings
 */

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

/**
 * Resolves the tutor responsible for a booking request.
 */
final class TutorHelper_Booking_Tutor_Resolver {

	/**
	 * Option storing the default Core tutor.
	 *
	 * @var string
	 */
	const OPTION_KEY =
		'tutorhelper_default_tutor_user_id';

	/**
	 * Resolve the tutor for one student booking request.
	 *
	 * Core currently supports one administrator tutor. Pro and SaaS may
	 * override this with student-to-tutor connection data.
	 *
	 * @param int $student_user_id Student user ID.
	 * @param int $booking_type_id Booking Type ID.
	 *
	 * @return int|WP_Error
	 */
	public static function resolve(
		$student_user_id,
		$booking_type_id = 0
	) {
		$student_user_id =
			absint( $student_user_id );

		$booking_type_id =
			absint( $booking_type_id );

		$tutor_user_id =
			absint(
				get_option(
					self::OPTION_KEY,
					0
				)
			);

		if ( ! $tutor_user_id ) {
			$tutor_user_id =
				self::get_fallback_administrator();
		}

		/**
		 * Filter the tutor assigned to a student booking request.
		 *
		 * Pro or SaaS may use this to resolve an accepted tutor-student
		 * connection instead of the Core default administrator.
		 *
		 * @param int $tutor_user_id   Resolved Core tutor ID.
		 * @param int $student_user_id Student user ID.
		 * @param int $booking_type_id Booking Type ID.
		 */
		$tutor_user_id =
			absint(
				apply_filters(
					'tutorhelper_booking_tutor_user_id',
					$tutor_user_id,
					$student_user_id,
					$booking_type_id
				)
			);

		if ( ! $tutor_user_id ) {
			return new WP_Error(
				'tutorhelper_booking_tutor_unavailable',
				__(
					'A booking tutor has not been configured for this site.',
					'tutorhelper-bookings'
				)
			);
		}

		$tutor = get_user_by(
			'id',
			$tutor_user_id
		);

		if ( ! $tutor instanceof WP_User ) {
			return new WP_Error(
				'tutorhelper_booking_tutor_not_found',
				__(
					'The assigned tutor account could not be found.',
					'tutorhelper-bookings'
				)
			);
		}
		if (
			! in_array(
				'administrator',
				(array) $tutor->roles,
				true
			)
		) {
			return new WP_Error(
				'tutorhelper_booking_tutor_invalid',
				__(
					'The configured booking tutor is not a valid TutorHelper administrator.',
					'tutorhelper-bookings'
				)
			);
		}

		return $tutor_user_id;
	}






	/**
	 * Return the administrator when Core has exactly one.
	 *
	 * Core must not guess between multiple administrator
	 * accounts because availability belongs to a specific
	 * WordPress user.
	 *
	 * @return int
	 */
	private static function get_fallback_administrator() {

		$administrators =
			get_users(
				array(
					'role' =>
						'administrator',

					'number' =>
						2,

					'orderby' =>
						'ID',

					'order' =>
						'ASC',

					'fields' =>
						'ids',
				)
			);

		if ( 1 !== count( $administrators ) ) {
			return 0;
		}

		return absint(
			$administrators[0]
		);
	}
}
