<?php

/**
 * Retake mark entry workflow.
 *
 * @package ResultManagementSystem
 * @subpackage MenuFiles/Mark
 */

if (! defined('ABSPATH')) {
	exit;
}

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

class ASTGDRMSYS_Retake_Marks_Manager
{
	use ASTGDRMSYS_Retake_Helper;

	/**
	 * @var wpdb
	 */
	private $wpdb;

	/**
	 * @var string
	 */
	private $prefix;

	public function __construct()
	{
		global $wpdb;

		$this->wpdb   = $wpdb;
		$this->prefix = $wpdb->prefix;

		$this->init();
	}

	private function init()
	{
		if (isset($_POST['astgdrmsys_retake_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['astgdrmsys_retake_nonce'])), 'astgdrmsys_retake_action')) {
			$this->handle_save();
		}

		if (isset($_GET['retake_saved']) && '1' === sanitize_text_field(wp_unslash($_GET['retake_saved']))) {
			echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__('Retake marks have been saved.', 'result-management-system-for-institutions') . '</p></div>';
		}

		$this->render_filter();

		if (isset($_GET['retake_sid'])) {
			$this->render_retake_form(absint(wp_unslash($_GET['retake_sid'])));
			return;
		}

		if (isset($_GET['classsearch'], $_GET['examname'])) {
			$this->render_student_table(
				absint(wp_unslash($_GET['classsearch'])),
				absint(wp_unslash($_GET['examname']))
			);
		}
	}

	private function render_filter()
	{
		$classes = $this->fetch_classes();
		?>
		<div class="container astgdrmsys-premium-wrap">
			<div class="premium-page-header">
				<div class="page-header-text">
					<h1><?php esc_html_e('Retake Marks', 'result-management-system-for-institutions'); ?></h1>
				</div>
			</div>
			<form method="get" action="" id="submitForm" style="background: #ffffff; padding: 25px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.02); border: 1px solid #e2e8f0; margin-bottom: 30px;">
				<input type="hidden" name="page" value="astgdrmsys-add-mark">
				<input type="hidden" name="mark_tab" value="retake">
				<div style="display: flex; flex-wrap: wrap; gap: 20px; align-items: flex-end;">
					<div class="filter-group" style="flex: 1; min-width: 200px;">
						<label style="display: block; font-size: 11px; font-weight: 700; color: #1e293b; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px;"><?php esc_html_e('Select Class', 'result-management-system-for-institutions'); ?></label>
						<select class="selectClass premium-input" name="classsearch" required style="width: 100%;">
							<option value="" selected disabled><?php esc_html_e('Select a Class', 'result-management-system-for-institutions'); ?></option>
							<?php foreach ($classes as $class) : ?>
								<option value="<?php echo esc_attr($class['id']); ?>" <?php selected(isset($_GET['classsearch']) ? absint(wp_unslash($_GET['classsearch'])) : 0, (int) $class['id']); ?>>
									<?php echo esc_html($class['class']); ?>
								</option>
							<?php endforeach; ?>
						</select>
					</div>
					<div class="filter-group" style="flex: 1; min-width: 200px;">
						<label style="display: block; font-size: 11px; font-weight: 700; color: #1e293b; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px;"><?php esc_html_e('Select Exam Name', 'result-management-system-for-institutions'); ?></label>
						<select class="selectExam premium-input" name="examname" required style="width: 100%;">
							<option value=""><?php esc_html_e('Select Class First', 'result-management-system-for-institutions'); ?></option>
						</select>
					</div>
					<div class="filter-actions" style="margin-top: 0;">
						<input type="submit" value="<?php esc_attr_e('See Students', 'result-management-system-for-institutions'); ?>" class="btn btn-primary submit-btn hero-btn" style="height: 42px; margin-bottom: 0;">
					</div>
				</div>
			</form>
		</div>
		<?php
	}

	private function render_student_table($class_id, $exam_id)
	{
		$students = $this->fetch_students($class_id, $exam_id);
		?>
		<div class="students-container m-4 px-1 astgdrmsys-premium-wrap">
			<div class="premium-page-header">
				<div class="page-header-text">
					<h1><?php echo esc_html(sprintf('Students in %s for Exam %s', $this->fetch_class_name($class_id), $this->fetch_exam_name($exam_id))); ?></h1>
				</div>
			</div>
			<table class="styled-table">
				<?php if (empty($students)) : ?>
					<tr><td><div class="notice notice-warning"><p><?php esc_html_e('No students found for this class and exam.', 'result-management-system-for-institutions'); ?></p></div></td></tr>
				<?php else : ?>
					<thead class="thead-dark">
						<tr>
							<th><?php esc_html_e('Id', 'result-management-system-for-institutions'); ?></th>
							<th><?php esc_html_e('Roll No', 'result-management-system-for-institutions'); ?></th>
							<th><?php esc_html_e('Student Name', 'result-management-system-for-institutions'); ?></th>
							<th><?php esc_html_e('Retake Subjects', 'result-management-system-for-institutions'); ?></th>
							<th><?php esc_html_e('Action', 'result-management-system-for-institutions'); ?></th>
						</tr>
					</thead>
					<tbody>
						<?php foreach ($students as $index => $student) : ?>
							<tr>
								<td><?php echo esc_html($index + 1); ?></td>
								<td><strong><?php echo esc_html($student['sno']); ?></strong></td>
								<td><?php echo esc_html($student['name']); ?></td>
								<td><?php echo esc_html($this->count_retake_subjects($student['sid'])); ?></td>
								<td>
									<a class="hero-btn primary-btn" href="<?php echo esc_url(wp_nonce_url(admin_url('admin.php?page=astgdrmsys-add-mark&mark_tab=retake&retake_sid=' . absint($student['sid']) . '&classsearch=' . absint($class_id) . '&examname=' . absint($exam_id)), 'astgdrmsys_retake_view', 'astgdrmsys_retake_view_nonce')); ?>">
										<?php esc_html_e('Record Retake', 'result-management-system-for-institutions'); ?>
									</a>
								</td>
							</tr>
						<?php endforeach; ?>
					</tbody>
				<?php endif; ?>
			</table>
		</div>
		<?php
	}

	private function render_retake_form($sid)
	{
		if (! isset($_GET['astgdrmsys_retake_view_nonce']) || ! wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['astgdrmsys_retake_view_nonce'])), 'astgdrmsys_retake_view')) {
			wp_die(esc_html__('Invalid or expired request.', 'result-management-system-for-institutions'));
		}

