<?php
namespace EM\Waitlist;

class Bookings_Admin {

	public static function init() {
		add_action( 'em_bookings_table', '\EM\Waitlist\Bookings_Admin::em_bookings_table', 10, 1 );
		add_action( 'em_admin_event_booking_availibility', '\EM\Waitlist\Bookings_Admin::em_admin_event_booking_availibility', 10, 1 );
		add_filter( 'em_bookings_table_booking_allowed_actions', '\EM\Waitlist\Bookings_Admin::bookings_table_allowed_actions', 10, 2 );
		// Register the waitlist-specific row actions (cancel, resend_email) so they actually render, wire up
		// their AJAX handlers, and supply the missing icon for resend_email. Without the action-data items the
		// core bookings table silently drops these actions, leaving waitlist rows with no cancel/resend. (#545)
		add_filter( 'em_bookings_table_get_action_data_items', '\EM\Waitlist\Bookings_Admin::em_bookings_table_get_action_data_items', 10, 3 );
		add_action( 'em_bookings_table_ajax_table_row_action', '\EM\Waitlist\Bookings_Admin::em_bookings_table_ajax_table_row_action', 10, 1 );
		add_action( 'admin_enqueue_scripts', '\EM\Waitlist\Bookings_Admin::admin_enqueue_scripts', 20 );

		add_action( 'em_admin_event_booking_before_availibility', '\EM\Waitlist\Bookings_Admin::em_admin_event_booking_before_availibility', 10, 2 );
		add_action( 'em_admin_event_booking_after_availibility', '\EM\Waitlist\Bookings_Admin::em_admin_event_booking_after_availibility', 10, 2 );

		add_action( 'em_bookings_table_cols_template', '\EM\Waitlist\Bookings_Admin::em_bookings_table_cols_template', 10, 1 );
		add_filter( 'em_bookings_table_rows_col_waitlist_expiry', '\EM\Waitlist\Bookings_Admin::em_bookings_table_rows_col_waitlist_expiry', 10, 3 );
		add_filter( 'em_bookings_table_rows_col_waitlist_position', '\EM\Waitlist\Bookings_Admin::em_bookings_table_rows_col_waitlist_position', 10, 3 );
	}

	public static function em_bookings_table( $EM_Bookings_Table ) {
		$EM_Bookings_Table->statuses['waitlist'] = array(
			'label'  => __( 'Waitlist', 'em-pro' ),
			'search' => array( 6, 7, 8 ),
		);
		$EM_Bookings_Table->status               = ! empty( $_REQUEST['status'] ) && $_REQUEST['status'] == 'waitlist' ? 'waitlist' : $EM_Bookings_Table->status;
	}

	/**
	 * @param array $actions
	 * @param \EM_Booking $EM_Booking
	 * @return string[]
	 */
	public static function bookings_table_allowed_actions( $actions, $EM_Booking ) {
		if ( $EM_Booking instanceof Booking ) {
			if ( $EM_Booking->booking_status == 6 ) {
				$actions = array( 'approve', 'cancel', 'delete', 'resend_email' );
			} elseif ( $EM_Booking->booking_status == 7 ) {
				$actions = array( 'cancel', 'delete', 'resend_email' );
			} elseif ( $EM_Booking->booking_status == 8 ) {
				$actions = array( 'approve', 'cancel', 'delete' );
			}
		}
		return $actions;
	}

	/**
	 * Registers the action-data for the waitlist-only row actions. The core bookings table only keeps actions
	 * that exist in this registry, so without these `cancel` and `resend_email` (added in bookings_table_allowed_actions)
	 * were dropped and never rendered. (#545)
	 *
	 * @param array $actions
	 * @param \EM_Bookings_Table $EM_Bookings_Table
	 * @param array $args
	 * @return array
	 */
	public static function em_bookings_table_get_action_data_items( $actions, $EM_Bookings_Table, $args ) {
		$data_template            = $args['data_template'];
		$actions['cancel']        = array(
			'label' => __( 'Cancel', 'em-pro' ),
			'data'  => array_merge( $data_template, array( 'row_action' => 'cancel' ) ),
		);
		$actions['resend_email']  = array(
			'label' => __( 'Resend email', 'em-pro' ),
			'data'  => array_merge( $data_template, array( 'row_action' => 'resend_email' ) ),
		);
		return $actions;
	}

	/**
	 * Handles the waitlist row actions that core doesn't know about, then re-renders the row so the table
	 * updates in place (same approach as the attendance add-on's check-in/out actions). The nonce is already
	 * verified by the core list-table AJAX handler before this fires. (#545)
	 *
	 * @param string $requested_action
	 * @return void
	 */
	public static function em_bookings_table_ajax_table_row_action( $requested_action ) {
		if ( $requested_action !== 'cancel' && $requested_action !== 'resend_email' ) {
			return;
		}
		$EM_Booking = ! empty( $_REQUEST['booking_id'] ) ? em_get_booking( $_REQUEST['booking_id'] ) : em_get_booking();
		if ( ! $EM_Booking || ! $EM_Booking->booking_id || ! $EM_Booking->can_manage( 'manage_bookings', 'manage_others_bookings' ) ) {
			return;
		}
		if ( $requested_action === 'cancel' ) {
			$EM_Booking->cancel();
		} else { // resend_email
			if ( $EM_Booking->email( false, true ) ) {
				$EM_Booking->feedback_message = $EM_Booking->mails_sent > 0
					? __( 'Email Sent.', 'events-manager' )
					: _x( 'No emails to send for this booking.', 'bookings', 'events-manager' );
			}
		}
		$EM_Bookings_Table = new \EM_Bookings_Table();
		$EM_Bookings_Table->single_row( $EM_Booking );
	}

