<?php
/**
 * Class Register Public Handler
 *
 * Handles the frontend class register shortcode for marking attendance
 *
 * @package    Karate_Club_Manager
 * @subpackage Karate_Club_Manager/includes/public
 * @since      1.0.0
 */

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

/**
 * Class MACM_Class_Register
 *
 * Manages the frontend class register interface
 *
 * @since 1.0.0
 */
class MACM_Class_Register {

	/**
	 * Initialize the class register
	 *
	 * @since 1.0.0
	 */
	public function __construct() {
		add_shortcode( 'macm_class_register', array( $this, 'render_shortcode' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) );

		// AJAX handlers.
		add_action( 'wp_ajax_macm_load_class_members', array( $this, 'ajax_load_class_members' ) );
		add_action( 'wp_ajax_macm_mark_attendance', array( $this, 'ajax_mark_attendance' ) );
	}

	/**
	 * Enqueue scripts and styles
	 *
	 * @since 1.0.0
	 */
	public function enqueue_assets() {
		// Only enqueue if shortcode is present.
		global $post;
		if ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'macm_class_register' ) ) {
			wp_enqueue_style(
				'kcm-class-register',
				plugins_url( 'assets/css/class-register.css', dirname( __DIR__ ) ),
				array(),
				MACM_VERSION
			);

			wp_enqueue_script(
				'kcm-class-register',
				plugins_url( 'assets/js/class-register.js', dirname( __DIR__ ) ),
				array( 'jquery' ),
				MACM_VERSION,
				true
			);

			// Localize script for AJAX.
			wp_localize_script(
				'kcm-class-register',
				'macmClassRegister',
				array(
					'ajaxurl' => admin_url( 'admin-ajax.php' ),
					'nonce'   => wp_create_nonce( 'kcm-class-register-nonce' ),
				)
			);
		}
	}

	/**
	 * Render the class register shortcode
	 *
	 * @since 1.0.0
	 * @return string Shortcode HTML output.
	 */
	public function render_shortcode() {
		// Check if user is logged in.
		if ( ! is_user_logged_in() ) {
			return '<div class="kcm-class-register-error">' . __( 'You must be logged in to access the class register.', 'martial-arts-club-manager' ) . '</div>';
		}

		// Check if user has permission.
		if ( ! $this->user_has_permission() ) {
			return '<div class="kcm-class-register-error">' . __( 'You do not have permission to mark attendance.', 'martial-arts-club-manager' ) . '</div>';
		}

		// Get all active classes.
		$classes = MACM_Class::get_all( true );

		// Load template.
		ob_start();
		include MACM_PLUGIN_DIR . 'templates/public/class-register.php';
		return ob_get_clean();
	}

	/**
	 * Check if current user has permission to use class register
	 *
	 * @since 1.0.0
	 * @return bool True if user has permission, false otherwise.
	 */
	private function user_has_permission() {
		$user_id = get_current_user_id();

		// Administrators always have access.
		if ( current_user_can( 'manage_options' ) ) {
			return true;
		}

		// Check if user has manage_macm_attendance capability.
		if ( current_user_can( 'manage_macm_attendance' ) ) {
			return true;
		}

		// Check user meta for custom class register permission.
		$has_permission = get_user_meta( $user_id, 'macm_class_register_access', true );

		return '1' === $has_permission || 1 === $has_permission;
	}

	/**
	 * AJAX handler to load enrolled members for a class
	 *
	 * @since 1.0.0
	 */
	public function ajax_load_class_members() {
		// Verify nonce.
		check_ajax_referer( 'kcm-class-register-nonce', 'nonce' );

		// Check permission.
		if ( ! $this->user_has_permission() ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied.', 'martial-arts-club-manager' ) ) );
		}

		// Get class ID and date.
		$class_id = isset( $_POST['class_id'] ) ? absint( wp_unslash( $_POST['class_id'] ) ) : 0;
		$date     = isset( $_POST['date'] ) ? sanitize_text_field( wp_unslash( $_POST['date'] ) ) : '';

		if ( ! $class_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid class ID.', 'martial-arts-club-manager' ) ) );
		}

		if ( empty( $date ) ) {
			wp_send_json_error( array( 'message' => __( 'Date is required.', 'martial-arts-club-manager' ) ) );
		}

		// Validate date format.
		$date_obj = DateTime::createFromFormat( 'Y-m-d', $date );
		if ( ! $date_obj || $date_obj->format( 'Y-m-d' ) !== $date ) {
			wp_send_json_error( array( 'message' => __( 'Invalid date format.', 'martial-arts-club-manager' ) ) );
		}

		// Get class.
		$class = MACM_Class::get( $class_id );
		if ( ! $class ) {
			wp_send_json_error( array( 'message' => __( 'Class not found.', 'martial-arts-club-manager' ) ) );
		}

		// Get enrolled members.
		$enrollments = MACM_Class::get_enrolled_members( $class_id );

		if ( empty( $enrollments ) ) {
			wp_send_json_success(
				array(
					'members'    => array(),
					'attendance' => array(),
					'message'    => __( 'No members enrolled in this class.', 'martial-arts-club-manager' ),
				)
			);
		}

		// Prepare member data.
		$members = array();
		foreach ( $enrollments as $enrollment ) {
			$member = MACM_Member::get( $enrollment->member_id );
			if ( $member ) {
				$members[] = array(
					'id'         => $member->id,
					'full_name'  => $member->full_name,
					'group_id'   => $member->group_id,
					'belt_color' => $member->belt_color,
				);
			}
		}

		// Get existing attendance records for this class and date.
		global $wpdb;
		$table_attendance   = $wpdb->prefix . 'macm_attendance';
		$attendance_records = $wpdb->get_results(
			$wpdb->prepare(
				'SELECT * FROM %i WHERE class_id = %d AND attendance_date = %s',
				$table_attendance,
				$class_id,
				$date
			)
		);

		// Prepare attendance data.
		$attendance = array();
		if ( ! empty( $attendance_records ) ) {
			foreach ( $attendance_records as $record ) {
				$attendance[] = array(
					'id'        => $record->id,
					'member_id' => $record->member_id,
				);
			}
		}

		wp_send_json_success(
			array(
				'members'    => $members,
				'attendance' => $attendance,
				'class_name' => $class->class_name,
			)
		);
	}

	/**
	 * AJAX handler to mark attendance
	 *
	 * @since 1.0.0
	 */
	public function ajax_mark_attendance() {
		// Verify nonce.
		check_ajax_referer( 'kcm-class-register-nonce', 'nonce' );

		// Check permission.
		if ( ! $this->user_has_permission() ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied.', 'martial-arts-club-manager' ) ) );
		}

		// Get data.
		$class_id = isset( $_POST['class_id'] ) ? absint( wp_unslash( $_POST['class_id'] ) ) : 0;
		$date     = isset( $_POST['date'] ) ? sanitize_text_field( wp_unslash( $_POST['date'] ) ) : '';
		$members  = isset( $_POST['members'] ) ? array_map( 'absint', wp_unslash( $_POST['members'] ) ) : array();
		$notes    = isset( $_POST['notes'] ) ? sanitize_textarea_field( wp_unslash( $_POST['notes'] ) ) : '';

		// Validate.
		if ( ! $class_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid class ID.', 'martial-arts-club-manager' ) ) );
		}

		if ( empty( $date ) ) {
			wp_send_json_error( array( 'message' => __( 'Date is required.', 'martial-arts-club-manager' ) ) );
		}

		// Validate date format.
		$date_obj = DateTime::createFromFormat( 'Y-m-d', $date );
		if ( ! $date_obj || $date_obj->format( 'Y-m-d' ) !== $date ) {
			wp_send_json_error( array( 'message' => __( 'Invalid date format.', 'martial-arts-club-manager' ) ) );
		}

		// Get class.
		$class = MACM_Class::get( $class_id );
		if ( ! $class ) {
			wp_send_json_error( array( 'message' => __( 'Class not found.', 'martial-arts-club-manager' ) ) );
		}

		$marked_by     = get_current_user_id();
		$success_count = 0;
		$error_count   = 0;
		$errors        = array();

		// Get all enrolled members for this class.
		$enrollments         = MACM_Class::get_enrolled_members( $class_id );
		$enrolled_member_ids = array();
		foreach ( $enrollments as $enrollment ) {
			$enrolled_member_ids[] = absint( $enrollment->member_id );
		}

		// Get existing attendance records for this date.
		global $wpdb;
		$table_attendance    = $wpdb->prefix . 'macm_attendance';
		$existing_attendance = $wpdb->get_results(
			$wpdb->prepare(
				'SELECT id, member_id FROM %i WHERE class_id = %d AND attendance_date = %s',
				$table_attendance,
				$class_id,
				$date
			)
		);

		// Build a map of member_id => record for easy lookup.
		$existing_attendance_map = array();
		$existing_member_ids     = array();
		foreach ( $existing_attendance as $record ) {
			$member_id_int                             = absint( $record->member_id );
			$existing_attendance_map[ $member_id_int ] = $record;
			$existing_member_ids[]                     = $member_id_int;
		}

		// Mark attendance for selected members (create if not exists).
		foreach ( $members as $member_id ) {
			if ( ! in_array( $member_id, $enrolled_member_ids, true ) ) {
				$member   = MACM_Member::get( $member_id );
				$errors[] = sprintf(
					/* translators: %s: member name */
					__( '%s is not enrolled in this class.', 'martial-arts-club-manager' ),
					$member ? $member->full_name : "Member #{$member_id}"
				);
				++$error_count;
				continue;
			}

			// Only create new record if it doesn't exist.
			if ( ! in_array( $member_id, $existing_member_ids, true ) ) {
				$result = MACM_Attendance::mark( $member_id, $class_id, $date, $marked_by, $notes );

				if ( is_wp_error( $result ) ) {
					$member   = MACM_Member::get( $member_id );
					$errors[] = sprintf(
						/* translators: 1: member name, 2: error message */
						__( 'Failed to mark attendance for %1$s: %2$s', 'martial-arts-club-manager' ),
						$member ? $member->full_name : "Member #{$member_id}",
						$result->get_error_message()
					);
					++$error_count;
				} else {
					++$success_count;
				}
			} else {
				// Already exists, count as success (no action needed).
				++$success_count;
			}
		}

		// Remove attendance for members who are unchecked but have existing records.
		$members_to_remove = array_diff( $existing_member_ids, $members );
		foreach ( $members_to_remove as $member_id ) {
			if ( isset( $existing_attendance_map[ $member_id ] ) ) {
				$delete_result = $wpdb->delete(
					$table_attendance,
					array(
						'id' => $existing_attendance_map[ $member_id ]->id,
					),
					array( '%d' )
				);

				if ( false === $delete_result ) {
					$member   = MACM_Member::get( $member_id );
					$errors[] = sprintf(
						/* translators: %s: member name */
						__( 'Failed to remove attendance for %s.', 'martial-arts-club-manager' ),
						$member ? $member->full_name : "Member #{$member_id}"
					);
					++$error_count;
				}
			}
		}

		// Prepare response message.
		$message       = '';
		$removed_count = count( $members_to_remove );

		if ( $success_count > 0 ) {
			$message = sprintf(
				/* translators: %d: number of members */
				_n(
					'Attendance marked for %d member.',
					'Attendance marked for %d members.',
					$success_count,
					'martial-arts-club-manager'
				),
				$success_count
			);
		} elseif ( $removed_count > 0 && empty( $members ) ) {
			// All members were removed (zero attendance).
			$message = __( 'All attendance records removed for this date.', 'martial-arts-club-manager' );
		}

		if ( $removed_count > 0 && $success_count > 0 ) {
			// Some members added, some removed.
			if ( ! empty( $message ) ) {
				$message .= ' ';
			}
			$message .= sprintf(
				/* translators: %d: number of members removed */
				_n(
					'%d member removed.',
					'%d members removed.',
					$removed_count,
					'martial-arts-club-manager'
				),
				$removed_count
			);
		}

		if ( $error_count > 0 ) {
			if ( ! empty( $message ) ) {
				$message .= ' ';
			}
			$message .= sprintf(
				/* translators: %d: number of errors */
				_n(
					'%d error occurred.',
					'%d errors occurred.',
					$error_count,
					'martial-arts-club-manager'
				),
				$error_count
			);
		}

		wp_send_json_success(
			array(
				'message'       => $message,
				'success_count' => $success_count,
				'error_count'   => $error_count,
				'errors'        => $errors,
			)
		);
	}
}

// Initialize.
new MACM_Class_Register();
