<?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 to prevent unauthorized access.
 *
 * @package ResultManagementSystem
 * @subpackage Menu_Files/Edit_Record
 */
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

global $wpdb;

/**
 * Class ASTGDRMSYS_Edit_Record
 *
 * This class handles the editing of records within the Result Management System for Institutions plugin.
 *
 * @package ResultManagementSystem
 * @subpackage MenuFiles/ASTGDRMSYS_Edit_Record
 * @since 1.0.0
 */
class ASTGDRMSYS_Edit_Record {

	private $wpdb;
	private $prefix;
	private $id;
	private $row;

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

		// First, try GET (initial load)
		if ( isset( $_GET['id'], $_GET['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'get_id_nonce' ) ) {
			$this->id = absint( wp_unslash( $_GET['id'] ) );
		}
		// Then try POST (form submission)
		elseif ( isset( $_POST['id'], $_POST['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'get_id_nonce' ) ) {
			$this->id = absint( wp_unslash( $_POST['id'] ) );
		} else {
			$this->id = 0;
		}

		// Fetch student data
		$this->row = $this->getStudentData( $this->id, $wpdb );

		// Check if this is a POST request
		if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'POST' ) {
			// Handle form submission
			if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
				$this->handleFormSubmission();
			}
		}

		// Render the page
		$this->renderPage();
	}

	/**
	 * Retrieves the data of a student based on the provided ID.
	 *
	 * @param int $id The ID of the student whose data is to be retrieved.
	 * @return array The data of the student.
	 */
	private function getStudentData( $id, $wpdb ) {
		$table_name  = $this->prefix . 'astgdrmsys_student_result';
		$cache_key   = 'student_data_' . intval( $id );
		$cache_group = 'astgdrmsys_student_data';

		$student_data = wp_cache_get( $cache_key, $cache_group );

		if ( $student_data === false ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
			$student_data = $wpdb->get_row(
				$wpdb->prepare(
                    // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
					"SELECT * FROM `$table_name` WHERE `sid` = %d",
					$id
				),
				ARRAY_A
			);

			if ( $student_data ) {
				wp_cache_set( $cache_key, $student_data, $cache_group, 600 ); // Cache for 10 minutes
			}
		}

		return $student_data;
	}


	/**
	 * Handles the form submission for editing a record.
	 *
	 * This function processes the form data submitted by the user to edit an existing record.
	 * It validates the input, updates the record in the database, and provides feedback to the user.
	 *
	 * @return void
	 */
	private function handleFormSubmission() {
		if ( ! isset( $_POST['update_student_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['update_student_nonce'] ) ), 'update_student_action' ) ) {
			wp_die( esc_html__( 'Security check failed. Please try again.', 'result-management-system-for-institutions' ) );
		}

		// Now safely access form data
		$data = array(
			'sno'        => isset( $_POST['sno'] ) ? sanitize_text_field( wp_unslash( $_POST['sno'] ) ) : '',
			'regno'      => isset( $_POST['regno'] ) ? sanitize_text_field( wp_unslash( $_POST['regno'] ) ) : '',
			'name'       => isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '',
			'gender'     => isset( $_POST['gender'] ) ? sanitize_text_field( wp_unslash( $_POST['gender'] ) ) : '',
			'fname'      => isset( $_POST['fname'] ) ? sanitize_text_field( wp_unslash( $_POST['fname'] ) ) : '',
			'mname'      => isset( $_POST['mname'] ) ? sanitize_text_field( wp_unslash( $_POST['mname'] ) ) : '',
			'class'      => isset( $_POST['class'] ) ? sanitize_text_field( wp_unslash( $_POST['class'] ) ) : '',
			'department' => isset( $_POST['department'] ) ? sanitize_text_field( wp_unslash( $_POST['department'] ) ) : '',
			'section'    => isset( $_POST['section'] ) ? sanitize_text_field( wp_unslash( $_POST['section'] ) ) : '',
			'exam_name'  => isset( $_POST['exam_name'] ) ? sanitize_text_field( wp_unslash( $_POST['exam_name'] ) ) : '',
			'exam_year'  => isset( $_POST['exam_year'] ) ? sanitize_text_field( wp_unslash( $_POST['exam_year'] ) ) : '',
		);

		$this->wpdb->update( "{$this->prefix}astgdrmsys_student_result", $data, array( 'sid' => $this->id ) );

		echo "<div class='updated'><p>Record updated successfully!</p></div>";
		$this->row = array_merge( $this->row, $data ); // Update row with new data
	}

	/**
	 * Renders the edit record page.
	 *
	 * This function is responsible for rendering the page where users can edit
	 * records within the plugin. It handles the display of the form and any
	 * necessary data processing.
	 *
	 * @return void
	 */
	private function renderPage() {
		$gender = isset( $this->row['gender'] ) ? $this->row['gender'] : '';

		$maleselected   = ( $gender === 'MALE' ) ? 'selected' : '';
		$femaleselected = ( $gender === 'FEMALE' ) ? 'selected' : '';
		$othersselected = ( $gender === 'OTHERS' ) ? 'selected' : '';
		$student_image_url = ! empty( $this->row['student_image'] ) ? esc_url( $this->row['student_image'] ) : ''; ?>
		<!-- Edit Container -->
		<div class="edit-record-container">
			<h1>Edit <?php echo esc_html( $this->row['name'] ); ?>'s Information</h1>
			<form action="" method="POST">
				<?php wp_nonce_field( 'get_id_nonce', '_wpnonce' ); ?>
				<?php wp_nonce_field( 'update_student_action', 'update_student_nonce' ); ?>
				<input type="hidden" name="id" value="<?php echo esc_attr( $this->id ); ?>">
				<div class="student-actions-container">
					<div class="action-row">
						<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
							<div class="filter-field">
								<label><strong>Student Image :</strong></label>
								<?php
								// Determine the default image URL based on gender
								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';
								}
								?>
								<img src="<?php echo $student_image_url ? $student_image_url : $default_avatar_url; ?>"
								alt="Student Image"
								class="edit-student-image"
								draggable="false"
								style="max-width: 150px; border-radius: 8px; margin-bottom: 10px;">
								<input type="file" name="student_image" accept="image/*" style="padding: 8px; border: 1px solid #e2e8f0; border-radius: 4px; background: #f8fafc; width: 100%;">
							</div>
							
							<div style="display: flex; flex-direction: column; gap: 20px;">
								<div class="filter-field">
									<label for="sno"><strong>Serial Number :</strong></label>
									<input type="text" placeholder="Enter Serial Number" name="sno" value="<?php echo esc_html( $this->row['sno'] ); ?>" id="sno">
								</div>
								<div class="filter-field">
									<label for="regno"><strong>Reg No :</strong></label>
									<input type="text" placeholder="Enter Registration Number" value="<?php echo esc_html( $this->row['regno'] ); ?>" name="regno" id="regno">
								</div>
							</div>

							<div class="filter-field">
								<label for="name"><strong>Name :</strong></label>
								<input type="text" placeholder="Enter Student Name" value="<?php echo esc_html( $this->row['name'] ); ?>" name="name" id="name" required>
							</div>

							<div class="filter-field">
								<label><strong>Gender :</strong></label>
								<select name="gender">
									<option value="MALE" <?php echo esc_attr( $maleselected ); ?>>MALE</option>
									<option value="FEMALE" <?php echo esc_attr( $femaleselected ); ?>>FEMALE</option>
									<option value="OTHERS" <?php echo esc_attr( $othersselected ); ?>>Others</option>
								</select>
							</div>

							<div class="filter-field">
								<label for="fname"><strong>Father's Name :</strong></label>
								<input type="text" placeholder="Enter Father's Name" value="<?php echo esc_html( $this->row['fname'] ); ?>" name="fname" id="fname">
							</div>

							<div class="filter-field">
								<label for="mname"><strong>Mother's Name :</strong></label>
								<input type="text" placeholder="Enter Mother's Name" value="<?php echo esc_html( $this->row['mname'] ); ?>" name="mname" id="mname">
							</div>

							<div class="filter-field">
								<label for="class"><strong>Class :</strong></label>
								<select name="class" id="class">
									<?php $this->renderOptions( 'astgdrmsys_class', 'class', $this->row['class'] ); ?>
								</select>
							</div>

							<div class="filter-field">
								<label for="department"><strong>Department :</strong></label>
								<select name="department" id="department">
									<?php $this->renderOptions( 'astgdrmsys_department', 'department', $this->row['department'] ); ?>
								</select>
							</div>

							<div class="filter-field">
								<label for="section"><strong>Section :</strong></label>
								<select name="section" id="section">
									<?php $this->renderOptions( 'astgdrmsys_section', 'section', $this->row['section'] ); ?>
								</select>
							</div>

							<div class="filter-field">
								<label for="exam_name"><strong>Exam Name :</strong></label>
								<select name="exam_name" id="exam_name">
									<?php $this->renderOptions( 'astgdrmsys_exam_name', 'exam_name', $this->row['exam_name'] ); ?>
								</select>
							</div>

							<div class="filter-field">
								<label for="exam_year"><strong>Exam Year :</strong></label>
								<select name="exam_year" id="exam_year">
									<?php $this->renderOptions( 'astgdrmsys_exam_year', 'exam_year', $this->row['exam_year'] ); ?>
								</select>
							</div>
						</div>

						<div class="action-buttons" style="margin-top: 25px; display: flex; gap: 15px;">
							<input class="btn btn-primary hero-btn" type="submit" name='submit' value="Update" style="width: auto; padding: 0 30px;">
							<button class="btn btn-danger" type="button" onclick="window.history.back();" style="width: auto; padding: 0 30px;">Cancel</button>
						</div>
					</div>
				</div>
			</form>
		</div>
		<?php
	}

	/**
	 * Renders the options for a select dropdown based on the specified table and column.
	 *
	 * @param string $table The name of the table to fetch options from.
	 * @param string $column The name of the column to fetch options from.
	 * @param int    $selected_id The ID of the option that should be pre-selected.
	 */
	private function renderOptions( $table, $column, $selected_id ) {
		global $wpdb;

		// Whitelist the table name if possible
		$allowed_tables = array( 'astgdrmsys_class', 'astgdrmsys_department', 'astgdrmsys_section', 'astgdrmsys_exam_name', 'astgdrmsys_exam_year' );
		if ( ! in_array( $table, $allowed_tables, true ) ) {
			return; // prevent unsafe access
		}

		// Build full table name
		$table_name = $wpdb->prefix . $table;

		// Sanitize column name if needed (same whitelisting approach can apply)
		$column = esc_sql( $column );

		// Generate cache key
		$cache_key = 'table_results_' . md5( $table_name . $column );

		// Try to get from cache
		$results = wp_cache_get( $cache_key );

		if ( $results === false ) {
			// Build SQL
			$sql = "SELECT * FROM `{$table_name}`";

			// Fetch and cache results
            // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
			$results = $wpdb->get_results( $sql, ARRAY_A );

			wp_cache_set( $cache_key, $results );
		}

		// Output HTML options
		foreach ( $results as $item ) {
			$selected = ( $item['id'] == $selected_id ) ? 'selected' : '';
			echo '<option value="' . esc_attr( $item['id'] ) . '" ' . esc_attr( $selected ) . '>' . esc_html( $item[ $column ] ) . '</option>';
		}
	}
}

/**
 * Instantiate the ASTGDRMSYS_Edit_Record class
 *
 * This line of code creates a new instance of the ASTGDRMSYS_Edit_Record class, passing the
 * $wpdb global variable as a parameter. The $wpdb variable is typically used in
 * WordPress to interact with the database.
 *
 * @param wpdb $wpdb The WordPress database access abstraction object.
 */
new ASTGDRMSYS_Edit_Record( $wpdb );
?>