<?php

namespace SugarCalendarBookings\Appointments;

use Exception;
use SugarCalendarBookings\Services\ServiceModel;
use SugarCalendarBookings\Employees\EmployeeModel;
use SugarCalendarBookings\Locations\AbstractLocation;

/**
 * Booking validation service.
 *
 * @since 1.0.0
 */
class AppointmentValidationService {

	/**
	 * Validate a booking.
	 *
	 * @since 1.0.0
	 *
	 * @param ServiceModel     $service  The service.
	 * @param AbstractLocation $location The location.
	 * @param EmployeeModel    $employee The employee.
	 *
	 * @throws Exception If the booking is not valid.
	 */
	public function validate_relations( $service, $location, $employee ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh

		if ( $service->status !== 'enabled' ) {
			throw new Exception( esc_html__( 'Service is not available.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
		}

		if ( $location->get_type() === 'in_person' ) {
			if ( $location->get_model()->status !== 'enabled' ) {
				throw new Exception( esc_html__( 'Location is not available.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
			}

			if ( ! $service->locations()->where( 'id', '=', $location->get_id(), '%d' )->get() ) {
				throw new Exception( esc_html__( 'Location is not available for the selected service.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
			}
		} elseif ( $location->get_type() === 'online' ) {
			if ( $location->get_service_id() !== $service->id ) {
				throw new Exception( esc_html__( 'Location is not available for the selected service.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
			}
		}

		if ( $employee->status !== 'enabled' ) {
			throw new Exception( esc_html__( 'Employee is not available.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
		}

		if ( ! $service->employees()->where( 'id', '=', $employee->id, '%d' )->get() ) {
			throw new Exception( esc_html__( 'Service is not available with the selected employee.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
		}

		// TODO: Check if employee is available at this location when we'll add employee <-> location relation. For now all employees are available at all locations.
	}
}
