<?php //phpcs:ignore

/**
 * File: Wemeet_Ajax.php
 *
 * The Wemeet_Ajax class handles AJAX requests and provides functionalities for generating referral coupons.
 *
 * @package ECRE
 * @since   1.0.0
 */

namespace SOVLIX\WEMEET;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! class_exists( 'Wemeet_Ajax' ) ) {
	/**
	 * The Wemeet_Ajax class handles AJAX requests and provides functionalities for generating referral coupons.
	 *
	 * @since 1.0.0
	 */
	class Wemeet_Ajax {
		/**
		 * Wemeet_Ajax constructor.
		 *
		 * Initializes the class and sets up AJAX request handlers.
		 */
		public function __construct() {
			add_action( 'wp_ajax_wemeet_meeting_action', array( $this, 'handle_wemeet_meeting_action' ) );
			add_action( 'wp_ajax_nopriv_wemeet_meeting_action', array( $this, 'handle_wemeet_meeting_action' ) );
			add_action( 'wp_ajax_wemeet_meeting_list', array( $this, 'wemeet_meeting_lists' ) );
			add_action( 'wp_ajax_nopriv_wemeet_meeting_list', array( $this, 'wemeet_meeting_lists' ) );
			add_action( 'wp_ajax_wemeet_save_visibility_mode', array( $this, 'wemeet_save_visibility_mode' ) );
			add_action( 'wp_ajax_wemeet_fetch_users', array( $this, 'wemeet_fetch_users_callback' ) );
			add_action( 'wp_ajax_wemeet_fetch_roles', array( $this, 'wemeet_fetch_roles_callback' ) );
			add_action( 'wp_ajax_wemeet_fetch_users_by_ids', array( $this, 'wemeet_fetch_users_by_ids' ) );
			add_action( 'wp_ajax_nopriv_wemeet_fetch_users_by_ids', array( $this, 'wemeet_fetch_users_by_ids' ) );
		}

		/**
		 * Fetch users by IDs via AJAX.
		 *
		 * @return void
		 */
		public function wemeet_fetch_users_by_ids() {
			if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wemeet_frontend_nonce' ) ) {
				wp_send_json_error( array( 'message' => 'Invalid nonce' ), 403 );
			}

			// Must be logged in.
			if ( ! is_user_logged_in() ) {
				wp_send_json_error( array( 'message' => 'Not logged in' ), 401 );
			}

			// Check user capability.
			if ( ! current_user_can( 'manage_options' ) ) {
				wp_send_json_error( array( 'message' => 'Unauthorized request.' ) );
			}

			$user_ids = isset( $_POST['user_ids'] ) ? array_map( 'absint', wp_unslash( (array) $_POST['user_ids'] ) ) : array();

			if ( empty( $user_ids ) ) {
				wp_send_json_success( array() );
			}

			$users = get_users(
				array(
					'include' => $user_ids,
					'fields'  => array( 'ID', 'display_name', 'user_email' ),
				)
			);

			$options = array_map(
				function ( $user ) {
					return array(
						'value' => (string) $user->ID,
						'label' => esc_html( $user->display_name ) . ' (' . esc_html( $user->user_email ) . ')',
					);
				},
				$users
			);

			wp_send_json_success( $options );
		}

		/**
		 * AJAX callback to fetch all available WordPress user roles.
		 *
		 * This function is triggered via an authenticated AJAX request from the frontend.
		 * It verifies the nonce for security, retrieves all registered user roles,
		 * and returns them in a structured JSON response suitable for use in
		 * dropdowns or selectors.
		 *
		 * @since 1.0.0
		 *
		 * @return void Outputs a JSON success response with the list of roles.
		 */
		public function wemeet_fetch_roles_callback() {
			if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wemeet_frontend_nonce' ) ) {
				wp_send_json_error( array( 'message' => 'Invalid nonce' ), 403 );
			}

			// Must be logged in.
			if ( ! is_user_logged_in() ) {
				wp_send_json_error( array( 'message' => 'Not logged in' ), 401 );
			}

			// Check user capability.
			if ( ! current_user_can( 'manage_options' ) ) {
				wp_send_json_error( array( 'message' => 'Unauthorized request.' ) );
			}

			$roles = wp_roles()->get_names();

			$role_options = array();

			foreach ( $roles as $key => $label ) {
				$role_options[] = array(
					'value' => $key,
					'label' => $label,
				);
			}

