<?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 being accessed through WordPress by checking if the ABSPATH constant is defined.
 * If ABSPATH is not defined, it exits the script to prevent direct access.
 *
 * @package ResultManagementSystem
 * @subpackage Menu_Files/All_Students
 */
if (! defined('ABSPATH')) {
	exit;
}

require_once ASTGDRMSYS_PLUGIN_DIR . 'includes/traits/class-astgdrmsys-retake-helper.php';

// Include WordPress database access
global $wpdb;

/**
 * Class ASTGDRMSYS_All_Students
 *
 * This class handles the functionality related to displaying and managing all students.
 *
 * @package ResultManagementSystem
 * @subpackage MenuFiles
 * @since 1.0.0
 */
class ASTGDRMSYS_All_Students
{
	use ASTGDRMSYS_Retake_Helper;

	private $wpdb;
	private $prefix;
	private $limit = 15;

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

		$this->handleMessages();
		$this->handleExport($wpdb);

		// Display the students table
		$this->displayStudents();
	}

	/**
	 * Handles the messages for the all-students page.
	 *
	 * This function processes and manages the messages that are displayed or handled
	 * on the all-students page within the Result Management System for Institutions plugin.
	 *
	 * @return void
	 */
	private function handleMessages()
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['del']) && $_GET['del'] == 'true') {
			$this->displayMessage('Student Record Deleted Successfully');
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['edit']) && $_GET['edit'] == 'true') {
			$this->displayMessage('Student Record Updated Successfully');
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['csv']) && $_GET['csv'] == 'imported') {
			$this->displayMessage('CSV File Imported Successfully');
		}
	}

	/**
	 * Displays a message.
	 *
	 * @param string $message The message to be displayed.
	 */
	private function displayMessage($message)
	{
		echo "
        <div id='message_div' class='alert alert-success'>
        <center>" . esc_html($message) . "</center>
        <button class='close-message' onclick='this.parentElement.style.display=\"none\";'>&times;</button>
        </div>";
	}

	/**
	 * Handles the export functionality for the all-students page.
	 *
	 * This function is responsible for managing the export process of student data.
	 *
	 * @return void
	 */
	private function handleExport($wpdb)
	{
		// phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fclose
		if (isset($_POST['export'])) {
			// Verify nonce for security
			check_admin_referer('export_action', 'export_nonce');

			header('Content-Type: text/csv; charset=utf-8');
			header('Content-Disposition: attachment; filename=astgdrmsys-all-students.csv');
			$output = fopen('php://output', 'w');
			ob_end_clean();

			$studentcolumns = $this->getStudentColumns();
			fputcsv($output, $studentcolumns);

			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery
			// Safe table name sanitization
			$table_name = esc_sql($this->prefix . 'astgdrmsys_student_result');
			$sql        = "SELECT * FROM `$table_name`";

			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery
			$students = $wpdb->get_results($sql, ARRAY_A);

			foreach ($students as $student) {
				$row = $this->prepareStudentRow($student, $this->wpdb);
				fputcsv($output, $row);
			}
			fclose($output);
			exit();
		}
	}

	/**
	 * Retrieves the columns for the student list.
	 *
	 * This function returns an array of columns to be displayed in the student list.
	 *
	 * @return array An associative array where the keys are column identifiers and the values are column titles.
	 */
	private function getStudentColumns()
	{
		// Get base student columns
		$query = $this->wpdb->prepare(
			'SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME = %s AND TABLE_SCHEMA = %s',
			$this->prefix . 'astgdrmsys_student_result',
			$this->wpdb->dbname
		);

		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		$columns        = $this->wpdb->get_results($query, ARRAY_A);
		$studentcolumns = array_column($columns, 'COLUMN_NAME');

		// Remove 'sid' column
		$key = array_search('sid', $studentcolumns);
		if ($key !== false) {
			unset($studentcolumns[$key]);
		}

		$subject_table = esc_sql($this->wpdb->prefix . 'astgdrmsys_subject');
		$sql           = "SELECT subname FROM `$subject_table`";

		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
		$subjects = $this->wpdb->get_results($sql, ARRAY_A);

		// Add subject columns
		foreach ($subjects as $subject) {
			$studentcolumns[] = $subject['subname'];
		}

		return $studentcolumns;
	}

	/**
	 * Prepares a row of student data for display.
	 *
	 * @param array $student An associative array containing student data.
	 *
	 * @return array The prepared student row data.
	 */
	private function prepareStudentRow($student, $wpdb)
	{
		// Remove 'sid' from the student array
		if (isset($student['sid'])) {
			unset($student['sid']);
		}

		// Fetch detailed information for various fields
		$class_table      = esc_sql($wpdb->prefix . 'astgdrmsys_class');
		$department_table = esc_sql($wpdb->prefix . 'astgdrmsys_department');
		$section_table    = esc_sql($wpdb->prefix . 'astgdrmsys_section');
		$exam_name_table  = esc_sql($wpdb->prefix . 'astgdrmsys_exam_name');
		$exam_year_table  = esc_sql($wpdb->prefix . 'astgdrmsys_exam_year');
		$subject_table    = esc_sql($wpdb->prefix . 'astgdrmsys_subject');

		// // Fetch detailed names
		//phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$class = $wpdb->get_var(
			$wpdb->prepare(
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"SELECT class FROM $class_table WHERE id = %d",
				intval($student['class'])
			)
		);

		//phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$department = $wpdb->get_var(
			$wpdb->prepare(
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"SELECT department FROM $department_table WHERE id = %d",
				intval($student['department'])
			)
		);

		//phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$section = $wpdb->get_var(
			$wpdb->prepare(
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"SELECT section FROM $section_table WHERE id = %d",
				intval($student['section'])
			)
		);

		//phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$exam_name = $wpdb->get_var(
			$wpdb->prepare(
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"SELECT exam_name FROM $exam_name_table WHERE id = %d",
				intval($student['exam_name'])
			)
		);

		//phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$exam_year = $wpdb->get_var(
			$wpdb->prepare(
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"SELECT exam_year FROM $exam_year_table WHERE id = %d",
				intval($student['exam_year'])
			)
		);

		// Replace IDs with actual names in the student array
		$student['class']      = $class;
		$student['section']    = $section;
		$student['department'] = $department;
		$student['exam_name']  = $exam_name;
		$student['exam_year']  = $exam_year;

		// Get student marks
		$marks = $this->getStudentMarks($student['sno'], $this->wpdb);

		// If marks is a nested array, use the first element
		$processedMarks = is_array($marks) && isset($marks[0]) && is_array($marks[0])
			? $marks[0]
			: $marks;

		// Fetch all subjects
		//phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$subjects = $wpdb->get_results(
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			"SELECT subcode, subname FROM $subject_table",
			ARRAY_A
		);

		// Add subject marks to the row
		foreach ($subjects as $subject) {
			$subcode = $subject['subcode'];
			$subname = $subject['subname'];

			// Check if this subject's code exists in marks
			$mark = isset($processedMarks[$subcode]) ? $processedMarks[$subcode] : 'N/A';

			// Add subject name and its mark to the row
			$student[$subname] = is_array($mark) ? implode(', ', $mark) : $mark;
		}

		return $student;
	}

	/**
	 * Retrieves the marks for a specific student.
	 *
	 * @param int $sid The ID of the student whose marks are to be retrieved.
	 * @return array An array containing the student's marks.
	 */
	private function getStudentMarks($sid, $wpdb)
	{
		$mark_table = esc_sql($wpdb->prefix . 'astgdrmsys_mark');
		//phpcs:ignore WordPress.DB.DirectDatabaseQuery
		$markData = $wpdb->get_var(
			$wpdb->prepare(
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"SELECT marks FROM $mark_table WHERE sid = %d",
				intval($sid)
			)
		);
		$marks = $markData ? maybe_unserialize($markData) : array();
		return is_array($marks) ? $marks : array();
	}

	/**
	 * Displays the list of all students.
	 *
	 * This function retrieves and displays the information of all students.
	 * It is used in the context of the 'all-students' menu in the RMS Result Management plugin.
	 *
	 * @return void
	 */
	private function displayStudents()
	{
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                $page   = isset($_GET['paginate']) ? (int) $_GET['paginate'] : 1;
                $offset = ($page - 1) * $this->limit;

                $filters = $this->getFiltersFromRequest();

                $students       = $this->getStudents($offset, $filters);
                $total_students = $this->getTotalStudents($filters);

                $this->renderPage($students, $total_students, $page, $filters);
        }

	/**
	 * Retrieves a list of students with pagination.
	 *
	 * @param int $offset The offset for pagination.
	 * @return array The list of students.
	 */
        private function getStudents($offset, array $filters)
        {
                global $wpdb;

                $offset = (int) $offset;
                $limit  = (int) $this->limit;

                $table_name = esc_sql($this->prefix . 'astgdrmsys_student_result');

                $where_clauses = array();
                $parameters    = array();

                if (! empty($filters['class'])) {
                        $where_clauses[] = '`class` = %d';
                        $parameters[]    = (int) $filters['class'];
                }

                if (! empty($filters['department'])) {
                        $where_clauses[] = '`department` = %d';
                        $parameters[]    = (int) $filters['department'];
                }

                if (! empty($filters['section'])) {
                        $where_clauses[] = '`section` = %d';
                        $parameters[]    = (int) $filters['section'];
                }

                if (! empty($filters['exam'])) {
                        $where_clauses[] = '`exam_name` = %d';
                        $parameters[]    = (int) $filters['exam'];
                }

                if ($filters['regno'] !== '') {
                        $where_clauses[] = '`regno` LIKE %s';
                        $parameters[]    = '%' . $wpdb->esc_like($filters['regno']) . '%';
                }

                if ($filters['roll'] !== '') {
                        $where_clauses[] = '`sno` LIKE %s';
                        $parameters[]    = '%' . $wpdb->esc_like($filters['roll']) . '%';
                }

                $where_sql = '';

                if (! empty($where_clauses)) {
                        $where_sql = 'WHERE ' . implode(' AND ', $where_clauses);
                }

                $sql = "SELECT * FROM `{$table_name}` {$where_sql} ORDER BY CAST(`sno` AS UNSIGNED) LIMIT %d, %d";

                $parameters[] = $offset;
                $parameters[] = $limit;

                // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
                $query = $wpdb->prepare($sql, $parameters);

                $cache_key = 'students_filtered_' . md5(maybe_serialize(array($offset, $limit, $filters)));

                $students = wp_cache_get($cache_key, 'rms');

                if (false === $students) {
                        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery
                        $students = $wpdb->get_results($query, ARRAY_A);
                        wp_cache_set($cache_key, $students, 'rms', 300); // Cache for 5 minutes
                }

                return $students;
        }

	/**
	 * Retrieves the total number of students.
	 *
	 * @return int The total number of students.
	 */
        private function getTotalStudents(array $filters)
        {
                $table_name = esc_sql($this->prefix . 'astgdrmsys_student_result');
                $where_clauses = array();
                $parameters    = array();

                if (! empty($filters['class'])) {
                        $where_clauses[] = '`class` = %d';
                        $parameters[]    = (int) $filters['class'];
                }

                if (! empty($filters['department'])) {
                        $where_clauses[] = '`department` = %d';
                        $parameters[]    = (int) $filters['department'];
                }

                if (! empty($filters['section'])) {
                        $where_clauses[] = '`section` = %d';
                        $parameters[]    = (int) $filters['section'];
                }

                if (! empty($filters['exam'])) {
                        $where_clauses[] = '`exam_name` = %d';
                        $parameters[]    = (int) $filters['exam'];
                }

                if ($filters['regno'] !== '') {
                        $where_clauses[] = '`regno` LIKE %s';
                        $parameters[]    = '%' . $this->wpdb->esc_like($filters['regno']) . '%';
                }

                if ($filters['roll'] !== '') {
                        $where_clauses[] = '`sno` LIKE %s';
                        $parameters[]    = '%' . $this->wpdb->esc_like($filters['roll']) . '%';
                }

                $where_sql = '';
                if (! empty($where_clauses)) {
                        $where_sql = 'WHERE ' . implode(' AND ', $where_clauses);
                }

                $sql = "SELECT COUNT(*) FROM `{$table_name}` {$where_sql}";

                if (empty($parameters)) {
                        $query = $sql;
                } else {
                        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
                        $query = $this->wpdb->prepare($sql, $parameters);
                }

                $cache_key = 'students_filtered_total_' . md5(maybe_serialize($filters));

                $cached_total = wp_cache_get($cache_key, 'rms');

                if (false !== $cached_total) {
                        return (int) $cached_total;
                }

                // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
                $total = (int) $this->wpdb->get_var($query);
                wp_cache_set($cache_key, $total, 'rms', 300);

                return $total;
        }

	/**
	 * Renders the page displaying all students.
	 *
	 * @param array $students Array of student data.
	 * @param int   $total_students Total number of students.
	 * @param int   $page Current page number.
	 */
        private function renderPage($students, $total_students, $page, array $filters)
        {
                $total_pages        = ceil($total_students / $this->limit);
                $class_options      = $this->getClassOptions();
                $department_options = $this->getDepartmentOptions($filters['class']);
                $exam_options       = $this->getExamOptions($filters['class'], $filters['department']);
                $section_options    = $this->getSectionOptions($filters['department']); ?>
                <div id='print' class="astgdrmsys-premium-wrap">

                        <div class="premium-page-header">
				<div class="page-header-text">
					<h1><?php esc_html_e('Exam Result Records', 'result-management-system-for-institutions'); ?></h1>
					<p><?php esc_html_e('View and manage all student records.', 'result-management-system-for-institutions'); ?></p>
				</div>
			</div>
                        <center>
                                <div class="student-actions-container">
                                        <div class="action-row">
                                                <form action="" method="post" class="export-form">
                                                        <?php wp_nonce_field('export_action', 'export_nonce'); ?>
                                                        <button type="submit" class="btn btn-export" name="export">
                                                                <i class="dashicons dashicons-download"></i> <?php esc_html_e('Export CSV', 'result-management-system-for-institutions'); ?>
                                                        </button>
                                                </form>

                                                <div class="filter-form-container">
                                                        <?php $this->renderFilterForm($filters, $class_options, $department_options, $exam_options, $section_options); ?>
                                                </div>
                                        </div>

                                        <div class="student-count-banner">
                                                <span class="student-count-icon">
                                                        <i class="dashicons dashicons-groups"></i>
                                                </span>
                                                <span class="student-count-text">
                                                        <?php
                                                        $count_label = $this->hasActiveFilters($filters) ? __('Result Records Matched', 'result-management-system-for-institutions') : __('Exam Result Records', 'result-management-system-for-institutions');
                                                        echo esc_html($total_students . ' ' . $count_label);
                                                        ?>
                                                </span>
                                        </div>
                                </div>


                                <table class="styled-table" id="student-table">
                                        <tr>
                                                <th class="student-id">
                                                        <center><?php esc_html_e('ID', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th>
                                                        <center><?php esc_html_e('Photo', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th>
                                                        <center><?php esc_html_e('Roll Number', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th>
                                                        <center><?php esc_html_e('Registration Number', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th>
                                                        <center><?php esc_html_e('Student Name', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th>
                                                        <center><?php esc_html_e('Class', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th>
                                                        <center><?php esc_html_e('Department', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th>
                                                        <center><?php esc_html_e('Section', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th>
                                                        <center><?php esc_html_e('Exam Name', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th>
                                                        <center><?php esc_html_e('Exam Year', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th>
                                                        <center><?php esc_html_e('Total Marks', 'result-management-system-for-institutions'); ?></center>
                                                </th>
                                                <th id='paddingaction'><?php esc_html_e('Action', 'result-management-system-for-institutions'); ?></th>
                                        </tr>
                                        <?php
                                        if (count($students) > 0) {
                                                foreach ($students as $index => $student) {
                                                        $this->renderStudentRow($student, $index + 1 + ($page - 1) * $this->limit, $this->wpdb);
                                                }
                                        } else {
                                                echo '<h2>' . esc_html__('No records found for the selected filters.', 'result-management-system-for-institutions') . '</h2>';
                                                echo '<center><a class="btn btn-primary" href="' . esc_url(admin_url('admin.php?page=astgdrmsys-all-students')) . '">' . esc_html__('See All Students', 'result-management-system-for-institutions') . '</a></center>';
                                        }
                                        ?>
                                </table>
                        </center>
                </div>
                <div id="pagination">
                        <?php $this->renderPagination($total_pages, $page, $filters); ?>
                </div> <?php
        }

	/**
	 * Renders a row for a student in the table.
	 *
	 * @param array $student An associative array containing student data.
	 * @param int   $id The ID of the student.
	 */
	private function renderStudentRow($student, $id, $wpdb)
	{
		// Convert $student to array if it's an object
		if (is_object($student)) {
			$student = (array) $student;
		}

		$class = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare("SELECT `class` FROM `{$wpdb->prefix}astgdrmsys_class` WHERE `id` = %d", intval($student['class']))
		);

		$department = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare("SELECT `department` FROM `{$wpdb->prefix}astgdrmsys_department` WHERE `id` = %d", intval($student['department']))
		);

		$section = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare("SELECT `section` FROM `{$wpdb->prefix}astgdrmsys_section` WHERE `id` = %d", intval($student['section']))
		);

		$exam_name = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare("SELECT `exam_name` FROM `{$wpdb->prefix}astgdrmsys_exam_name` WHERE `id` = %d", intval($student['exam_name']))
		);

		$exam_year = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$wpdb->prepare("SELECT `exam_year` FROM `{$wpdb->prefix}astgdrmsys_exam_year` WHERE `id` = %d", intval($student['exam_year']))
		);

		// Determine the exam_type
		$exam_type = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT exam_type FROM {$wpdb->prefix}astgdrmsys_exam_name WHERE id = %d",
				intval($student['exam_name'])
			)
		);

		// Fetch Marks
		$marks = $this->getStudentMarks($student['sid'], $this->wpdb);
		
		// Initialize $total_marks
		$total_marks = 0;
		
		// --- Data Normalization (Handles old, inconsistent 'single' type data) ---
		// If marks are weirdly nested in an array with key 0, extract the actual marks array.
		if (isset($marks[0]) && is_array($marks[0])) {
			$marks = $marks[0];
		}

		$marks = $this->apply_retake_marks_to_marks($student['sid'], is_array($marks) ? $marks : array());
		
		// --- Main Calculation Loop ---
		// A single loop that handles all cases is cleaner and more efficient.
		if (is_array($marks)) {
			foreach ($marks as $subject_code => $subject_mark) {
				if (is_array($subject_mark)) {
					if (! empty($subject_mark['not_taken'])) {
						continue;
					}

					if (isset($subject_mark['final_counted_mark']) && is_numeric($subject_mark['final_counted_mark'])) {
						$total_marks += floatval($subject_mark['final_counted_mark']);
						continue;
					}

					if (isset($subject_mark['total']) && is_numeric($subject_mark['total'])) {
						$total_marks += floatval($subject_mark['total']);
						continue;
					}
				}
				
				// For 'triple' and 'composite' types, the total is pre-calculated and stored.
				if ($exam_type === 'triple' || $exam_type === 'composite') {
					// We safely check if the mark is an array and has a 'total' key.
					if (is_array($subject_mark) && isset($subject_mark['total'])) {
						$total_marks += floatval($subject_mark['total']);
					}
				} 
				// For 'single' type, the mark itself is the value to add.
				elseif ($exam_type === 'single') {
					if (is_array($subject_mark) && isset($subject_mark['final'])) {
						 $total_marks += floatval($subject_mark['final']);
					} elseif (is_numeric($subject_mark)) {
						 $total_marks += floatval($subject_mark);
					}
				}
			}
		}

		$nonce_key = wp_create_nonce('get_id_nonce'); 
		 // ==================== THIS IS THE FIX ====================
    // Create a specific nonce for the delete action
    $delete_nonce = wp_create_nonce('astgdrmsys_delete_record');
    // =======================================================
		?>
		<tr>
			<td class='padding student-id'>
				<center><?php echo esc_html($id); ?></center>
			</td>
			<td class="padding">
				<?php
				$gender = !empty($student['gender']) ? strtoupper($student['gender']) : 'OTHER';
				$student_image_url = ! empty( $student['student_image'] ) ? esc_url( $student['student_image'] ) : '';
			
				if ( $gender === 'MALE' ) {
					$default_avatar_url = ASTGDRMSYS_PLUGIN_URL . 'images/default-student-image/default-male-student.png';
				} elseif ( $gender === 'FEMALE' ) {
					$default_avatar_url = ASTGDRMSYS_PLUGIN_URL . 'images/default-student-image/default-female-student.png';
				} else {
					$default_avatar_url = ASTGDRMSYS_PLUGIN_URL . 'images/default-student-image/default-other-student.png';
				}
			
				$final_image_url = $student_image_url ? $student_image_url : $default_avatar_url;
				?>
				<center>
					<img src="<?php echo $final_image_url; ?>" alt="Student Image" class="student-avatar" draggable="false" />
				</center>
			</td>
			<td class='padding'>
				<center><?php echo esc_html($student['sno']); ?></center>
			</td>
			<td class='padding'>
				<center><?php echo esc_html($student['regno']); ?></center>
			</td>
			<td class='padding'>
				<center><?php echo esc_html($student['name']); ?></center>
			</td>
			<td class='padding'>
				<center><?php echo esc_html($class ?: "Class doesn't exist"); ?></center>
			</td>
			<td class='padding'>
				<center><?php echo esc_html($department ?: "Department doesn't exist"); ?></center>
			</td>
			<td class='padding'>
				<center><?php echo esc_html($section ?: "Section doesn't exist"); ?></center>
			</td>
			<td class='padding'>
				<center><?php echo esc_html($exam_name ?: "Exam Name doesn't exist"); ?></center>
			</td>
			<td class='padding'>
				<center><?php echo esc_html($exam_year ?: "Exam Year doesn't exist"); ?></center>
			</td>
			<td class='padding'>
				<center><?php echo esc_html($total_marks); ?></center>
			</td>
			<td>
				<a href="<?php echo esc_url(admin_url('admin.php?page=astgdrmsys-edit-record&id=' . intval($student['sid']) . '&_wpnonce=' . $nonce_key)); ?>"
					class="button button-small">
					<span class="dashicons dashicons-edit"></span>
				</a>
				<a href='<?php echo esc_url(admin_url('admin.php?page=astgdrmsys-delrec&id=' . intval($student['sid']) . '&_wpnonce=' . $delete_nonce)); ?>'
					onclick="return confirm('<?php esc_attr_e('Do You Really Want to Delete the Record?', 'result-management-system-for-institutions'); ?>');"
					class="button button-small button-link-delete">
					<span class="dashicons dashicons-trash"></span>
				</a>
			</td>
		</tr> <?php
	}

	/**
	 * Renders the pagination for a list of students.
	 *
	 * @param int $total_pages The total number of pages.
	 * @param int $current_page The current page number.
	 */
        private function renderPagination($total_pages, $current_page, array $filters)
        {
                $prev_disabled = $current_page < 2 ? 'disabled' : '';
                $next_disabled = $current_page >= $total_pages ? 'disabled' : '';

                $prev_page = max(1, $current_page - 1);
                $next_page = min($total_pages, $current_page + 1);

                $base_args = $this->buildFilterQueryArgs($filters);

                $first_url = add_query_arg(array_merge($base_args, array('paginate' => 1)), admin_url('admin.php'));
                $prev_url  = add_query_arg(array_merge($base_args, array('paginate' => $prev_page)), admin_url('admin.php'));
                $next_url  = add_query_arg(array_merge($base_args, array('paginate' => $next_page)), admin_url('admin.php'));
                $last_url  = add_query_arg(array_merge($base_args, array('paginate' => $total_pages)), admin_url('admin.php'));
                ?>
                <nav>
                        <ul class="pagination justify-content-center">
                                <!-- First Page -->
                                <li class="page-item <?php echo esc_attr($prev_disabled); ?>">
                                        <a class="page-link" href="<?php echo esc_url($first_url); ?>" aria-label="First">«</a>
                                </li>

                                <!-- Previous Page -->
                                <li class="page-item <?php echo esc_attr($prev_disabled); ?>">
                                        <a class="page-link" href="<?php echo esc_url($prev_url); ?>" aria-label="Previous">‹</a>
                                </li>

                                <!-- Current Page -->
                                <li class="page-item active">
					<a class="page-link" href=""><?php echo esc_html($current_page); ?></a>
				</li>

                                <li class="page-item disabled">
                                        <span class="page-link">of</span>
                                </li>

                                <!-- Total Pages -->
                                <li class="page-item">
                                        <a class="page-link" href="<?php echo esc_url($last_url); ?>">
                                                <?php echo esc_html($total_pages); ?>
                                        </a>
                                </li>

                                <!-- Next Page -->
                                <li class="page-item <?php echo esc_attr($next_disabled); ?>">
                                        <a class="page-link" href="<?php echo esc_url($next_url); ?>" aria-label="Next">›</a>
                                </li>

                                <!-- Last Page -->
                                <li class="page-item <?php echo esc_attr($next_disabled); ?>">
                                        <a class="page-link" href="<?php echo esc_url($last_url); ?>" aria-label="Last">»</a>
                                </li>
                        </ul>
                </nav><?php
        }

        /**
         * Retrieves filter values from the current request.
         *
         * @return array<string, int|string> Filter values keyed by field name.
         */
        private function getFiltersFromRequest(): array
        {
                $filters = array(
                        'class'      => 0,
                        'department' => 0,
                        'exam'       => 0,
                        'section'    => 0,
                        'regno'      => '',
                        'roll'       => '',
                );

                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                if (isset($_GET['class_id'])) {
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                        $filters['class'] = absint(wp_unslash($_GET['class_id']));
                }

                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                if (isset($_GET['department_id'])) {
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                        $filters['department'] = absint(wp_unslash($_GET['department_id']));
                }

                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                if (isset($_GET['exam_id'])) {
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                        $filters['exam'] = absint(wp_unslash($_GET['exam_id']));
                }

                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                if (isset($_GET['section_id'])) {
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                        $filters['section'] = absint(wp_unslash($_GET['section_id']));
                }

                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                if (isset($_GET['regno'])) {
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                        $filters['regno'] = sanitize_text_field(wp_unslash($_GET['regno']));
                }

                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                if (isset($_GET['roll'])) {
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                        $filters['roll'] = sanitize_text_field(wp_unslash($_GET['roll']));
                }

                return $filters;
        }

        /**
         * Determines whether any filter is active.
         *
         * @param array $filters Filter values to inspect.
         *
         * @return bool True if at least one filter is active, false otherwise.
         */
        private function hasActiveFilters(array $filters): bool
        {
                foreach ($filters as $value) {
                        if (is_string($value) && $value !== '') {
                                return true;
                        }

                        if (is_int($value) && $value > 0) {
                                return true;
                        }
                }

                return false;
        }

        /**
         * Builds the base query arguments for pagination links with filters applied.
         *
         * @param array $filters The active filters.
         *
         * @return array<string, int|string> Query arguments for add_query_arg.
         */
        private function buildFilterQueryArgs(array $filters): array
        {
                $args = array('page' => 'astgdrmsys-all-students');

                if (! empty($filters['class'])) {
                        $args['class_id'] = (int) $filters['class'];
                }

                if (! empty($filters['department'])) {
                        $args['department_id'] = (int) $filters['department'];
                }

                if (! empty($filters['exam'])) {
                        $args['exam_id'] = (int) $filters['exam'];
                }

                if (! empty($filters['section'])) {
                        $args['section_id'] = (int) $filters['section'];
                }

                if ($filters['regno'] !== '') {
                        $args['regno'] = $filters['regno'];
                }

                if ($filters['roll'] !== '') {
                        $args['roll'] = $filters['roll'];
                }

                return $args;
        }

        /**
         * Outputs the filter form used on the All Students page.
         *
         * @param array $filters            Current filter values.
         * @param array $class_options      Available class options.
         * @param array $department_options Available department options.
         * @param array $exam_options       Available exam options.
         * @param array $section_options    Available section options.
         *
         * @return void
         */
        private function renderFilterForm(array $filters, array $class_options, array $department_options, array $exam_options, array $section_options)
        {
                ?>
                <form method="get" action="" class="filter-form">
                        <input type="hidden" name="page" value="astgdrmsys-all-students">
                        <div class="filter-grid">
                                <div class="filter-field">
                                        <label for="filter-class" class="filter-label"><?php esc_html_e('Class', 'result-management-system-for-institutions'); ?></label>
                                        <select name="class_id" id="filter-class" class="filter-select astgdrmsys-filter-class">
                                                <option value=""><?php esc_html_e('All Classes', 'result-management-system-for-institutions'); ?></option>
                                                <?php foreach ($class_options as $class_option) : ?>
                                                        <option value="<?php echo esc_attr($class_option['id']); ?>" <?php selected((int) $filters['class'], (int) $class_option['id']); ?>>
                                                                <?php echo esc_html($class_option['class']); ?>
                                                        </option>
                                                <?php endforeach; ?>
                                        </select>
                                </div>

                                <div class="filter-field">
                                        <label for="filter-department" class="filter-label"><?php esc_html_e('Department', 'result-management-system-for-institutions'); ?></label>
                                        <select name="department_id" id="filter-department" class="filter-select astgdrmsys-filter-department">
                                                <option value=""><?php esc_html_e('All Departments', 'result-management-system-for-institutions'); ?></option>
                                                <?php foreach ($department_options as $department_option) : ?>
                                                        <option value="<?php echo esc_attr($department_option['id']); ?>" <?php selected((int) $filters['department'], (int) $department_option['id']); ?>>
                                                                <?php echo esc_html($department_option['department']); ?>
                                                        </option>
                                                <?php endforeach; ?>
                                        </select>
                                </div>

                                <div class="filter-field">
                                        <label for="filter-exam" class="filter-label"><?php esc_html_e('Exam', 'result-management-system-for-institutions'); ?></label>
                                        <select name="exam_id" id="filter-exam" class="filter-select astgdrmsys-filter-exam">
                                                <option value=""><?php esc_html_e('All Exams', 'result-management-system-for-institutions'); ?></option>
                                                <?php foreach ($exam_options as $exam_option) : ?>
                                                        <option value="<?php echo esc_attr($exam_option['id']); ?>" <?php selected((int) $filters['exam'], (int) $exam_option['id']); ?>>
                                                                <?php echo esc_html($exam_option['label']); ?>
                                                        </option>
                                                <?php endforeach; ?>
                                        </select>
                                </div>

                                <div class="filter-field">
                                        <label for="filter-section" class="filter-label"><?php esc_html_e('Section', 'result-management-system-for-institutions'); ?></label>
                                        <select name="section_id" id="filter-section" class="filter-select astgdrmsys-filter-section">
                                                <option value=""><?php esc_html_e('All Sections', 'result-management-system-for-institutions'); ?></option>
                                                <?php foreach ($section_options as $section_option) : ?>
                                                        <option value="<?php echo esc_attr($section_option['id']); ?>" <?php selected((int) $filters['section'], (int) $section_option['id']); ?>>
                                                                <?php echo esc_html($section_option['section']); ?>
                                                        </option>
                                                <?php endforeach; ?>
                                        </select>
                                </div>

                                <div class="filter-field">
                                        <label for="filter-regno" class="filter-label"><?php esc_html_e('Registration Number', 'result-management-system-for-institutions'); ?></label>
                                        <input type="text" name="regno" id="filter-regno" value="<?php echo esc_attr($filters['regno']); ?>" class="filter-input" placeholder="<?php esc_attr_e('Search Registration No.', 'result-management-system-for-institutions'); ?>">
                                </div>

                                <div class="filter-field">
                                        <label for="filter-roll" class="filter-label"><?php esc_html_e('Roll Number', 'result-management-system-for-institutions'); ?></label>
                                        <input type="text" name="roll" id="filter-roll" value="<?php echo esc_attr($filters['roll']); ?>" class="filter-input" placeholder="<?php esc_attr_e('Search Roll No.', 'result-management-system-for-institutions'); ?>">
                                </div>
                        </div>

                        <div class="filter-actions">
                                <button type="submit" class="btn btn-filter">
                                        <i class="dashicons dashicons-filter"></i> <?php esc_html_e('Filter', 'result-management-system-for-institutions'); ?>
                                </button>
                                <a class="btn btn-reset" href="<?php echo esc_url(admin_url('admin.php?page=astgdrmsys-all-students')); ?>">
                                        <i class="dashicons dashicons-update"></i> <?php esc_html_e('Reset', 'result-management-system-for-institutions'); ?>
                                </a>
                        </div>
                </form>
                <?php
        }

        /**
         * Retrieves all available classes.
         *
         * @return array<int, array<string, mixed>> List of class records.
         */
        private function getClassOptions(): array
        {
                $table = esc_sql($this->prefix . 'astgdrmsys_class');

                // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery
                $results = $this->wpdb->get_results("SELECT id, class FROM `{$table}` ORDER BY class ASC", ARRAY_A);

                return is_array($results) ? $results : array();
        }

        /**
         * Retrieves departments for the provided class.
         *
         * @param int $class_id Class identifier.
         *
         * @return array<int, array<string, mixed>> Department records.
         */
        private function getDepartmentOptions(int $class_id): array
        {
                $table = esc_sql($this->prefix . 'astgdrmsys_department');

                // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery
                $results = $this->wpdb->get_results(
                        "SELECT id, department FROM `{$table}` ORDER BY department ASC",
                        ARRAY_A
                );

                return is_array($results) ? $results : array();
        }

        /**
         * Retrieves exam options for the provided class and department.
         *
         * @param int $class_id      Class identifier.
         * @param int $department_id Department identifier.
         *
         * @return array<int, array<string, mixed>> Exam options with formatted labels.
         */
        private function getExamOptions(int $class_id, int $department_id): array
        {
                if ($class_id <= 0) {
                        return array();
                }

                $table = esc_sql($this->prefix . 'astgdrmsys_exam_name');

                // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery
                $exams = $this->wpdb->get_results(
                        $this->wpdb->prepare(
                                "SELECT id, exam_name, exam_year, exam_year_id, department FROM `{$table}` WHERE class_id = %d ORDER BY exam_name ASC",
                                $class_id
                        ),
                        ARRAY_A
                );

                if (! is_array($exams) || empty($exams)) {
                        return array();
                }

                if ($department_id > 0) {
                        $department_table = esc_sql($this->prefix . 'astgdrmsys_department');

                        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery
                        $department_name = $this->wpdb->get_var(
                                $this->wpdb->prepare(
                                        "SELECT department FROM `{$department_table}` WHERE id = %d",
                                        $department_id
                                )
                        );

                        $filtered = array();

                        foreach ($exams as $exam) {
                                $exam_department = isset($exam['department']) ? trim((string) $exam['department']) : '';

                                if (
                                        (string) $department_id === $exam_department ||
                                        ($department_name && strcasecmp($exam_department, $department_name) === 0)
                                ) {
                                        $filtered[] = $exam;
                                }
                        }

                        $exams = $filtered;
                }

                return array_map(
                        static function ($exam) {
                                $label_parts = array_filter(array($exam['exam_name'], $exam['exam_year']));
                                return array(
                                        'id'    => (int) $exam['id'],
                                        'label' => implode(' - ', $label_parts),
                                );
                        },
                        $exams
                );
        }

        /**
         * Retrieves section options for the provided department.
         *
         * @param int $department_id Department identifier.
         *
         * @return array<int, array<string, mixed>> Section records.
         */
        private function getSectionOptions(int $department_id): array
        {
                if ($department_id <= 0) {
                        return array();
                }

                $table = esc_sql($this->prefix . 'astgdrmsys_section');

                // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery
                $results = $this->wpdb->get_results(
                        $this->wpdb->prepare(
                                "SELECT id, section FROM `{$table}` WHERE department = %d ORDER BY section ASC",
                                $department_id
                        ),
                        ARRAY_A
                );

                return is_array($results) ? $results : array();
        }
}

/**
 * Creates a new instance of the ASTGDRMSYS_All_Students class.
 *
 * @param wpdb $wpdb The WordPress database object.
 */
new ASTGDRMSYS_All_Students($wpdb);
?>
