<?php

/**
 * Result Management System for Institutions
 *
 * Copyright (C) 2025 ASTGD
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

/**
 * This file is part of the Result Management System for Institutions plugin.
 *
 * It ensures that the file is not accessed directly by checking if the ABSPATH constant is defined.
 * If ABSPATH is not defined, the script exits.
 *
 * @package ASTGD_Result_Management
 */
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class ASTGDRMSYS_Class_Manager
 *
 * This class is responsible for managing class-related functionalities within the plugin.
 * It provides methods to handle various operations related to classes.
 *
 * @package ResultManagementSystem
 * @subpackage MenuFiles
 */
class ASTGDRMSYS_Class_Manager {

	private $wpdb;
	private $prefix;
	private $messages = array();

	/**
	 * Constructor for the class.
	 *
	 * @param \wpdb $wpdb WordPress database abstraction object.
	 */
	public function __construct( \wpdb $wpdb ) {
		$this->wpdb   = $wpdb;
		$this->prefix = $this->wpdb->prefix;

		$this->handle_form_submission();
	}

	/**
	 * Handles the form submission process.
	 *
	 * This private method processes the form submission, including validation,
	 * sanitization, and any other necessary actions to handle the submitted data.
	 *
	 * @return void
	 */
	private function handle_form_submission() {
		// Check if this is a POST request
		if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'POST' ) {
			// Verify nonce with proper sanitization
			if ( ! isset( $_POST['astgdrmsys_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['astgdrmsys_nonce'] ) ), 'astgdrmsys_class_action' ) ) {
				wp_die(
					esc_html__( 'Invalid nonce specified', 'result-management-system-for-institutions' ),
					esc_html__( 'Error', 'result-management-system-for-institutions' ),
					array( 'response' => 403 )
				);
			}

			// Handle Add Class
			if ( isset( $_POST['addsubmit'] ) ) {
				$this->add_class();
			}

			// Handle Update Class
			if ( isset( $_POST['updatesubmit'] ) ) {
				$this->update_class();
			}
		}
	}


	/**
	 * Adds a new class to the system.
	 *
	 * This function handles the logic for adding a new class to the system.
	 * It performs necessary validations and saves the class details to the database.
	 *
	 * @return void
	 */
	private function add_class() {
		global $wpdb;
		// Sanitize input
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
		$class_name = isset( $_POST['class'] ) ? sanitize_text_field( wp_unslash( $_POST['class'] ) ) : '';

		// Validate input
		if ( empty( $class_name ) ) {
			$this->add_message( 'error', 'Class name cannot be empty' );
			return;
		}

		// Check for duplicate class
		$existing = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare(
				"SELECT COUNT(*) FROM {$wpdb->prefix}astgdrmsys_class WHERE class = %s",
				$class_name
			)
		);

		// Check if class already exists
		if ( $existing > 0 ) {
			$this->add_message( 'error', 'Class already exists' );
			return;
		}

		// Insert class
		$inserted = $this->wpdb->insert(
			$this->prefix . 'astgdrmsys_class',
			array( 'class' => $class_name ),
			array( '%s' )
		);

		if ( $inserted ) {
			// Redirect to prevent form resubmission
			wp_safe_redirect(
				add_query_arg(
					array(
						'page' => 'astgdrmsys-class',
						'add'  => 'true',
					),
					admin_url( 'admin.php' )
				)
			);
			exit;
		} else {
			$this->add_message( 'error', 'Failed to add class' );
		}
	}

	/**
	 * Updates the class information.
	 *
	 * This function is responsible for updating the details of a class.
	 * It performs necessary validation and updates the class record in the database.
	 *
	 * @return void
	 */
	private function update_class() {
		global $wpdb;
		// Sanitize and validate inputs
        // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$class_id = isset( $_POST['edit_id'] ) ? absint( wp_unslash( $_POST['edit_id'] ) ) : 0;
        // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$class_name = isset( $_POST['updateclass'] ) ? sanitize_text_field( wp_unslash( $_POST['updateclass'] ) ) : '';

		// Validate inputs
		if ( empty( $class_name ) ) {
			$this->add_message( 'error', 'Class name cannot be empty' );
			return;
		}

		// Check if class exists
		$existing_class = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare(
				"SELECT * FROM {$wpdb->prefix}astgdrmsys_class WHERE id = %d",
				$class_id
			)
		);

