<?php

/**
 * Trial Booking Public Class
 *
 * Handles the frontend trial booking form and page
 *
 * @package    Karate_Club_Manager
 * @subpackage Karate_Club_Manager/includes/public
 * @since      1.0.61
 */
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
/**
 * Trial Booking Class
 *
 * @since 1.0.61
 */
class MACM_Trial_Booking {
    /**
     * Page ID for trial booking page
     *
     * @var int
     */
    private $page_id;

    /**
     * Get filtered bookings list with sorting.
     *
     * Uses completely literal SQL queries for WordPress.org compliance.
     * No dynamic SQL string building - each filter/order combination has its own query.
     *
     * @since 1.0.210
     * @param string $status   Filter by status (pending, completed, or empty for all).
     * @param int    $class_id Filter by class ID (0 for all).
     * @param string $search   Search term for name/email/mobile.
     * @param string $orderby  Column to order by (created_at, full_name, class_name).
     * @param bool   $is_asc   True for ASC, false for DESC.
     * @return array Array of booking objects.
     */
    public static function get_filtered_bookings(
        $status = '',
        $class_id = 0,
        $search = '',
        $orderby = 'created_at',
        $is_asc = false
    ) {
        global $wpdb;
        $t1 = $wpdb->prefix . 'macm_trial_bookings';
        $t2 = $wpdb->prefix . 'macm_classes';
        // Determine active filters.
        $has_status = !empty( $status ) && in_array( $status, array(
            'pending',
            'completed',
            'confirmed',
            'cancelled'
        ), true );
        $has_class = !empty( $class_id );
        $has_search = !empty( $search );
        // Validate orderby.
        if ( !in_array( $orderby, array('created_at', 'full_name', 'class_name'), true ) ) {
            $orderby = 'created_at';
        }
        // Build filter key: s=status, c=class, q=search.
        $filter_key = (( $has_status ? 's' : '' )) . (( $has_class ? 'c' : '' )) . (( $has_search ? 'q' : '' ));
        $order_key = $orderby . (( $is_asc ? '_asc' : '_desc' ));
        // Prepare search term if needed.
        $search_term = ( $has_search ? '%' . $wpdb->esc_like( $search ) . '%' : '' );
        // Dispatch to literal query based on filter and order combination.
        return self::execute_booking_query(
            $filter_key,
            $order_key,
            $t1,
            $t2,
            $status,
            $class_id,
            $search_term
        );
    }

    /**
     * Execute booking query with literal SQL.
     *
     * Each combination has a completely literal query string for PHPCS compliance.
     *
     * @since 1.0.210
     * @param string $filter_key  Filter combination key (empty, s, c, q, sc, sq, cq, scq).
     * @param string $order_key   Order key (created_at_asc, created_at_desc, etc.).
     * @param string $t1          Bookings table name.
     * @param string $t2          Classes table name.
     * @param string $status      Status filter value.
     * @param int    $class_id    Class ID filter value.
     * @param string $search_term Prepared search term with wildcards.
     * @return array Query results.
     */
    private static function execute_booking_query(
        $filter_key,
        $order_key,
        $t1,
        $t2,
        $status,
        $class_id,
        $search_term
    ) {
        global $wpdb;
        // No filters.
        if ( '' === $filter_key ) {
            return self::query_no_filter( $order_key, $t1, $t2 );
        }
        // Single filters.
        if ( 's' === $filter_key ) {
            return self::query_status_only(
                $order_key,
                $t1,
                $t2,
                $status
            );
        }
        if ( 'c' === $filter_key ) {
            return self::query_class_only(
                $order_key,
                $t1,
                $t2,
                $class_id
            );
        }
        if ( 'q' === $filter_key ) {
            return self::query_search_only(
                $order_key,
                $t1,
                $t2,
                $search_term
            );
        }
        // Two filters.
        if ( 'sc' === $filter_key ) {
            return self::query_status_class(
                $order_key,
                $t1,
                $t2,
                $status,
                $class_id
            );
        }
        if ( 'sq' === $filter_key ) {
            return self::query_status_search(
                $order_key,
                $t1,
                $t2,
                $status,
                $search_term
            );
        }
        if ( 'cq' === $filter_key ) {
            return self::query_class_search(
                $order_key,
                $t1,
                $t2,
                $class_id,
                $search_term
            );
        }
        // All three filters.
        if ( 'scq' === $filter_key ) {
            return self::query_all_filters(
                $order_key,
                $t1,
                $t2,
                $status,
                $class_id,
                $search_term
            );
        }
        return array();
    }

    /**
     * Query with no filters.
     *
     * @param string $order_key Order key.
     * @param string $t1        Bookings table.
     * @param string $t2        Classes table.
     * @return array Results.
     */
    private static function query_no_filter( $order_key, $t1, $t2 ) {
        global $wpdb;
        switch ( $order_key ) {
            case 'created_at_asc':
                return $wpdb->get_results( $wpdb->prepare( 'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id ORDER BY b.created_at ASC', $t1, $t2 ) );
            case 'created_at_desc':
                return $wpdb->get_results( $wpdb->prepare( 'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id ORDER BY b.created_at DESC', $t1, $t2 ) );
            case 'full_name_asc':
                return $wpdb->get_results( $wpdb->prepare( 'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id ORDER BY b.full_name ASC', $t1, $t2 ) );
            case 'full_name_desc':
                return $wpdb->get_results( $wpdb->prepare( 'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id ORDER BY b.full_name DESC', $t1, $t2 ) );
            case 'class_name_asc':
                return $wpdb->get_results( $wpdb->prepare( 'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id ORDER BY c.class_name ASC', $t1, $t2 ) );
            case 'class_name_desc':
                return $wpdb->get_results( $wpdb->prepare( 'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id ORDER BY c.class_name DESC', $t1, $t2 ) );
            default:
                return $wpdb->get_results( $wpdb->prepare( 'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id ORDER BY b.created_at DESC', $t1, $t2 ) );
        }
    }