			wp_send_json_success( $role_options );
		}

		/**
		 * Alternative simpler approach - optimized version of existing method
		 * Replace your existing wemeet_fetch_users_callback with this
		 */
		public function wemeet_fetch_users_callback() {
			// Nonce check.
			if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wemeet_frontend_nonce' ) ) {
				wp_send_json_error( array( 'message' => 'Invalid nonce' ), 403 );
			}

			// Must be logged in.
			if ( ! is_user_logged_in() ) {
				wp_send_json_error( array( 'message' => 'Not logged in' ), 401 );
			}

			// Check user capability.
			if ( ! current_user_can( 'manage_options' ) ) {
				wp_send_json_error( array( 'message' => 'Unauthorized request.' ) );
			}

			global $wpdb;

			// Sanitize and validate search input.
			$search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : '';

			// Require minimum 3 characters to avoid extremely heavy queries on large datasets.
			if ( strlen( $search ) < 3 ) {
				wp_send_json_success( array() );
				return;
			}

			// Create cache key for this search.
			$cache_key = 'wemeet_user_search_' . md5( $search );

			// Try to get cached results first.
			$cached_results = wp_cache_get( $cache_key, 'wemeet_users' );
			if ( false !== $cached_results ) {
				wp_send_json_success( $cached_results );
				return;
			}

			// Prepare search term for LIKE query.
			$search_term = '%' . $wpdb->esc_like( $search ) . '%';

			// Execute prepared statement directly without intermediate variable.
			// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$results = $wpdb->get_results(
				$wpdb->prepare(
					"SELECT ID, display_name, user_login, user_email
					FROM {$wpdb->users}
					WHERE display_name LIKE %s 
						OR user_login LIKE %s 
						OR user_email LIKE %s
					ORDER BY display_name ASC",
					$search_term,
					$search_term,
					$search_term
				)
			);
			// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching

			// Handle empty results.
			if ( ! $results ) {
				// Cache empty results for 5 minutes to avoid repeated queries.
				wp_cache_set( $cache_key, array(), 'wemeet_users', 300 );
				wp_send_json_success( array() );
				return;
			}

			// Transform results using array_map for better performance.
			$data = array_map(
				function ( $user ) {
					return array(
						'value' => (string) $user->ID,
						'label' => sprintf(
							'%s (%s - %s)',
							esc_html( $user->display_name ),
							esc_html( $user->user_login ),
							esc_html( $user->user_email )
						),
					);
				},
				$results
			);

			// Cache results for 15 minutes.
			wp_cache_set( $cache_key, $data, 'wemeet_users', 900 );

			// Return successful response.
			wp_send_json_success( $data );
		}

		/**
		 * AJAX callback to save visibility mode settings for a page.
		 *
		 * @since 1.0.0
		 *
		 * @return void Outputs JSON response and exits.
		 */
		public function wemeet_save_visibility_mode() {
			// Verify nonce for security.
			if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wemeet_frontend_nonce' ) ) {
				wp_send_json_error( array( 'message' => 'Invalid nonce' ), 403 );
			}

			// Must be logged in.
			if ( ! is_user_logged_in() ) {
				wp_send_json_error( array( 'message' => 'Not logged in' ), 401 );
			}

			// Check user capability.
			if ( ! current_user_can( 'manage_options' ) ) {
				wp_send_json_error( array( 'message' => 'Unauthorized request.' ) );
			}

			// Sanitize and validate input data.
			$page_id = isset( $_POST['page_id'] ) ? absint( $_POST['page_id'] ) : 0;
			$mode    = isset( $_POST['mode'] ) ? sanitize_text_field( wp_unslash( $_POST['mode'] ) ) : 'user';

			// Validate page ID.
			if ( 0 === $page_id ) {
				wp_send_json_error( __( 'Invalid page ID.', 'wemeet' ) );
				return;
			}

			// Handle roles data.
			$roles = array();
			if ( isset( $_POST['roles'] ) ) {
				$roles_input = sanitize_text_field( wp_unslash( $_POST['roles'] ) );
				$roles_raw   = json_decode( stripslashes( $roles_input ), true );
				if ( is_array( $roles_raw ) ) {
					$roles = array_map( 'sanitize_text_field', $roles_raw );
				}
			}

			// Handle users data.
			$users = array();
			if ( isset( $_POST['users'] ) ) {
				$users_input = sanitize_text_field( wp_unslash( $_POST['users'] ) );
				$users_raw   = json_decode( stripslashes( $users_input ), true );
				if ( is_array( $users_raw ) ) {
					$users = array_map( 'absint', $users_raw );
				}
			}

			// Save the visibility settings.
			update_post_meta( $page_id, '_wemeet_visibility_mode', $mode );
			update_post_meta( $page_id, '_wemeet_visibility_roles', $roles );
			update_post_meta( $page_id, '_wemeet_visibility_users', $users );

			wp_send_json_success( __( 'Visibility settings saved successfully.', 'wemeet' ) );
		}


		/**
		 * Handles AJAX requests for fetching meeting lists.
		 *
		 * This function verifies the nonce for security, fetches the list of meetings,
		 * and returns the meetings as a JSON response. It is intended to be used as a
		 * callback for AJAX requests in WordPress.
		 *
		 * @since 1.13.1
		 *
		 * @return void Outputs JSON response and exits.
		 */
		public function wemeet_meeting_lists() {
			// Verify nonce for security.
			$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
			if ( ! wp_verify_nonce( $nonce, 'wemeet_frontend_nonce' ) ) {
				wp_send_json_error( __( 'Invalid security token.', 'wemeet' ) );
				return;
			}

			// Sanitize and validate input data.
			$page_id = isset( $_POST['page_id'] ) ? absint( $_POST['page_id'] ) : 0;
			$mode    = isset( $_POST['visibility_mode'] ) ? sanitize_text_field( wp_unslash( $_POST['visibility_mode'] ) ) : 'user';

			// Handle roles data - ignore PHPCS warning as we sanitize after JSON decode.
			$roles = array();
			if ( isset( $_POST['roles'] ) ) {
				$roles_input = isset( $_POST['roles'] ) ? sanitize_text_field( wp_unslash( $_POST['roles'] ) ) : '';
				$roles_raw   = json_decode( stripslashes( $roles_input ), true );
				if ( is_array( $roles_raw ) ) {
					$roles = array_map( 'sanitize_text_field', $roles_raw );
				}
			}

			// Handle users data - ignore PHPCS warning as we sanitize after JSON decode.
			$users = array();
			if ( isset( $_POST['users'] ) ) {
				$users_input = isset( $_POST['users'] ) ? sanitize_text_field( wp_unslash( $_POST['users'] ) ) : '';
				$users_raw   = json_decode( stripslashes( $users_input ), true );
				if ( is_array( $users_raw ) ) {
					$users = array_map( 'absint', $users_raw );
				}
			}

			// Check if we should use passed values or saved values.
			$use_passed_values = isset( $_POST['use_passed_values'] ) && '1' === $_POST['use_passed_values'];

			// Fetch meetings based on the specified mode and parameters.
			$meetings = wemeet_meetings_by_mode( $mode, $page_id, $roles, $users, $use_passed_values );

			// Handle potential errors from the helper function.
			if ( is_wp_error( $meetings ) ) {
				wp_send_json_error( $meetings->get_error_message() );
				return;
			}

			wp_send_json_success( $meetings );
		}

		/**
		 * Handle end meeting action
		 */
		public function handle_wemeet_meeting_action() {
			// Verify nonce for security.
			$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
			if ( ! wp_verify_nonce( $nonce, 'wemeet_frontend_nonce' ) ) {
				wp_send_json_error( 'Invalid nonce.' );
			}

			$response = '';

			// Retrieve and sanitize posted data.
			$meeting_id     = isset( $_POST['meeting_id'] ) ? sanitize_text_field( wp_unslash( $_POST['meeting_id'] ) ) : '';
			$post_id        = isset( $_POST['post_id'] ) ? sanitize_text_field( wp_unslash( $_POST['post_id'] ) ) : '';
			$meeting_status = isset( $_POST['meeting_status'] ) ? sanitize_text_field( wp_unslash( $_POST['meeting_status'] ) ) : '';

			if ( 'end' === $meeting_status ) {
				update_post_meta( $post_id, 'wemeet_meeting_status', 'end' );
				$response = 'Meeting ended successfully.';
			}

			if ( 'resume' === $meeting_status ) {
				update_post_meta( $post_id, 'wemeet_meeting_status', 'resume' );
				$response = 'Meeting resumed successfully.';
			}

			if ( 'start' === $meeting_status ) {
				update_post_meta( $post_id, 'wemeet_meeting_start_status', 'start' );
				$response = 'Meeting started successfully.';
			}

			if ( 'stop' === $meeting_status ) {
				update_post_meta( $post_id, 'wemeet_meeting_start_status', 'stop' );
				$response = 'Meeting stoped successfully.';
			}

			// Example: Respond with a success message.
			wp_send_json_success( $response );
		}
	}
}
