<?php

namespace SugarCalendarBookings\Calendar\Admin;

use SugarCalendarBookings\Appointments\Admin\AppointmentDetailsPage;
use SugarCalendarBookings\Appointments\AppointmentModel;
use SugarCalendarBookings\Payments\PaymentsHelpers;
use SugarCalendarBookings\Plugin;
use SugarCalendarBookings\Support\Ajax\AbstractController;
use SugarCalendarBookings\Support\Helpers\Date;
use SugarCalendarBookings\Support\Helpers\UI;
use SugarCalendarBookings\Payments\Admin\PaymentsDetailsPage;

/**
 * Calendar controller.
 *
 * @since 1.0.0
 */
class CalendarController extends AbstractController {

	/**
	 * Update screen options.
	 *
	 * @since 1.0.0
	 * @since 1.4.0 Use instance method get_calendar_filters_for_ajax().
	 *
	 * @return void
	 */
	public function update_screen_options() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( esc_html__( 'You are not allowed to modify calendar settings.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
		}

		$input_data = $this->get_input_data(
			[
				'mode'             => 'required|string|in:month,week,day,agenda',
				'hidden_columns'   => 'array',
				'hidden_columns.*' => 'string',
				'year'             => 'numeric',
				'month'            => 'numeric|min:1|max:12',
				'day'              => 'numeric|min:1|max:31',
			]
		);

		$options = [
			'hidden_columns' => [
				$input_data['mode'] => $input_data['hidden_columns'] ?? [],
			],
		];

		$screen_options = Plugin::get( CalendarScreenOptions::class );

		$screen_options->update( $options );

		$filters = $this->get_calendar_filters_for_ajax( $input_data );

		$query = Plugin::make( CalendarQuery::class, CalendarPage::get_url(), $filters );

		$view = null;

		// @todo: Refactor this to use array.
		switch ( $input_data['mode'] ) {
			case 'day':
				$view = Plugin::make( CalendarDayView::class, $query );
				break;

			case 'week':
				$view = Plugin::make( CalendarWeekView::class, $query );
				break;

			case 'agenda':
				$view = Plugin::make( CalendarAgendaView::class, $query );
				break;

			case 'month':
			default:
				$view = Plugin::make( CalendarMonthView::class, $query );
				break;
		}

		if ( ! $view ) {
			wp_send_json_error( esc_html__( 'Invalid view mode.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
		}

		ob_start();

		$view->output_styles();

		$calendar_styles = ob_get_clean();

		wp_send_json_success( $calendar_styles );
	}

	/**
	 * Get calendar query filters for AJAX (e.g. screen options). Uses current date when params not sent.
	 *
	 * @since 1.4.0
	 *
	 * @param array $input_data Validated input.
	 *
	 * @return array Filters for CalendarQuery.
	 */
	private function get_calendar_filters_for_ajax( array $input_data ) {

		$today = Date::create()->setTimezone( Date::get_default_timezone() );

		return [
			'mode'  => $input_data['mode'],
			'year'  => ! empty( $input_data['year'] ) ? (int) $input_data['year'] : (int) $today->format( 'Y' ),
			'month' => ! empty( $input_data['month'] ) ? (int) $input_data['month'] : (int) $today->format( 'n' ),
			'day'   => ! empty( $input_data['day'] ) ? (int) $input_data['day'] : (int) $today->format( 'j' ),
		];
	}

	/**
	 * Get appointment data.
	 *
	 * @since 1.0.0
	 * @since 1.2.1 Refactor appointment popover location.
	 *
	 * @return void
	 */
	public function get_appointment_popover() {

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( esc_html__( 'You are not allowed to view appointments.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
		}

		$input_data = $this->get_input_data(
			[
				'id' => 'required|id',
			]
		);

		$appointment = AppointmentModel::get( $input_data['id'] );

		if ( ! $appointment ) {
			wp_send_json_error( esc_html__( 'Appointment not found.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
		}

		$timezone      = Date::get_default_timezone();
		$timezone_abbr = $appointment->start_at->setTimezone( $timezone )->format( 'T' );

		ob_start();
		?>

		<div class="sugar-calendar-bookings-appointment-popover" data-sugar-calendar-bookings-appointment-popover>
			<div class="sugar-calendar-bookings-appointment-popover__body">
				<div class="sugar-calendar-bookings-appointment-popover__status-badge sugar-calendar-bookings-appointment-popover__status-badge--<?php echo esc_attr( $appointment->status ); ?>">
					<?php echo esc_html( $appointment->get_status_label() ); ?>
				</div>
				<dl class="sugar-calendar-bookings-appointment" style="--entry-color: <?php echo esc_attr( $appointment->service->color ); ?>;">
					<dt><?php echo esc_html( $appointment->service->name ); ?></dt>
					<dd class="sugar-calendar-bookings-appointment__duration">
					<?php
						echo esc_html(
							sprintf(
							/* translators: %1$s - appointment start time; %2$s - appointment end time; %3$s - timezone abbreviation. */
								__( '%1$s - %2$s (%3$s)', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
								Date::format_display_date( $appointment->start_at, 'h:i a' ),
								Date::format_display_date( $appointment->end_at, 'h:i a' ),
								$timezone_abbr
							)
						);
					?>
					</dd>

					<?php
				$location = $appointment->get_location();

				if ( $location ) {
					$this->get_appointment_popover_location( $location, $appointment );
				}
				?>

					<dd class="sugar-calendar-bookings-appointment__people">
						<span>
							<?php echo esc_html( $appointment->customer->name ); ?> (<?php echo esc_html__( 'Customer', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?>)
						</span>
						<span>
							<?php echo esc_html( $appointment->employee->name ); ?> (<?php echo esc_html__( 'Employee', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?>)
						</span>
					</dd>

					<?php
					$payment = PaymentsHelpers::get_payment( $appointment );

					if ( $payment ) :
						?>

						<dd class="sugar-calendar-bookings-appointment__payment sugar-calendar-bookings-appointment__payment--<?php echo esc_attr( $payment->status ); ?>">
							<span>
								<?php
								echo esc_html(
									sprintf(
									/* Translators: %1$s - payment status. */
										__( 'Payment %1$s', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
										$payment->get_status_label()
									)
								);
								?>
							</span>
						</dd>

					<?php endif; ?>
				</dl>
			</div>
			<div class="sugar-calendar-bookings-appointment-popover__footer">
				<ul class="sugar-calendar-bookings-appointment__actions">
					<li>
						<a href="<?php echo esc_url( AppointmentDetailsPage::get_url( $appointment->id ) ); ?>"><?php echo esc_html__( 'View', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?></a>
					</li>
					<li>
						<a href="#" data-edit data-appointment-id="<?php echo esc_attr( $appointment->id ); ?>"><?php echo esc_html__( 'Edit', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?></a>
					</li>
					<?php if ( $payment ) : ?>
						<li>
							<a href="<?php echo esc_url( PaymentsDetailsPage::get_url( $payment->id ) ); ?>"><?php echo esc_html__( 'Payment Details', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?></a>
						</li>
					<?php endif; ?>
				</ul>
			</div>
			<div class="sugar-calendar-bookings-appointment-popover__arrow"></div>
		</div>

		<?php
		$content = ob_get_clean();

		wp_send_json_success( $content );
	}

	/**
	 * Get appointment popover location.
	 *
	 * If text exceeds maximum length, provide title attribute.
	 * If location is online, provide a link to the location URL.
	 *
	 * @since 1.2.1
	 * @since 1.4.0 Accept appointment to resolve Zoom join URL.
	 *
	 * @param LocationModel    $location    Location model.
	 * @param AppointmentModel $appointment Appointment model.
	 *
	 * @return void
	 */
	public function get_appointment_popover_location( $location, $appointment ) {

		$display_name = $location->get_display_name();
		?>
		<dd
			class="sugar-calendar-bookings-appointment__location"
			<?php UI::maybe_render_title_attribute( $display_name ); ?>
		>
			<?php UI::render_appointment_location_for_display( $location, $appointment ); ?>
		</dd>
		<?php
	}
}