		$student = $this->fetch_student_result($sid);
		if (empty($student)) {
			echo '<div class="notice notice-error"><p>' . esc_html__('Student result not found.', 'result-management-system-for-institutions') . '</p></div>';
			return;
		}

		$exam     = $this->fetch_exam_row((int) $student['exam_name']);
		$subjects = $this->fetch_subjects_for_student($student, $exam);
		$marks    = $this->get_student_original_marks($sid);
		$retakes  = $this->get_retake_marks_by_sid($sid);
		?>
		<div class="container astgdrmsys-premium-wrap">
			<div class="premium-page-header">
				<div class="page-header-text">
					<h1><?php echo esc_html(sprintf('Retake Marks for %s', $student['name'])); ?></h1>
				</div>
			</div>
			<form method="post" action="">
				<?php wp_nonce_field('astgdrmsys_retake_action', 'astgdrmsys_retake_nonce'); ?>
				<input type="hidden" name="sid" value="<?php echo esc_attr($sid); ?>">
				<table class="styled-table mark-table">
					<thead class="thead-dark">
						<tr>
							<th><?php esc_html_e('Subject', 'result-management-system-for-institutions'); ?></th>
							<th><?php esc_html_e('Full Mark', 'result-management-system-for-institutions'); ?></th>
							<th><?php esc_html_e('Original Mark', 'result-management-system-for-institutions'); ?></th>
							<th><?php esc_html_e('Retake Mark', 'result-management-system-for-institutions'); ?></th>
							<th><?php esc_html_e('Retake Date', 'result-management-system-for-institutions'); ?></th>
							<th><?php esc_html_e('Note', 'result-management-system-for-institutions'); ?></th>
						</tr>
					</thead>
					<tbody>
						<?php foreach ($subjects as $subject) :
							$subcode       = trim((string) ($subject['subcode'] ?? ''));
							$subject_mark  = $marks[$subcode] ?? null;
							$original_mark = $this->get_original_subject_total($subject_mark);
							$retake        = $retakes[$subcode] ?? array();
							?>
							<tr>
								<td>
									<strong><?php echo esc_html($subject['subname'] ?? $subcode); ?></strong><br>
									<small>(<?php echo esc_html($subcode); ?>)</small>
								</td>
								<td><?php echo esc_html($subject['total'] ?? ''); ?></td>
								<td><?php echo esc_html(null === $original_mark ? '-' : $this->format_retake_mark_value($original_mark)); ?></td>
								<td>
									<input type="number" step="0.01" min="0" name="retakes[<?php echo esc_attr($subcode); ?>][mark]" value="<?php echo esc_attr(isset($retake['retake_mark']) ? $this->format_retake_mark_value($retake['retake_mark']) : ''); ?>">
								</td>
								<td>
									<input type="date" name="retakes[<?php echo esc_attr($subcode); ?>][date]" value="<?php echo esc_attr($retake['retake_date'] ?? ''); ?>">
								</td>
								<td>
									<input type="text" name="retakes[<?php echo esc_attr($subcode); ?>][note]" value="<?php echo esc_attr($retake['note'] ?? ''); ?>">
								</td>
							</tr>
						<?php endforeach; ?>
					</tbody>
				</table>
				<div class="button-div">
					<input type="submit" name="retake_submit" value="<?php esc_attr_e('Save Retake Marks', 'result-management-system-for-institutions'); ?>" class="btn btn-primary">
					<button class="btn btn-danger" type="button" onclick="window.history.back();"><?php esc_html_e('Cancel', 'result-management-system-for-institutions'); ?></button>
				</div>
			</form>
		</div>
		<?php
	}

	private function handle_save()
	{
		$sid = isset($_POST['sid']) ? absint(wp_unslash($_POST['sid'])) : 0;
		if ($sid <= 0 || empty($_POST['retake_submit'])) {
			return;
		}

		$student = $this->fetch_student_result($sid);
		if (empty($student)) {
			wp_die(esc_html__('Student result not found.', 'result-management-system-for-institutions'));
		}

		$retakes = isset($_POST['retakes']) && is_array($_POST['retakes']) ? wp_unslash($_POST['retakes']) : array();
		$table   = $this->prefix . 'astgdrmsys_retake_marks';
		$user_id = get_current_user_id();

		foreach ($retakes as $subject_code => $data) {
			$subject_code = sanitize_text_field((string) $subject_code);
			$mark_raw     = isset($data['mark']) ? trim((string) $data['mark']) : '';

			if ('' === $subject_code) {
				continue;
			}

			if ('' === $mark_raw) {
				$this->wpdb->delete($table, array('sid' => $sid, 'subject_code' => $subject_code), array('%d', '%s'));
				continue;
			}

			$retake_mark = max(0, floatval($mark_raw));
			$retake_date = isset($data['date']) && '' !== $data['date'] ? sanitize_text_field((string) $data['date']) : null;
			$note        = isset($data['note']) ? sanitize_text_field((string) $data['note']) : '';
			$existing_id = $this->wpdb->get_var(
				$this->wpdb->prepare(
					"SELECT id FROM {$table} WHERE sid = %d AND subject_code = %s",
					$sid,
					$subject_code
				)
			);

			$row = array(
				'sid'          => $sid,
				'student_id'   => isset($student['student_id']) ? absint($student['student_id']) : null,
				'exam_id'      => absint($student['exam_name']),
				'exam_year_id' => isset($student['exam_year']) ? absint($student['exam_year']) : null,
				'subject_code' => $subject_code,
				'retake_mark'  => $retake_mark,
				'retake_date'  => $retake_date,
				'note'         => $note,
				'created_by'   => $user_id,
				'updated_at'   => current_time('mysql'),
			);

			if ($existing_id) {
				unset($row['created_by']);
				$this->wpdb->update(
					$table,
					$row,
					array('id' => absint($existing_id)),
					array('%d', '%d', '%d', '%d', '%s', '%f', '%s', '%s', '%s'),
					array('%d')
				);
			} else {
				$row['created_at'] = current_time('mysql');
				$this->wpdb->insert(
					$table,
					$row,
					array('%d', '%d', '%d', '%d', '%s', '%f', '%s', '%s', '%d', '%s', '%s')
				);
			}
		}

		wp_safe_redirect(
			wp_nonce_url(
				admin_url('admin.php?page=astgdrmsys-add-mark&mark_tab=retake&retake_sid=' . $sid . '&classsearch=' . absint($student['class']) . '&examname=' . absint($student['exam_name']) . '&retake_saved=1'),
				'astgdrmsys_retake_view',
				'astgdrmsys_retake_view_nonce'
			)
		);
		exit;
	}

	private function fetch_classes()
	{
		$table = esc_sql($this->prefix . 'astgdrmsys_class');
		return $this->wpdb->get_results("SELECT * FROM {$table}", ARRAY_A);
	}

	private function fetch_students($class_id, $exam_id)
	{
		$table = esc_sql($this->prefix . 'astgdrmsys_student_result');
		return $this->wpdb->get_results(
			$this->wpdb->prepare(
				"SELECT * FROM {$table} WHERE class = %d AND exam_name = %d ORDER BY CAST(sno AS UNSIGNED) ASC",
				$class_id,
				$exam_id
			),
			ARRAY_A
		);
	}

	private function fetch_student_result($sid)
	{
		$table = esc_sql($this->prefix . 'astgdrmsys_student_result');
		return $this->wpdb->get_row(
			$this->wpdb->prepare("SELECT * FROM {$table} WHERE sid = %d", $sid),
			ARRAY_A
		);
	}

	private function fetch_class_name($class_id)
	{
		$table = esc_sql($this->prefix . 'astgdrmsys_class');
		return (string) $this->wpdb->get_var($this->wpdb->prepare("SELECT class FROM {$table} WHERE id = %d", $class_id));
	}

	private function fetch_exam_name($exam_id)
	{
		$table = esc_sql($this->prefix . 'astgdrmsys_exam_name');
		return (string) $this->wpdb->get_var($this->wpdb->prepare("SELECT exam_name FROM {$table} WHERE id = %d", $exam_id));
	}

	private function fetch_exam_row($exam_id)
	{
		$table = esc_sql($this->prefix . 'astgdrmsys_exam_name');
		return $this->wpdb->get_row($this->wpdb->prepare("SELECT * FROM {$table} WHERE id = %d", $exam_id), ARRAY_A);
	}

	private function get_student_original_marks($sid)
	{
		$table = esc_sql($this->prefix . 'astgdrmsys_mark');
		$raw   = $this->wpdb->get_var($this->wpdb->prepare("SELECT marks FROM {$table} WHERE sid = %d", $sid));
		$marks = $raw ? maybe_unserialize($raw) : array();

		if (! is_array($marks)) {
			return array();
		}

		$normalized = isset($marks[0]) && is_array($marks[0]) ? $marks[0] : $marks;
		unset($normalized['fourth_subject']);

		return $normalized;
	}

	private function count_retake_subjects($sid)
	{
		$table = esc_sql($this->prefix . 'astgdrmsys_retake_marks');
		return (int) $this->wpdb->get_var($this->wpdb->prepare("SELECT COUNT(*) FROM {$table} WHERE sid = %d", $sid));
	}

	private function fetch_subjects_for_student($student, $exam)
	{
		$subject_entries = $this->parse_exam_subject_entries($exam['subject_full_marks'] ?? null);

		if (! empty($subject_entries)) {
			return $subject_entries;
		}

		$table = esc_sql($this->prefix . 'astgdrmsys_subject');
		return $this->wpdb->get_results(
			$this->wpdb->prepare(
				"SELECT * FROM {$table} WHERE class = %d AND department = %d ORDER BY subid ASC, id ASC",
				absint($student['class']),
				absint($student['department'])
			),
			ARRAY_A
		);
	}

	private function parse_exam_subject_entries($raw_value)
	{
		if (empty($raw_value)) {
			return array();
		}

		if (is_string($raw_value)) {
			$decoded = json_decode($raw_value, true);
			$raw_value = (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) ? $decoded : maybe_unserialize($raw_value);
		} elseif (is_object($raw_value)) {
			$raw_value = (array) $raw_value;
		}

		if (! is_array($raw_value)) {
			return array();
		}

		$subjects = array();
		foreach ($raw_value as $entry) {
			if (is_object($entry)) {
				$entry = (array) $entry;
			}

			if (! is_array($entry)) {
				continue;
			}

			$code = '';
			if (! empty($entry['code'])) {
				$code = sanitize_text_field((string) $entry['code']);
			} elseif (! empty($entry['subcode'])) {
				$code = sanitize_text_field((string) $entry['subcode']);
			}

			if ('' === $code) {
				continue;
			}

			$subjects[] = array(
				'subcode' => $code,
				'subname' => isset($entry['name']) ? sanitize_text_field((string) $entry['name']) : sanitize_text_field((string) ($entry['subname'] ?? $code)),
				'total'   => isset($entry['full_mark']) ? floatval($entry['full_mark']) : (isset($entry['total']) ? floatval($entry['total']) : ''),
			);
		}

		return $subjects;
	}
}

new ASTGDRMSYS_Retake_Marks_Manager();
