<?php

namespace SugarCalendarBookings\Calendar\Admin;

use SugarCalendarBookings\Plugin;
use SugarCalendarBookings\Support\Admin\AbstractPage;
use SugarCalendarBookings\Support\DataProcessing\InputProcessor;
use SugarCalendarBookings\Support\Helpers\UI;
use SugarCalendarBookings\Calendar\Admin\CalendarAgendaView;

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

/**
 * Calendar page.
 *
 * @since 1.0.0
 */
class CalendarPage extends AbstractPage {

	/**
	 * Current view.
	 *
	 * @since 1.0.0
	 *
	 * @var AbstractCalendarView
	 */
	private $view;

	/**
	 * Page title.
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public static function get_title() {

		return esc_html__( 'Calendar', 'sugar-calendar-bookings-scheduling-appointments-lite' );
	}

	/**
	 * Page slug.
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public static function get_slug() {

		return 'calendar';
	}

	/**
	 * Register page hooks.
	 *
	 * @since 1.0.0
	 */
	public function hooks() {

		add_action( 'admin_init', [ $this, 'init_view' ] );
		add_action( 'sugar_calendar_bookings_admin_page_subheader_actions_left', [ $this, 'subheader_actions_left' ] );
		add_action( 'sugar_calendar_bookings_admin_page_subheader_actions_right', [ $this, 'subheader_actions_right' ] );
		add_action( 'sugar_calendar_bookings_admin_area_enqueue_assets_before', [ $this, 'enqueue_lib_assets' ] );
	}

	/**
	 * Enqueue lib assets.
	 *
	 * @since 1.1.0
	 */
	public function enqueue_lib_assets() {

		// Required for Service feature image (when creating service from appointment form).
		wp_enqueue_media();

		// Required for WYSIWYG editor (when creating service from appointment form).
		wp_enqueue_editor();
	}

	/**
	 * Get validation rules.
	 *
	 * @since 1.0.0
	 * @since 1.3.0 Made protected.
	 *
	 * @return string[]
	 */
	protected function get_validation_rules() {

		$months = implode( ',', range( 1, 12 ) );
		$days   = implode( ',', range( 1, 31 ) );

		return [
			'mode'            => 'string|in:month,week,day,agenda',
			'status'          => 'string|in:approved,pending,cancelled,done',
			'search'          => 'string|trim',
			'year'            => 'numeric',
			'month'           => "numeric|in:$months",
			'day'             => "numeric|in:$days",
			'service_id'      => 'string',
			'add-appointment' => 'string|in:1',
		];
	}

	/**
	 * Initialize the calendar view based on request parameters.
	 *
	 * @since 1.0.0
	 * @since 1.3.0 Refactor to use view mode from screen options.
	 *
	 * @return void
	 */
	public function init_view() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh

		$rules     = $this->get_validation_rules();
		$sanitized = InputProcessor::process( wp_unslash( $_REQUEST ), $rules ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		if ( is_wp_error( $sanitized ) ) {
			wp_die( esc_html( $sanitized->get_error_message() ) );
		}

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

		if ( empty( $sanitized['mode'] ) ) {
			$sanitized['mode'] = $screen_options->get_view_mode();
		} else {
			$screen_options->set_view_mode( $sanitized['mode'] );
		}

		// Current query.
		$query = Plugin::make( CalendarQuery::class, self::get_url(), $sanitized );

		switch ( $sanitized['mode'] ) {
			case 'day':
				$this->view = Plugin::make( CalendarDayView::class, $query );
				break;

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

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

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

	/**
	 * Subheader left controls.
	 *
	 * @since 1.0.0
	 *
	 * @param AbstractPage $page The page instance.
	 */
	public function subheader_actions_left( $page ) {

		UI::button(
			[
				'link'  => '#',
				'size'  => 'sm',
				'class' => 'sugar-calendar-bookings-btn-new-item',
				'text'  => esc_html__( 'Add Appointment', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);
	}

	/**
	 * Subheader right controls.
	 *
	 * @since 1.0.0
	 *
	 * @param AbstractPage $page The page instance.
	 */
	public function subheader_actions_right( $page ) {

		UI::calendar_modes(
			[
				'base_url' => static::get_url(),
				'mode'     => $this->view->get_mode(),
			]
		);

		UI::calendar_view_options(
			[
				'mode'           => $this->view->get_mode(),
				'columns'        => $this->view->get_column_options(),
				'screen_options' => Plugin::get( CalendarScreenOptions::class )->get(),
			]
		);
	}

	/**
	 * Display page.
	 *
	 * @since 1.0.0
	 */
	public function display_content() {

		$this->view->display();
		?>

		<div id="sugar-calendar-bookings-sidebar"></div>

		<?php
	}

	/**
	 * Get script data for the calendar page.
	 *
	 * @since 1.2.0
	 *
	 * @return array
	 */
	public function get_script_data() {

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$auto_open_sidebar = isset( $_GET['add-appointment'] ) && sanitize_text_field( wp_unslash( $_GET['add-appointment'] ) ) === '1';

		return [
			'autoOpenSidebar' => $auto_open_sidebar,
		];
	}
}
