<?php

namespace SugarCalendarBookings\Admin\Settings;

use SugarCalendarBookings\Options;
use SugarCalendarBookings\Plugin;
use SugarCalendarBookings\Support\Admin\AbstractTabPage;
use SugarCalendarBookings\Support\Admin\Notices;
use SugarCalendarBookings\Support\Data\DateTime;
use SugarCalendarBookings\Support\Helpers\Date;
use SugarCalendarBookings\Support\Helpers\UI;

/**
 * General Settings tab.
 *
 * @since 1.0.0
 */
class GeneralSettingsTab extends AbstractTabPage {

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

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

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

		return 'settings';
	}

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

		return 'general';
	}

	/**
	 * Priority in menu position.
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public static function get_priority() {

		return 10;
	}

	/**
	 * Get appointment statuses.
	 *
	 * @since 1.0.0
	 *
	 * @return array
	 */
	private function get_appointment_statuses() {

		return [
			'approved' => __( 'Approved', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			'pending'  => __( 'Pending', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
		];
	}

	/**
	 * Display page.
	 *
	 * @since 1.0.0
	 * @since 1.5.0 Added Services Booking Page Slug field.
	 */
	public function display_content() {

		ob_start();

		$options = Plugin::get( Options::class );

		// Display heading.
		UI::heading(
			[
				'title' => esc_html__( 'Display', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);

		// Start of the week.
		UI::select_input(
			[
				'id'          => 'display_start_of_week',
				'name'        => [ 'display', 'start_of_week' ],
				'options'     => DateTime::get_week_days(),
				'value'       => $options->get( 'display.start_of_week' ),
				'label'       => esc_html__( 'Start of Week', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description' => esc_html__( 'Select the first day of the week.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);

		// Date format.
		UI::date_time_format_control(
			[
				'id'      => 'display_date_format',
				'name'    => [ 'display', 'date_format' ],
				'formats' => DateTime::get_date_formats(),
				'value'   => $options->get( 'display.date_format' ),
				'label'   => esc_html__( 'Date Format', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);

		// Time format.
		UI::date_time_format_control(
			[
				'id'      => 'display_time_format',
				'name'    => [ 'display', 'time_format' ],
				'formats' => DateTime::get_time_formats(),
				'value'   => $options->get( 'display.time_format' ),
				'label'   => esc_html__( 'Time Format', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);

		// Time Zone heading.
		UI::heading(
			[
				'title' => esc_html__( 'Time Zone', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);

		// Timezone.
		$this->display_timezone_field( $options );

		// Customer settings heading.
		UI::heading(
			[
				'title' => esc_html__( 'Customer Settings', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);

		// Default appointment status.
		UI::select_input(
			[
				'id'          => 'appointments_default_status',
				'name'        => [ 'appointments', 'default_status' ],
				'options'     => $this->get_appointment_statuses(),
				'value'       => $options->get( 'appointments.default_status' ),
				'label'       => esc_html__( 'Default Appointment Status', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description' => esc_html__( 'This will control the default appointment status applied to new bookings.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);

		// Minimum advance booking.
		UI::toggle_group(
			[
				'id'          => 'appointments_advance_minimum',
				'name'        => [ 'appointments', 'advance_minimum' ],
				'value'       => $options->get( 'appointments.advance_minimum' ),
				'label'       => esc_html__( 'Minimum Advance Booking', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description' => __( 'Prevent last-minute bookings by setting a minimum notice period. Example: 1 day means no same-day appointments.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			],
			function () use ( $options ) {

				UI::number_input(
					[
						'id'           => 'appointments_advance_minimum_days',
						'name'         => [ 'appointments', 'advance_minimum_days' ],
						'value'        => $options->get( 'appointments.advance_minimum_days' ),
						'placeholder'  => 1,
						'inline_label' => esc_html__( 'Days', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
					]
				);
			}
		);

		// Maximum advance booking.
		UI::toggle_group(
			[
				'id'          => 'appointments_advance_maximum',
				'name'        => [ 'appointments', 'advance_maximum' ],
				'value'       => $options->get( 'appointments.advance_maximum' ),
				'label'       => esc_html__( 'Maximum Advance Booking', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description' => __( 'Limit how far ahead customers can book. Example: 30 days means customers can schedule up to 1 month in advance.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			],
			function () use ( $options ) {

				UI::number_input(
					[
						'id'           => 'appointments_advance_maximum_days',
						'name'         => [ 'appointments', 'advance_maximum_days' ],
						'value'        => $options->get( 'appointments.advance_maximum_days' ),
						'placeholder'  => 1,
						'inline_label' => esc_html__( 'Days', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
					]
				);
			}
		);

		// Services booking page slug.
		$this->render_services_page_slug_setting( $options );

		UI::form_wrapper( ob_get_clean() );
	}

	/**
	 * Get post data processing rules.
	 *
	 * @since 1.0.0
	 *
	 * @return array
	 */
	public function get_post_data_processing_rules() {

		$appointment_statuses = implode( ',', array_keys( $this->get_appointment_statuses() ) );

		return [
			'display.timezone'                  => 'string', // Additional semantic validation in handle_post().
			'display.start_of_week'             => 'required|numeric|min:0,max:6',
			'display.date_format'               => 'required|string',
			'display.time_format'               => 'required|string',
			'appointments.default_status'       => "required|string|in:$appointment_statuses",
			'appointments.advance_minimum'      => 'required|form_boolean',
			'appointments.advance_minimum_days' => 'numeric',
			'appointments.advance_maximum'      => 'required|form_boolean',
			'appointments.advance_maximum_days' => 'numeric',
		];
	}

	/**
	 * Handle POST requests.
	 *
	 * @since 1.0.0
	 *
	 * @param array $post_data Post data.
	 */
	public function handle_post( $post_data = [] ) {

		// Validate timezone before saving.
		if ( ! empty( $post_data['display']['timezone'] ) && ! Date::is_valid_timezone( $post_data['display']['timezone'] ) ) {
			Plugin::get( Notices::class )->error(
				esc_html__( 'Invalid timezone.', 'sugar-calendar-bookings-scheduling-appointments-lite' )
			);

			return;
		}

		Plugin::get( Options::class )->update( $post_data );

		// Reset cached timezone so the current-time display reflects the new value.
		Date::reset_timezone_cache();

		Plugin::get( Notices::class )->success( esc_html__( 'Settings successfully saved.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
	}

	/**
	 * Display timezone field.
	 *
	 * Uses UI::timezone_select() for a searchable Choices.js-powered timezone dropdown.
	 * Appends the current time display via the description argument.
	 *
	 * @since 1.3.1
	 *
	 * @param Options $options Options instance.
	 */
	private function display_timezone_field( $options ) {

		$timezone = $options->get( 'display.timezone' );

		$description = esc_html__(
			'Select a city in your timezone for scheduling appointments.',
			'sugar-calendar-bookings-scheduling-appointments-lite'
		);

		$current_time = sprintf(
			'<p class="sugar-calendar-bookings-current-time">%s <span class="sugar-calendar-bookings-badge sugar-calendar-bookings-badge--inline">%s</span></p>',
			esc_html__( 'Current time:', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			esc_html( wp_date( $options->get( 'display.time_format' ) . ', ' . $options->get( 'display.date_format' ), null, Date::get_default_timezone() ) )
		);

		UI::timezone_select(
			[
				'id'                => 'display-timezone',
				'name'              => [ 'display', 'timezone' ],
				'value'             => $timezone,
				'label'             => esc_html__( 'Appointment Time Zone', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description'       => $description,
				'after_description' => $current_time,
			]
		);
	}

	/**
	 * Render the "Services Booking Page Slug" setting row.
	 *
	 * Lite renders a Pro-education row. Pro overrides this method to render
	 * the actual text input.
	 *
	 * @since 1.5.0
	 *
	 * @param Options $options Plugin options reader.
	 *
	 * @return void
	 */
	protected function render_services_page_slug_setting( Options $options ): void {

		UI::pro_education_row(
			[
				'label'       => __( 'Services Booking Page<br>Slug', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				/* translators: %1$s - upgrade to Pro link. */
				'description' => __( '<a href="%1$s" target="_blank" rel="noopener noreferrer">Upgrade to Pro</a> to publish public booking pages for each service with a customizable URL base.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'utm_content' => 'Services Booking Page Slug',
				'utm_medium'  => 'settings-general',
			]
		);
	}
}
