<?php
/**
 * Handle frontend forms.
 *
 * @package WooCommerce Bookings
 */

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

/**
 * WC_Booking_Form_Handler class.
 *
 * Handles frontend booking forms.
 *
 * @version 3.5.0
 */
class WC_Booking_Form_Handler {

	/**
	 * Hook in methods
	 */
	public static function init() {
		add_action( 'init', array( __CLASS__, 'cancel_booking' ), 20 );
	}

	/**
	 * Cancel a booking.
	 */
	public static function cancel_booking() {
		if ( isset( $_GET['cancel_booking'] ) && isset( $_GET['booking_id'] ) ) {

			$booking_id         = absint( $_GET['booking_id'] );
			$booking            = get_wc_booking( $booking_id );

			if ( ! $booking ) {
				wc_add_notice( __( 'Invalid booking.', 'woocommerce-bookings' ), 'error' );
				return;
			}

			$booking_can_cancel = $booking->has_status( get_wc_booking_statuses( 'cancel' ) );
			$redirect           = esc_url_raw( wp_unslash( $_GET['redirect'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated

			if ( $booking->get_customer_id() !== get_current_user_id() ) {
				wc_add_notice( __( 'Invalid booking.', 'woocommerce-bookings' ), 'error' );
			} elseif ( $booking->has_status( 'cancelled' ) ) {
				// Already cancelled - take no action
			} elseif ( $booking_can_cancel && $booking->get_id() == $booking_id && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( sanitize_key( wp_unslash( $_GET['_wpnonce'] ) ), "woocommerce-bookings-cancel_booking_{$booking->get_id()}" ) ) {
				// Cancel the booking
				$booking->update_status( 'cancelled' );
				WC_Cache_Helper::get_transient_version( 'bookings', true );

				/**
				 * Filters the notice shown to the user when a booking is cancelled.
				 *
				 * @since 1.5.1
				 * @param string     $notice  The notice text.
				 * @param WC_Booking $booking The booking that was cancelled.
				 * @return string
				*/
				$notice = apply_filters( 'woocommerce_booking_cancelled_notice', __( 'Your booking was cancelled.', 'woocommerce-bookings' ), $booking );

				/**
				 * Filters the notice type shown to the user when a booking is cancelled.
				 *
				 * @since 1.5.1
				 * @param string     $notice_type The notice type (e.g. 'success', 'error', 'notice').
				 * @param WC_Booking $booking     The booking that was cancelled.
				 * @return string
				*/
				$notice_type = apply_filters( 'woocommerce_booking_cancelled_notice_type', 'success', $booking );

				// Message.
				wc_add_notice( $notice, $notice_type );

				do_action( 'woocommerce_bookings_cancelled_booking', $booking->get_id() );
			} elseif ( ! $booking_can_cancel ) {
				wc_add_notice( __( 'Your booking can no longer be cancelled. Please contact us if you need assistance.', 'woocommerce-bookings' ), 'error' );
			} else {
				wc_add_notice( __( 'Invalid booking.', 'woocommerce-bookings' ), 'error' );
			}

			if ( $redirect ) {
				wp_safe_redirect( $redirect );
				exit;
			}
		}
	}
}