		// Show error if class not found
		if ( ! $existing_class ) {
			$this->add_message( 'error', 'Class not found' );
			return;
		}

		// Check for duplicate class
		$duplicate = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare(
				"SELECT COUNT(*) FROM {$wpdb->prefix}astgdrmsys_class WHERE class = %s AND id != %d",
				$class_name,
				$class_id
			)
		);

		if ( $duplicate > 0 ) {
			$this->add_message( 'error', 'A class with this name already exists' );
			return;
		}

		// Update class
		$updated = $this->wpdb->update(
			$this->prefix . 'astgdrmsys_class',
			array( 'class' => $class_name ),
			array( 'id' => $class_id ),
			array( '%s' ),
			array( '%d' )
		);

		if ( $updated !== false ) {
			// Redirect to prevent form resubmission
			wp_safe_redirect(
				add_query_arg(
					array(
						'page' => 'astgdrmsys-class',
						'edit' => 'true',
					),
					admin_url( 'admin.php' )
				)
			);
			exit;
		} else {
			$this->add_message( 'error', 'Failed to update class' );
		}
	}

	/**
	 * Adds a message to the system.
	 *
	 * @param string $type The type of the message (e.g., 'error', 'success', 'info').
	 * @param string $message The message content to be added.
	 */
	private function add_message( $type, $message ) {
		$this->messages[] = array(
			'type'    => $type,
			'message' => $message,
		);
	}

	/**
	 * Renders the class page.
	 *
	 * This function is responsible for generating and displaying the class page
	 * within the plugin's menu.
	 *
	 * @return void
	 */
	public function astgdrmsys_render_class_page( $wpdb ) {
		if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'POST' ) {
			if ( ! isset( $_POST['astgdrmsys_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['astgdrmsys_nonce'] ) ), 'astgdrmsys_class_action' ) ) {
				wp_die( esc_html__( 'Security check failed. Please try again.', 'result-management-system-for-institutions' ) );
			}
		}
		// Display any messages
		$this->display_messages();

		// Render the main class list view
		?>
		<div class='classcontainer astgdrmsys-premium-wrap px-1'>
		<div class="premium-page-header">
			<div class="page-header-text">
				<h1>Manage Classes</h1>
				<p>View and organize all classes for your institution.</p>
			</div>
			<div class="page-header-actions">
				<button onclick="document.getElementById('addmodal').style.display='block'" class="hero-btn primary-btn"><i class="dashicons dashicons-plus"></i> Add Class</button>
			</div>
		</div>
			<?php $this->astgdrmsys_render_class_list( $wpdb ); ?>
			<?php $this->astgdrmsys_render_add_class_modal(); ?>
		</div>
		<?php
	}

	/**
	 * Displays messages to the user.
	 *
	 * This function is responsible for rendering any messages that need to be
	 * displayed to the user. It handles the formatting and output of these
	 * messages.
	 *
	 * @return void
	 */
	private function display_messages() {
		// Handle URL-based messages
		$message_types = array(
			'edit' => 'Class Updated Successfully',
			'del'  => 'Class Deleted Successfully',
			'add'  => 'Class Added Successfully',
		);

		foreach ( $message_types as $type => $msg ) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
			if ( isset( $_GET[ $type ] ) && $_GET[ $type ] === 'true' ) {
				$this->add_message( 'success', $msg );
			}
		}

		// Display all messages
		foreach ( $this->messages as $message ) {
			printf(
				'<div class="notice notice-%s is-dismissible"><p>%s</p></div>',
				esc_attr( $message['type'] ),
				esc_html( $message['message'] )
			);
		}
	}

	/**
	 * Renders the list of classes.
	 *
	 * This private function is responsible for generating and displaying
	 * the list of classes in the plugin's admin interface.
	 *
	 * @return void
	 */
	private function astgdrmsys_render_class_list( $wpdb ) {
		// Fetch classes
		$table = esc_sql( $wpdb->prefix . 'astgdrmsys_class' );
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$classes = $wpdb->get_results(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			"SELECT id, class FROM $table ORDER BY class ASC",
			ARRAY_A
		);

		if ( ! empty( $classes ) ) {
			?>
			<table class="styled-table">
				<thead>
					<tr>
						<th scope="col">Class ID</th>
						<th scope="col">Class Name</th>
						<th scope="col">Action</th>
					</tr>
				</thead>
				<tbody>
					<?php
					foreach ( $classes as $class ) :
						// Convert $class to array if it's an object
						if ( is_object( $class ) ) {
							$class = (array) $class;
						}
						$cache_key = wp_create_nonce( 'astgdrmsys_class_action' );
						?>
						<tr>
							<td><?php echo esc_html( $class['id'] ); ?></td>
							<td><strong><?php echo esc_html( $class['class'] ); ?></strong></td>
							<td>
								<a href="
								<?php
								echo esc_url(
									add_query_arg(
										array(
											'page'   => 'astgdrmsys-class',
											'editid' => $class['id'],
											'astgdrmsys_nonce' => $cache_key,
										),
										admin_url( 'admin.php' )
									)
								);
								?>
											"
									class="button button-small">
									<span class="dashicons dashicons-edit"></span>
								</a>
								<a href="
								<?php
								echo esc_url(
									add_query_arg(
										array(
											'page'  => 'astgdrmsys-class',
											'delid' => $class['id'],
											'astgdrmsys_nonce' => $cache_key,
										),
										admin_url( 'admin.php' )
									)
								);
								?>
											"
									onclick="return confirm('Do you really want to delete this class? This will delete all related subjects and student records.');"
									class="button button-small button-link-delete">
									<span class="dashicons dashicons-trash"></span>
								</a>
							</td>
						</tr>
					<?php endforeach; ?>
				</tbody>
			</table>
			<?php
		} else {
			?>
			<div class="notice notice-warning">
				<p>No Classes Added</p>
			</div>
			<?php
		}
	}

	/**
	 * Renders the modal for adding a new class.
	 *
	 * This function generates the HTML and necessary scripts for displaying
	 * a modal dialog that allows users to add a new class.
	 *
	 * @return void
	 */
	private function astgdrmsys_render_add_class_modal() {
		?>
		<div id="addmodal" class="modal">
			<div class="modal-content">
				<span class="close close-class-modal">&times;</span>
				<h2>Add Class</h2>
				<form method="post" action="">
					<?php wp_nonce_field( 'astgdrmsys_class_action', 'astgdrmsys_nonce' ); ?>
					<div class="form-field">
						<label for="class">Class Name:</label>
						<input type='text' name='class' id="class" required class="regular-text">
					</div>
					<div class="button-group">
						<?php submit_button( 'Add Class', 'primary', 'addsubmit' ); ?>
						<button type="button" class="button cancel-button">
							Cancel
						</button>
					</div>
				</form>
			</div>
		</div>
		<?php
	}

	/**
	 * Renders the form to edit a class.
	 *
	 * @param int $class_id The ID of the class to be edited.
	 */
	public function astgdrmsys_render_edit_class_form( $class_id, $wpdb ) {

		// Fetch the specific class
		$class = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare(
				"SELECT * FROM {$wpdb->prefix}astgdrmsys_class WHERE id = %d",
				$class_id
			),
			ARRAY_A
		);

		// Show error if class not found
		if ( ! $class ) {
			wp_die( 'Class not found' );
		}
		?>
		<div class='container'>
			<h3 class='heading text-center'>Edit Class</h3>
			<form method='post' action=''>
				<?php wp_nonce_field( 'astgdrmsys_class_action', 'astgdrmsys_nonce' ); ?>
				<input type="hidden" name="edit_id" value="<?php echo esc_attr( $class_id ); ?>">
				<table class='table'>
					<tr>
						<td><strong>Enter Class Name:</strong></td>
						<td>
							<input type='text' name='updateclass'
								value='<?php echo esc_attr( $class['class'] ); ?>'
								required class="regular-text">
						</td>
					</tr>
					<tr>
						<td>
							<?php submit_button( 'Update', 'primary', 'updatesubmit' ); ?>
						</td>
						<td>
							<button type="button"
								class="btn btn-danger ml-2"
								onclick="window.history.back();"><?php esc_html_e( 'Cancel', 'result-management-system-for-institutions' ); ?>
							</button>
						</td>
					</tr>
				</table>
			</form>
		</div>
		<?php
	}

			/**
			 * Deletes a class based on the provided class ID.
			 *
			 * @param int $class_id The ID of the class to be deleted.
			 * @return void
			 */
	public function delete_class( $class_id ) {
		// Start transaction
		$this->wpdb->query( 'START TRANSACTION' );

		try {
			// Delete class and related records
			$tables = array(
				'astgdrmsys_class'          => 'id',
				'astgdrmsys_subject'        => 'class',
				'astgdrmsys_student_result' => 'class',
			);

			foreach ( $tables as $table => $column ) {
				$this->wpdb->delete(
					$this->prefix . $table,
					array( $column => $class_id ),
					array( '%d' )
				);
			}

			$this->wpdb->query( 'COMMIT' );
			wp_safe_redirect(
				add_query_arg(
					array(
						'page' => 'astgdrmsys-class',
						'del'  => 'true',
					),
					admin_url( 'admin.php' )
				)
			);
			exit;
		} catch ( \Exception $e ) {
			$this->wpdb->query( 'ROLLBACK' );
			$this->add_message( 'error', 'Error deleting class: ' . $e->getMessage() );
		}
	}
}