    /**
     * Query with status filter only.
     *
     * @param string $order_key Order key.
     * @param string $t1        Bookings table.
     * @param string $t2        Classes table.
     * @param string $status    Status value.
     * @return array Results.
     */
    private static function query_status_only(
        $order_key,
        $t1,
        $t2,
        $status
    ) {
        global $wpdb;
        switch ( $order_key ) {
            case 'created_at_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s ORDER BY b.created_at ASC',
                    $t1,
                    $t2,
                    $status
                ) );
            case 'created_at_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $status
                ) );
            case 'full_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s ORDER BY b.full_name ASC',
                    $t1,
                    $t2,
                    $status
                ) );
            case 'full_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s ORDER BY b.full_name DESC',
                    $t1,
                    $t2,
                    $status
                ) );
            case 'class_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s ORDER BY c.class_name ASC',
                    $t1,
                    $t2,
                    $status
                ) );
            case 'class_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s ORDER BY c.class_name DESC',
                    $t1,
                    $t2,
                    $status
                ) );
            default:
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $status
                ) );
        }
    }

    /**
     * Query with class filter only.
     *
     * @param string $order_key Order key.
     * @param string $t1        Bookings table.
     * @param string $t2        Classes table.
     * @param int    $class_id  Class ID.
     * @return array Results.
     */
    private static function query_class_only(
        $order_key,
        $t1,
        $t2,
        $class_id
    ) {
        global $wpdb;
        switch ( $order_key ) {
            case 'created_at_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d ORDER BY b.created_at ASC',
                    $t1,
                    $t2,
                    $class_id
                ) );
            case 'created_at_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $class_id
                ) );
            case 'full_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d ORDER BY b.full_name ASC',
                    $t1,
                    $t2,
                    $class_id
                ) );
            case 'full_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d ORDER BY b.full_name DESC',
                    $t1,
                    $t2,
                    $class_id
                ) );
            case 'class_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d ORDER BY c.class_name ASC',
                    $t1,
                    $t2,
                    $class_id
                ) );
            case 'class_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d ORDER BY c.class_name DESC',
                    $t1,
                    $t2,
                    $class_id
                ) );
            default:
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $class_id
                ) );
        }
    }

    /**
     * Query with search filter only.
     *
     * @param string $order_key   Order key.
     * @param string $t1          Bookings table.
     * @param string $t2          Classes table.
     * @param string $search_term Search term with wildcards.
     * @return array Results.
     */
    private static function query_search_only(
        $order_key,
        $t1,
        $t2,
        $search_term
    ) {
        global $wpdb;
        switch ( $order_key ) {
            case 'created_at_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at ASC',
                    $t1,
                    $t2,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'created_at_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'full_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.full_name ASC',
                    $t1,
                    $t2,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'full_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.full_name DESC',
                    $t1,
                    $t2,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'class_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY c.class_name ASC',
                    $t1,
                    $t2,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'class_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY c.class_name DESC',
                    $t1,
                    $t2,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            default:
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
        }
    }

    /**
     * Query with status and class filters.
     *
     * @param string $order_key Order key.
     * @param string $t1        Bookings table.
     * @param string $t2        Classes table.
     * @param string $status    Status value.
     * @param int    $class_id  Class ID.
     * @return array Results.
     */
    private static function query_status_class(
        $order_key,
        $t1,
        $t2,
        $status,
        $class_id
    ) {
        global $wpdb;
        switch ( $order_key ) {
            case 'created_at_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d ORDER BY b.created_at ASC',
                    $t1,
                    $t2,
                    $status,
                    $class_id
                ) );
            case 'created_at_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $status,
                    $class_id
                ) );
            case 'full_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d ORDER BY b.full_name ASC',
                    $t1,
                    $t2,
                    $status,
                    $class_id
                ) );
            case 'full_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d ORDER BY b.full_name DESC',
                    $t1,
                    $t2,
                    $status,
                    $class_id
                ) );
            case 'class_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d ORDER BY c.class_name ASC',
                    $t1,
                    $t2,
                    $status,
                    $class_id
                ) );
            case 'class_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d ORDER BY c.class_name DESC',
                    $t1,
                    $t2,
                    $status,
                    $class_id
                ) );
            default:
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $status,
                    $class_id
                ) );
        }
    }

    /**
     * Query with status and search filters.
     *
     * @param string $order_key   Order key.
     * @param string $t1          Bookings table.
     * @param string $t2          Classes table.
     * @param string $status      Status value.
     * @param string $search_term Search term with wildcards.
     * @return array Results.
     */
    private static function query_status_search(
        $order_key,
        $t1,
        $t2,
        $status,
        $search_term
    ) {
        global $wpdb;
        switch ( $order_key ) {
            case 'created_at_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at ASC',
                    $t1,
                    $t2,
                    $status,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'created_at_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $status,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'full_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.full_name ASC',
                    $t1,
                    $t2,
                    $status,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'full_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.full_name DESC',
                    $t1,
                    $t2,
                    $status,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'class_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY c.class_name ASC',
                    $t1,
                    $t2,
                    $status,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'class_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY c.class_name DESC',
                    $t1,
                    $t2,
                    $status,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            default:
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $status,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
        }
    }

    /**
     * Query with class and search filters.
     *
     * @param string $order_key   Order key.
     * @param string $t1          Bookings table.
     * @param string $t2          Classes table.
     * @param int    $class_id    Class ID.
     * @param string $search_term Search term with wildcards.
     * @return array Results.
     */
    private static function query_class_search(
        $order_key,
        $t1,
        $t2,
        $class_id,
        $search_term
    ) {
        global $wpdb;
        switch ( $order_key ) {
            case 'created_at_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at ASC',
                    $t1,
                    $t2,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'created_at_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'full_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.full_name ASC',
                    $t1,
                    $t2,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'full_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.full_name DESC',
                    $t1,
                    $t2,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'class_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY c.class_name ASC',
                    $t1,
                    $t2,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'class_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY c.class_name DESC',
                    $t1,
                    $t2,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            default:
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
        }
    }

    /**
     * Query with all three filters (status, class, search).
     *
     * @param string $order_key   Order key.
     * @param string $t1          Bookings table.
     * @param string $t2          Classes table.
     * @param string $status      Status value.
     * @param int    $class_id    Class ID.
     * @param string $search_term Search term with wildcards.
     * @return array Results.
     */
    private static function query_all_filters(
        $order_key,
        $t1,
        $t2,
        $status,
        $class_id,
        $search_term
    ) {
        global $wpdb;
        switch ( $order_key ) {
            case 'created_at_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at ASC',
                    $t1,
                    $t2,
                    $status,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'created_at_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $status,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'full_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.full_name ASC',
                    $t1,
                    $t2,
                    $status,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'full_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.full_name DESC',
                    $t1,
                    $t2,
                    $status,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'class_name_asc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY c.class_name ASC',
                    $t1,
                    $t2,
                    $status,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            case 'class_name_desc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY c.class_name DESC',
                    $t1,
                    $t2,
                    $status,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
            default:
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d AND (b.full_name LIKE %s OR b.email LIKE %s OR b.mobile LIKE %s) ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $status,
                    $class_id,
                    $search_term,
                    $search_term,
                    $search_term
                ) );
        }
    }

    /**
     * Get active classes for dropdown.
     *
     * @since 1.0.209
     * @return array Array of class objects with id and class_name.
     */
    public static function get_active_classes_for_dropdown() {
        global $wpdb;
        $macm_classes_table = $wpdb->prefix . 'macm_classes';
        return $wpdb->get_results( $wpdb->prepare( 'SELECT id, class_name FROM %i WHERE is_archived = 0 ORDER BY class_name', $macm_classes_table ) );
    }

    /**
     * Initialize the class.
     *
     * @since 1.0.61
     */
    public function __construct() {
        add_action( 'init', array($this, 'create_trial_booking_page') );
        add_shortcode( 'macm_trial_booking', array($this, 'render_booking_form') );
        add_shortcode( 'macm_trial_booking_form', array($this, 'render_booking_form') );
        // Alias for compatibility.
        add_action( 'wp_enqueue_scripts', array($this, 'enqueue_scripts') );
        add_action( 'wp_ajax_macm_submit_trial_booking', array($this, 'handle_booking_submission') );
        add_action( 'wp_ajax_nopriv_macm_submit_trial_booking', array($this, 'handle_booking_submission') );
    }

    /**
     * Create trial booking page on activation.
     *
     * @since 1.0.61
     */
    public function create_trial_booking_page() {
        // Check if page already exists.
        $page = get_page_by_path( 'book-trial-class' );
        if ( !$page ) {
            $page_id = wp_insert_post( array(
                'post_title'   => __( 'Book a Trial Class', 'martial-arts-club-manager' ),
                'post_content' => '[macm_trial_booking]',
                'post_status'  => 'publish',
                'post_type'    => 'page',
                'post_name'    => 'book-trial-class',
            ) );
            update_option( 'macm_trial_booking_page_id', $page_id );
        }
    }

    /**
     * Enqueue scripts and styles.
     *
     * @since 1.0.61
     */
    public function enqueue_scripts() {
        $post_content = get_post()->post_content ?? '';
        if ( is_page( 'book-trial-class' ) || has_shortcode( $post_content, 'macm_trial_booking' ) || has_shortcode( $post_content, 'macm_trial_booking_form' ) ) {
            wp_enqueue_style(
                'kcm-trial-booking',
                plugins_url( 'assets/css/trial-booking.css', dirname( __DIR__ ) ),
                array(),
                MACM_VERSION
            );
            // Add dynamic button gradient CSS.
            $button_gradient_start_raw = get_option( 'macm_button_gradient_start', '#B11226' );
            $button_gradient_end_raw = get_option( 'macm_button_gradient_end', '#8F0E1E' );
            // Sanitize hex colors - fall back to defaults if invalid.
            $button_gradient_start = sanitize_hex_color( $button_gradient_start_raw );
            $button_gradient_end = sanitize_hex_color( $button_gradient_end_raw );
            if ( !$button_gradient_start ) {
                $button_gradient_start = '#B11226';
            }
            if ( !$button_gradient_end ) {
                $button_gradient_end = '#8F0E1E';
            }
            $custom_css = sprintf( '.kcm-submit-button {
					background: linear-gradient(135deg, %s 0%%, %s 100%%) !important;
				}', esc_attr( $button_gradient_start ), esc_attr( $button_gradient_end ) );
            wp_add_inline_style( 'kcm-trial-booking', $custom_css );
            wp_enqueue_script(
                'kcm-trial-booking',
                plugins_url( 'assets/js/trial-booking.js', dirname( __DIR__ ) ),
                array('jquery'),
                MACM_VERSION,
                true
            );
            wp_localize_script( 'kcm-trial-booking', 'macmTrialBooking', array(
                'ajaxurl' => admin_url( 'admin-ajax.php' ),
                'nonce'   => wp_create_nonce( 'macm_trial_booking_nonce' ),
                'i18n'    => array(
                    'fullNameRequired'   => __( 'Full name is required.', 'martial-arts-club-manager' ),
                    'parentNameRequired' => __( 'Parent name is required when booking for a child.', 'martial-arts-club-manager' ),
                    'emailRequired'      => __( 'Email is required.', 'martial-arts-club-manager' ),
                    'invalidEmail'       => __( 'Please enter a valid email address.', 'martial-arts-club-manager' ),
                    'submitting'         => __( 'Submitting...', 'martial-arts-club-manager' ),
                    'bookTrialClass'     => __( 'Book Trial Class', 'martial-arts-club-manager' ),
                    'errorTryAgain'      => __( 'An error occurred. Please try again.', 'martial-arts-club-manager' ),
                    'childsName'         => __( "Child's Name", 'martial-arts-club-manager' ),
                    'fullName'           => __( 'Full Name', 'martial-arts-club-manager' ),
                ),
            ) );
        }
    }

    /**
     * Render booking form.
     *
     * @since 1.0.61
     * @return string HTML output.
     */
    public function render_booking_form() {
        // Get all active classes (premium feature only).
        global $wpdb;
        $classes = array();
        // Only query classes if premium and table exists.
        if ( function_exists( 'macm_fs' ) && macm_fs()->can_use_premium_code() ) {
            $table_name = $wpdb->prefix . 'macm_classes';
            // Check if table exists with caching.
            $cache_key = 'macm_table_exists_classes';
            $table_exists = wp_cache_get( $cache_key, 'macm' );
            if ( false === $table_exists ) {
                $table_check = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) );
                $table_exists = ( $table_check === $table_name ? 'yes' : 'no' );
                wp_cache_set(
                    $cache_key,
                    $table_exists,
                    'macm',
                    300
                );
            }
            if ( 'yes' === $table_exists ) {
                $locations_table = $wpdb->prefix . 'macm_locations';
                $classes_cache = wp_cache_get( 'macm_active_classes_list', 'macm' );
                if ( false === $classes_cache ) {
                    $classes_cache = $wpdb->get_results( $wpdb->prepare( 'SELECT c.id, c.class_name as name, c.day_of_week, c.start_time, c.end_time, l.location_name
							FROM %i c
							LEFT JOIN %i l ON c.location_id = l.id
							WHERE c.is_archived = 0
							ORDER BY c.day_of_week, c.start_time', $table_name, $locations_table ) );
                    wp_cache_set(
                        'macm_active_classes_list',
                        $classes_cache,
                        'macm',
                        300
                    );
                }
                $classes = $classes_cache;
            }
        }
        ob_start();
        include MACM_PLUGIN_DIR . 'templates/public/trial-booking-form.php';
        return ob_get_clean();
    }

    /**
     * Handle booking form submission.
     *
     * @since 1.0.61
     */
    public function handle_booking_submission() {
        // Verify nonce.
        $nonce = ( isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '' );
        if ( !wp_verify_nonce( $nonce, 'macm_trial_booking_nonce' ) ) {
            wp_send_json_error( array(
                'message' => __( 'Security check failed.', 'martial-arts-club-manager' ),
            ) );
        }
        // Sanitize and validate input.
        $full_name = ( isset( $_POST['full_name'] ) ? sanitize_text_field( wp_unslash( $_POST['full_name'] ) ) : '' );
        $is_for_child = ( isset( $_POST['is_for_child'] ) ? absint( wp_unslash( $_POST['is_for_child'] ) ) : 0 );
        $parent_name = ( isset( $_POST['parent_name'] ) ? sanitize_text_field( wp_unslash( $_POST['parent_name'] ) ) : '' );
        $mobile = ( isset( $_POST['mobile'] ) ? sanitize_text_field( wp_unslash( $_POST['mobile'] ) ) : '' );
        $email = ( isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '' );
        $class_id = ( isset( $_POST['class_id'] ) ? absint( wp_unslash( $_POST['class_id'] ) ) : 0 );
        // Validation.
        $errors = array();
        if ( empty( $full_name ) ) {
            $errors[] = __( 'Full name is required.', 'martial-arts-club-manager' );
        }
        if ( $is_for_child && empty( $parent_name ) ) {
            $errors[] = __( 'Parent name is required when booking for a child.', 'martial-arts-club-manager' );
        }
        // Mobile is optional, but if provided, validate format.
        if ( !empty( $mobile ) && !preg_match( '/^[0-9\\s\\-\\+\\(\\)]+$/', $mobile ) ) {
            $errors[] = __( 'Please enter a valid mobile number (numbers only).', 'martial-arts-club-manager' );
        }
        if ( empty( $email ) ) {
            $errors[] = __( 'Email is required.', 'martial-arts-club-manager' );
        } elseif ( !is_email( $email ) ) {
            $errors[] = __( 'Please enter a valid email address.', 'martial-arts-club-manager' );
        }
        // Class selection is optional.
        if ( !empty( $errors ) ) {
            wp_send_json_error( array(
                'message' => implode( '<br>', $errors ),
            ) );
        }
        // Insert into database.
        global $wpdb;
        // Invalidate trial bookings cache before insert.
        wp_cache_delete( 'macm_trial_bookings_list', 'macm' );
        $inserted = $wpdb->insert( $wpdb->prefix . 'macm_trial_bookings', array(
            'full_name'    => $full_name,
            'is_for_child' => $is_for_child,
            'parent_name'  => $parent_name,
            'mobile'       => $mobile,
            'email'        => $email,
            'class_id'     => ( $class_id ? $class_id : null ),
            'status'       => 'pending',
        ), array(
            '%s',
            '%d',
            '%s',
            '%s',
            '%s',
            '%d',
            '%s'
        ) );
        if ( $inserted ) {
            $booking_id = $wpdb->insert_id;
            // Get class details if class_id is provided with caching.
            $class_details = array();
            if ( $class_id ) {
                $class_cache_key = 'macm_class_details_' . $class_id;
                $class = wp_cache_get( $class_cache_key, 'macm' );
                if ( false === $class ) {
                    $classes_table = $wpdb->prefix . 'macm_classes';
                    $locations_table = $wpdb->prefix . 'macm_locations';
                    $class = $wpdb->get_row( $wpdb->prepare(
                        'SELECT c.class_name, c.day_of_week, c.start_time, c.end_time, l.location_name
							FROM %i c
							LEFT JOIN %i l ON c.location_id = l.id
							WHERE c.id = %d',
                        $classes_table,
                        $locations_table,
                        $class_id
                    ) );
                    if ( $class ) {
                        wp_cache_set(
                            $class_cache_key,
                            $class,
                            'macm',
                            300
                        );
                    }
                }
                if ( $class ) {
                    $class_details = array(
                        'name'          => $class->class_name,
                        'day_of_week'   => $class->day_of_week,
                        'start_time'    => $class->start_time,
                        'end_time'      => $class->end_time,
                        'location_name' => $class->location_name,
                    );
                }
            }
            // Send notification email to admin.
            $this->send_notification_email(
                $booking_id,
                $full_name,
                $is_for_child,
                $parent_name,
                $mobile,
                $email,
                $class_details
            );
            // Send confirmation email to user.
            $this->send_user_confirmation_email(
                $full_name,
                $is_for_child,
                $parent_name,
                $mobile,
                $email,
                $class_details
            );
            // Get success message.
            $success_message = get_option( 'macm_trial_booking_success_message', __( 'Thank you for booking a trial lesson. A member of our team will contact you as soon as possible to confirm availability.', 'martial-arts-club-manager' ) );
            wp_send_json_success( array(
                'message' => $success_message,
            ) );
        } else {
            wp_send_json_error( array(
                'message' => __( 'Failed to submit booking. Please try again.', 'martial-arts-club-manager' ),
            ) );
        }
    }

    /**
     * Send notification email to admin.
     *
     * @since 1.0.62
     * @param int    $booking_id     Booking ID.
     * @param string $full_name      Full name.
     * @param int    $is_for_child   Is for child.
     * @param string $parent_name    Parent name.
     * @param string $mobile         Mobile number.
     * @param string $email          Email address.
     * @param array  $class_details  Class details array.
     */
    private function send_notification_email(
        $booking_id,
        $full_name,
        $is_for_child,
        $parent_name,
        $mobile,
        $email,
        $class_details
    ) {
        // Get notification email(s) from settings.
        $to = macm_parse_notification_emails( get_option( 'macm_trial_booking_notification_email', '' ) );
        // Get gradient colors from settings.
        $gradient_start = get_option( 'macm_email_gradient_start', '#B11226' );
        $gradient_end = get_option( 'macm_email_gradient_end', '#8F0E1E' );
        $gradient_style = sprintf( 'background: linear-gradient(135deg, %s 0%%, %s 100%%)', esc_attr( $gradient_start ), esc_attr( $gradient_end ) );
        $site_name = get_bloginfo( 'name' );
        $site_logo_html = $this->get_site_logo_html();
        // Prepare email subject.
        /* translators: %s: site name */
        $subject = sprintf( __( 'New Trial Class Booking Request - %s', 'martial-arts-club-manager' ), $site_name );
        // Build admin panel link.
        $admin_link = admin_url( 'admin.php?page=kcm-trial-bookings' );
        // Build email body with all booking information.
        $body = '<h2 style="color: #111827; font-size: 20px; margin-bottom: 20px;">' . __( 'New Trial Class Booking', 'martial-arts-club-manager' ) . '</h2>';
        $body .= '<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;">';
        $body .= '<tr><td style="padding: 10px; border-bottom: 1px solid #D1D5DB; font-weight: 600; width: 35%;">' . __( 'Full Name:', 'martial-arts-club-manager' ) . '</td>';
        $body .= '<td style="padding: 10px; border-bottom: 1px solid #D1D5DB;">' . esc_html( $full_name ) . '</td></tr>';
        $body .= '<tr><td style="padding: 10px; border-bottom: 1px solid #D1D5DB; font-weight: 600;">' . __( 'For Child:', 'martial-arts-club-manager' ) . '</td>';
        $body .= '<td style="padding: 10px; border-bottom: 1px solid #D1D5DB;">' . (( $is_for_child ? __( 'Yes', 'martial-arts-club-manager' ) : __( 'No', 'martial-arts-club-manager' ) )) . '</td></tr>';
        if ( $is_for_child && !empty( $parent_name ) ) {
            $body .= '<tr><td style="padding: 10px; border-bottom: 1px solid #D1D5DB; font-weight: 600;">' . __( 'Parent Name:', 'martial-arts-club-manager' ) . '</td>';
            $body .= '<td style="padding: 10px; border-bottom: 1px solid #D1D5DB;">' . esc_html( $parent_name ) . '</td></tr>';
        } else {
            $body .= '<tr><td style="padding: 10px; border-bottom: 1px solid #D1D5DB; font-weight: 600;">' . __( 'Parent Name:', 'martial-arts-club-manager' ) . '</td>';
            $body .= '<td style="padding: 10px; border-bottom: 1px solid #D1D5DB; color: #6B7280;">—</td></tr>';
        }
        $body .= '<tr><td style="padding: 10px; border-bottom: 1px solid #D1D5DB; font-weight: 600;">' . __( 'Mobile:', 'martial-arts-club-manager' ) . '</td>';
        $body .= '<td style="padding: 10px; border-bottom: 1px solid #D1D5DB;">' . esc_html( $mobile ) . '</td></tr>';
        $body .= '<tr><td style="padding: 10px; border-bottom: 1px solid #D1D5DB; font-weight: 600;">' . __( 'Email:', 'martial-arts-club-manager' ) . '</td>';
        $body .= '<td style="padding: 10px; border-bottom: 1px solid #D1D5DB;"><a href="mailto:' . esc_attr( $email ) . '" style="color: #B11226; text-decoration: none;">' . esc_html( $email ) . '</a></td></tr>';
        // Class information section.
        if ( !empty( $class_details ) ) {
            $days = array(
                __( 'Sunday', 'martial-arts-club-manager' ),
                __( 'Monday', 'martial-arts-club-manager' ),
                __( 'Tuesday', 'martial-arts-club-manager' ),
                __( 'Wednesday', 'martial-arts-club-manager' ),
                __( 'Thursday', 'martial-arts-club-manager' ),
                __( 'Friday', 'martial-arts-club-manager' ),
                __( 'Saturday', 'martial-arts-club-manager' )
            );
            $day_name = ( isset( $days[$class_details['day_of_week']] ) ? $days[$class_details['day_of_week']] : '' );
            $start_time = ( !empty( $class_details['start_time'] ) ? wp_date( 'g:i A', strtotime( $class_details['start_time'] ) ) : '' );
            $end_time = ( !empty( $class_details['end_time'] ) ? wp_date( 'g:i A', strtotime( $class_details['end_time'] ) ) : '' );
            $location = ( !empty( $class_details['location_name'] ) ? $class_details['location_name'] : '' );
            $body .= '<tr><td colspan="2" style="padding: 15px 10px 5px 10px; font-weight: 600; font-size: 14px; color: #6B7280;">' . __( 'Class Information', 'martial-arts-club-manager' ) . '</td></tr>';
            $body .= '<tr><td style="padding: 10px; padding-left: 20px; border-bottom: 1px solid #D1D5DB; font-weight: 600;">' . __( 'Class Name:', 'martial-arts-club-manager' ) . '</td>';
            $body .= '<td style="padding: 10px; border-bottom: 1px solid #D1D5DB;">' . esc_html( $class_details['name'] ) . '</td></tr>';
            $body .= '<tr><td style="padding: 10px; padding-left: 20px; border-bottom: 1px solid #D1D5DB; font-weight: 600;">' . __( 'Day:', 'martial-arts-club-manager' ) . '</td>';
            $body .= '<td style="padding: 10px; border-bottom: 1px solid #D1D5DB;">' . esc_html( $day_name ) . '</td></tr>';
            $body .= '<tr><td style="padding: 10px; padding-left: 20px; border-bottom: 1px solid #D1D5DB; font-weight: 600;">' . __( 'Time:', 'martial-arts-club-manager' ) . '</td>';
            $body .= '<td style="padding: 10px; border-bottom: 1px solid #D1D5DB;">' . esc_html( $start_time . ' - ' . $end_time ) . '</td></tr>';
            $body .= '<tr><td style="padding: 10px; padding-left: 20px; border-bottom: 1px solid #D1D5DB; font-weight: 600;">' . __( 'Location:', 'martial-arts-club-manager' ) . '</td>';
            $body .= '<td style="padding: 10px; border-bottom: 1px solid #D1D5DB;">' . esc_html( $location ) . '</td></tr>';
        }
        $body .= '</table>';
        $body .= '<p style="margin: 20px 0;"><a href="' . esc_url( $admin_link ) . '" style="display: inline-block; background: linear-gradient(135deg, ' . esc_attr( $gradient_start ) . ' 0%, ' . esc_attr( $gradient_end ) . ' 100%); color: #ffffff; text-decoration: none; padding: 12px 30px; border-radius: 4px; font-weight: 600;">' . __( 'View in Admin Panel', 'martial-arts-club-manager' ) . '</a></p>';
        // Format email with template.
        $email_content = $this->format_notification_email(
            $body,
            $gradient_style,
            $site_name,
            $site_logo_html
        );
        // Send email.
        $headers = array('Content-Type: text/html; charset=UTF-8');
        wp_mail(
            $to,
            $subject,
            $email_content,
            $headers
        );
    }

    /**
     * Format notification email with template.
     *
     * @since 1.0.62
     * @param string $body          Email body.
     * @param string $gradient_style Gradient style.
     * @param string $site_name     Site name.
     * @param string $site_logo_html Site logo HTML.
     * @return string Formatted email HTML.
     */
    private function format_notification_email(
        $body,
        $gradient_style,
        $site_name,
        $site_logo_html
    ) {
        $html = '<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #F4F4F2;">
	<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background-color: #F4F4F2; padding: 20px 0;">
		<tr>
			<td align="center">
				<table role="presentation" cellpadding="0" cellspacing="0" width="600" style="background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
					<tr>
						<td style="' . $gradient_style . '; padding: 40px 30px; text-align: center; border-radius: 8px 8px 0 0;">
							' . $site_logo_html . '
							<h1 style="color: #ffffff; margin: 20px 0 0 0; font-size: 24px; font-weight: 600;">' . esc_html( $site_name ) . '</h1>
						</td>
					</tr>
					<tr>
						<td style="padding: 40px 30px;">
							<div style="font-size: 16px; color: #111827; line-height: 1.6;">
								' . $body . '
							</div>
						</td>
					</tr>
					<tr>
						<td style="background-color: #F4F4F2; padding: 20px 30px; text-align: center; border-radius: 0 0 8px 8px; border-top: 1px solid #D1D5DB;">
							<p style="margin: 0; font-size: 13px; color: #6B7280;">
								' . esc_html__( 'This is an automated notification from your website.', 'martial-arts-club-manager' ) . '
							</p>
						</td>
					</tr>
				</table>
			</td>
		</tr>
	</table>
</body>
</html>';
        return $html;
    }

    /**
     * Get site logo HTML.
     *
     * @since 1.0.62
     * @return string Logo HTML.
     */
    private function get_site_logo_html() {
        $custom_logo_id = get_theme_mod( 'custom_logo' );
        if ( $custom_logo_id ) {
            $logo_url = wp_get_attachment_image_url( $custom_logo_id, 'medium' );
            if ( $logo_url ) {
                return '<img src="' . esc_url( $logo_url ) . '" alt="' . esc_attr( get_bloginfo( 'name' ) ) . '" style="max-width: 200px; height: auto; display: block; margin: 0 auto;" />';
            }
        }
        return '';
    }

    /**
     * Send confirmation email to user.
     *
     * @since 1.0.62
     * @param string $full_name    Full name.
     * @param int    $is_for_child Is for child.
     * @param string $parent_name  Parent name.
     * @param string $mobile       Mobile number.
     * @param string $email        Email address.
     * @param array  $class_details Class details array.
     */
    private function send_user_confirmation_email(
        $full_name,
        $is_for_child,
        $parent_name,
        $mobile,
        $email,
        $class_details
    ) {
        if ( empty( $email ) || !is_email( $email ) ) {
            return;
            // Skip if no valid email.
        }
        // Get gradient colors from settings.
        $gradient_start = get_option( 'macm_email_gradient_start', '#B11226' );
        $gradient_end = get_option( 'macm_email_gradient_end', '#8F0E1E' );
        $gradient_style = sprintf( 'background: linear-gradient(135deg, %s 0%%, %s 100%%)', esc_attr( $gradient_start ), esc_attr( $gradient_end ) );
        $site_name = get_bloginfo( 'name' );
        $site_logo_html = $this->get_site_logo_html();
        // Prepare email subject.
        /* translators: %s: site name */
        $subject = sprintf( __( 'Trial Class Booking Confirmation - %s', 'martial-arts-club-manager' ), $site_name );
        // Build email body with booking details.
        $body = '<h2 style="color: #111827; font-size: 20px; margin-bottom: 10px;">' . __( 'Thank You for Your Booking Request!', 'martial-arts-club-manager' ) . '</h2>';
        $body .= '<p style="color: #6B7280; font-size: 16px; line-height: 1.6; margin-bottom: 20px;">' . __( 'We have received your trial class booking request. A member of our team will contact you soon to confirm availability.', 'martial-arts-club-manager' ) . '</p>';
        $body .= '<h3 style="color: #111827; font-size: 18px; margin-top: 30px; margin-bottom: 15px;">' . __( 'Booking Details:', 'martial-arts-club-manager' ) . '</h3>';
        $body .= '<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px; background-color: #F4F4F2; border-radius: 4px;">';
        $body .= '<tr><td style="padding: 12px 15px; border-bottom: 1px solid #D1D5DB; font-weight: 600; width: 35%; color: #6B7280;">' . __( 'Name:', 'martial-arts-club-manager' ) . '</td>';
        $body .= '<td style="padding: 12px 15px; border-bottom: 1px solid #D1D5DB; color: #111827;">' . esc_html( $full_name ) . '</td></tr>';
        if ( $is_for_child && !empty( $parent_name ) ) {
            $body .= '<tr><td style="padding: 12px 15px; border-bottom: 1px solid #D1D5DB; font-weight: 600; color: #6B7280;">' . __( 'Parent Name:', 'martial-arts-club-manager' ) . '</td>';
            $body .= '<td style="padding: 12px 15px; border-bottom: 1px solid #D1D5DB; color: #111827;">' . esc_html( $parent_name ) . '</td></tr>';
        }
        if ( !empty( $mobile ) ) {
            $body .= '<tr><td style="padding: 12px 15px; border-bottom: 1px solid #D1D5DB; font-weight: 600; color: #6B7280;">' . __( 'Mobile:', 'martial-arts-club-manager' ) . '</td>';
            $body .= '<td style="padding: 12px 15px; border-bottom: 1px solid #D1D5DB; color: #111827;">' . esc_html( $mobile ) . '</td></tr>';
        }
        $body .= '<tr><td style="padding: 12px 15px; border-bottom: 1px solid #D1D5DB; font-weight: 600; color: #6B7280;">' . __( 'Email:', 'martial-arts-club-manager' ) . '</td>';
        $body .= '<td style="padding: 12px 15px; border-bottom: 1px solid #D1D5DB; color: #111827;">' . esc_html( $email ) . '</td></tr>';
        // Add class details if available.
        if ( !empty( $class_details ) ) {
            $body .= '<tr><td style="padding: 12px 15px; font-weight: 600; color: #6B7280;">' . __( 'Class:', 'martial-arts-club-manager' ) . '</td>';
            $body .= '<td style="padding: 12px 15px; color: #111827;">';
            $body .= '<strong>' . esc_html( $class_details['name'] ) . '</strong><br>';
            // Format day of week.
            $days = array(
                1 => __( 'Monday', 'martial-arts-club-manager' ),
                2 => __( 'Tuesday', 'martial-arts-club-manager' ),
                3 => __( 'Wednesday', 'martial-arts-club-manager' ),
                4 => __( 'Thursday', 'martial-arts-club-manager' ),
                5 => __( 'Friday', 'martial-arts-club-manager' ),
                6 => __( 'Saturday', 'martial-arts-club-manager' ),
                7 => __( 'Sunday', 'martial-arts-club-manager' ),
            );
            $day_name = ( isset( $days[$class_details['day_of_week']] ) ? $days[$class_details['day_of_week']] : '' );
            if ( $day_name ) {
                $body .= esc_html( $day_name ) . ', ';
            }
            // Format times.
            if ( !empty( $class_details['start_time'] ) && !empty( $class_details['end_time'] ) ) {
                $start_time = wp_date( get_option( 'time_format' ), strtotime( $class_details['start_time'] ) );
                $end_time = wp_date( get_option( 'time_format' ), strtotime( $class_details['end_time'] ) );
                $body .= esc_html( $start_time . ' - ' . $end_time );
            }
            // Add location.
            if ( !empty( $class_details['location_name'] ) ) {
                $body .= '<br><span style="color: #6B7280;">' . esc_html( $class_details['location_name'] ) . '</span>';
            }
            $body .= '</td></tr>';
        }
        $body .= '</table>';
        $body .= '<p style="color: #6B7280; font-size: 15px; line-height: 1.6; margin-top: 30px;">' . __( 'If you have any questions or need to make changes to your booking, please contact us.', 'martial-arts-club-manager' ) . '</p>';
        // Format email with template.
        $email_content = $this->format_user_confirmation_email(
            $body,
            $gradient_style,
            $site_name,
            $site_logo_html
        );
        // Send email.
        $headers = array('Content-Type: text/html; charset=UTF-8');
        wp_mail(
            $email,
            $subject,
            $email_content,
            $headers
        );
    }

    /**
     * Format user confirmation email with template.
     *
     * @since 1.0.62
     * @param string $body          Email body.
     * @param string $gradient_style Gradient style.
     * @param string $site_name     Site name.
     * @param string $site_logo_html Site logo HTML.
     * @return string Formatted email HTML.
     */
    private function format_user_confirmation_email(
        $body,
        $gradient_style,
        $site_name,
        $site_logo_html
    ) {
        $html = '<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #F4F4F2;">
	<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background-color: #F4F4F2; padding: 20px 0;">
		<tr>
			<td align="center">
				<table role="presentation" cellpadding="0" cellspacing="0" width="600" style="background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
					<tr>
						<td style="' . $gradient_style . '; padding: 40px 30px; text-align: center; border-radius: 8px 8px 0 0;">
							' . $site_logo_html . '
							<h1 style="color: #ffffff; margin: 20px 0 0 0; font-size: 24px; font-weight: 600;">' . esc_html( $site_name ) . '</h1>
						</td>
					</tr>
					<tr>
						<td style="padding: 40px 30px;">
							<div style="font-size: 16px; color: #111827; line-height: 1.6;">
								' . $body . '
							</div>
						</td>
					</tr>
					<tr>
						<td style="background-color: #F4F4F2; padding: 20px 30px; text-align: center; border-radius: 0 0 8px 8px; border-top: 1px solid #D1D5DB;">
							<p style="margin: 0; font-size: 13px; color: #6B7280;">
								' . sprintf( esc_html__( 'This is an automated confirmation from %s.', 'martial-arts-club-manager' ), esc_html( $site_name ) ) . '
							</p>
						</td>
					</tr>
				</table>
			</td>
		</tr>
	</table>
</body>
</html>';
        return $html;
    }

    /**
     * Execute report query with literal SQL.
     *
     * @since 1.0.319
     * @param string $filter_key Filter combination key.
     * @param string $t1         Bookings table.
     * @param string $t2         Classes table.
     * @param string $date_from  Start date.
     * @param string $date_to    End date.
     * @param string $status     Status filter.
     * @param int    $class_id   Class ID filter.
     * @return array Query results.
     */
    private static function execute_report_query(
        $filter_key,
        $t1,
        $t2,
        $date_from,
        $date_to,
        $status,
        $class_id
    ) {
        global $wpdb;
        switch ( $filter_key ) {
            case '':
                return $wpdb->get_results( $wpdb->prepare( 'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id ORDER BY b.created_at DESC', $t1, $t2 ) );
            case 'd':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.created_at >= %s AND b.created_at <= %s ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $date_from . ' 00:00:00',
                    $date_to . ' 23:59:59'
                ) );
            case 's':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $status
                ) );
            case 'c':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.class_id = %d ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $class_id
                ) );
            case 'ds':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.created_at >= %s AND b.created_at <= %s AND b.status = %s ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $date_from . ' 00:00:00',
                    $date_to . ' 23:59:59',
                    $status
                ) );
            case 'dc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.created_at >= %s AND b.created_at <= %s AND b.class_id = %d ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $date_from . ' 00:00:00',
                    $date_to . ' 23:59:59',
                    $class_id
                ) );
            case 'sc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.status = %s AND b.class_id = %d ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $status,
                    $class_id
                ) );
            case 'dsc':
                return $wpdb->get_results( $wpdb->prepare(
                    'SELECT b.*, c.class_name FROM %i b LEFT JOIN %i c ON b.class_id = c.id WHERE b.created_at >= %s AND b.created_at <= %s AND b.status = %s AND b.class_id = %d ORDER BY b.created_at DESC',
                    $t1,
                    $t2,
                    $date_from . ' 00:00:00',
                    $date_to . ' 23:59:59',
                    $status,
                    $class_id
                ) );
            default:
                return array();
        }
    }

}

// Initialize.
new MACM_Trial_Booking();