	/**
	 * Supplies the action-column icon for the resend_email row action (cancel reuses core's cross-circle icon).
	 * Core has no icon for resend_email, so the link would otherwise render invisibly (text is hidden by a
	 * text-indent and there is no background image). Uses the @ icon as a stand-in for email. (#545)
	 *
	 * @return void
	 */
	public static function admin_enqueue_scripts() {
		wp_add_inline_style(
			'events-manager-admin',
			'td.column-actions a[data-row_action="resend_email"]{ background: var(--icon-at) no-repeat; background-size: 18px; }'
		);
	}

	public static function em_admin_event_booking_availibility( $EM_Event ) {
		$waiting_spaces          = Events::get_waiting_spaces( $EM_Event );
		$waiting_approved_spaces = Events::get_waiting_approved_spaces( $EM_Event );
		$style                   = 'text-decoration: underline 2px dotted #aaa; text-underline-offset: 4px;';
		if ( $waiting_spaces ) {
			echo ', <span class="em-tooltip" style="' . $style . '" aria-label="' . esc_html__( 'Number of spaces reserved when new spaces become available.', 'em-pro' ) . '">';
			echo esc_html__( 'Waitlist spaces', 'em-pro' ) . '</span>: ' . $waiting_spaces;
		}
		if ( $waiting_approved_spaces ) {
			echo ', <span class="em-tooltip" style="' . $style . '" aria-label="' . esc_html__( 'Number of spaces approved to make a booking from recently available spaces.', 'em-pro' ) . '">';
			echo esc_html__( 'Waitlist approved', 'em-pro' ) . '</span>: ' . $waiting_approved_spaces;
		}
	}

	public static function em_admin_event_booking_before_availibility( $EM_Event ) {
		Bookings::$ignore_waitlisted = true;
	}

	public static function em_admin_event_booking_after_availibility( $EM_Event ) {
		Bookings::$ignore_waitlisted = false;
	}

	/**
	 * Adds columns in the bookings tables
	 * @param array $template
	 * @return array
	 */
	public static function em_bookings_table_cols_template( $template ) {
		$template['waitlist_expiry']   = esc_html__( 'Waitlist Expiry', 'events-manager-pro' );
		$template['waitlist_position'] = esc_html__( 'Waitlist Position', 'events-manager-pro' );
		return $template;
	}

	/**
	 * @param string $val
	 * @param \EM_Booking $EM_Booking
	 */
	public static function em_bookings_table_rows_col_waitlist_expiry( $val, $EM_Booking ) {
		$val = '-';
		if ( $EM_Booking instanceof Booking ) {
			if ( $EM_Booking->booking_status == 7 ) {
				$EM_DateTime = new \EM_DateTime( $EM_Booking->booking_meta['waitlist_expiry'] );
				$val         = $EM_DateTime->formatDefault();
			} elseif ( $EM_Booking->booking_status == 8 ) {
				$EM_DateTime = new \EM_DateTime( $EM_Booking->booking_meta['waitlist_expired'] );
				$val         = '<span style="color:#bc8787">' . $EM_DateTime->formatDefault() . '</span>';
			} elseif ( $EM_Booking->booking_status == 3 && ! empty( $EM_Booking->booking_meta['waitlist_expiry'] ) ) { // assuming it expired at all before cancellation
				$EM_DateTime = new \EM_DateTime( $EM_Booking->booking_meta['waitlist_expiry'] );
				if ( $EM_Booking->is_expired() ) {
					$val = '<span style="color:#bc8787">' . $EM_DateTime->formatDefault() . '</span>';
				} else {
					$val = $EM_DateTime->formatDefault();
				}
			}
		}
		return $val;
	}

	/**
	 * @param string $val
	 * @param Booking $EM_Booking
	 */
	public static function em_bookings_table_rows_col_waitlist_position( $val, $EM_Booking ) {
		global $wpdb;
		$val = '-';
		if ( $EM_Booking instanceof Booking ) {
			if ( $EM_Booking->booking_status == 6 ) {
				$sql = $wpdb->prepare( 'SELECT COUNT(*) FROM ' . EM_BOOKINGS_TABLE . ' WHERE event_id=%d AND booking_status=6 AND booking_id <= %d', $EM_Booking->event_id, $EM_Booking->booking_id );
				$val = $wpdb->get_var( $sql );
			}
		}
		return $val;
	}
}
Bookings_Admin::init();