/**
 * Initializes the class manager.
 *
 * This function sets up the necessary configurations and dependencies
 * required for managing classes within the plugin.
 *
 * @return void
 */
function astgdrmsys_initialize_class_manager() {
	global $wpdb;
	$class_manager = new ASTGDRMSYS_Class_Manager( $wpdb );

	// Nonce verification for POST requests
	if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'POST' ) {
		check_admin_referer( 'astgdrmsys_class_action', 'astgdrmsys_nonce' );
	}

	// Handle deletion if delid is set and nonce is verified
	if ( isset( $_GET['delid'], $_GET['astgdrmsys_nonce'] ) ) {
		// sanitize and validate delid
		$delid = isset( $_GET['delid'] ) ? absint( $_GET['delid'] ) : 0;
		$nonce = isset( $_GET['astgdrmsys_nonce'] ) ? sanitize_text_field( wp_unslash( $_GET['astgdrmsys_nonce'] ) ) : '';

		if ( wp_verify_nonce( $nonce, 'astgdrmsys_class_action' ) && current_user_can( 'manage_options' ) ) {
			$class_manager->delete_class( $delid );
		} else {
			wp_die( esc_html__( 'Unauthorized deletion attempt.', 'result-management-system-for-institutions' ) );
		}
		return;
	}

	// Handle editing if editid is set and nonce is verified
	if ( isset( $_GET['editid'], $_GET['astgdrmsys_nonce'] ) && $_GET['editid'] !== '' ) {
		// sanitize and validate editid
		$editid = isset( $_GET['editid'] ) ? absint( $_GET['editid'] ) : 0;
		$nonce  = isset( $_GET['astgdrmsys_nonce'] ) ? sanitize_text_field( wp_unslash( $_GET['astgdrmsys_nonce'] ) ) : '';

		// Verify nonce and user capability
		if ( wp_verify_nonce( $nonce, 'astgdrmsys_class_action' ) && current_user_can( 'manage_options' ) ) {
			$class_manager->astgdrmsys_render_edit_class_form( $editid, $wpdb );
		} else {
			wp_die( esc_html__( 'Unauthorized edit attempt.', 'result-management-system-for-institutions' ) );
		}
		return;
	}

	// Render main class list
	$class_manager->astgdrmsys_render_class_page( $wpdb );
}

/**
 * Initializes the class manager for the plugin.
 *
 * This function is responsible for setting up the necessary components
 * and configurations required for managing classes within the plugin.
 *
 * @file your-site-location/wp-content/plugins/astgdrmsys-result-management/menu-files/class/add-class.php
 */
astgdrmsys_initialize_class_manager();
