// class dropdown list 

function loadClassDropdown() {
    fetch("api/class_list_dropdown.php")
        .then(res => res.json())
        .then(data => {
            let html = `<option value="">Select Class</option>`;

            data.forEach(c => {
                html += `<option value="${c.id}">${c.class_name}</option>`;
            });

            document.getElementById("class_id").innerHTML = html;
        })
        .catch(() => {
            console.error("Class dropdown load failed");
        });
}

loadClassDropdown();
// 1. Fetch Streams from your API on page load




// subjects addd 
function addSubject() {
    const classId = document.getElementById("class_id").value;
    const subjectName = document.getElementById("subject_name").value.trim();

    // Capture the mark distribution values
    const theoryMax = parseInt(document.getElementById("theory_max").value) || 0;
    const practicalMax = parseInt(document.getElementById("practical_max").value) || 0;
    const passMarks = parseInt(document.getElementById("pass_marks").value) || 0;

    // Basic Validation
    if (!classId || !subjectName) {
        Swal.fire("Error", "Class and Subject Name are required", "error");
        return;
    }

    // Logical Validation: Pass marks shouldn't be higher than total marks
    if (passMarks > (theoryMax + practicalMax)) {
        Swal.fire("Error", "Pass marks cannot be greater than Total Marks (Theory + Practical)", "error");
        return;
    }

    // Construct the payload without stream_id
    const payload = {
        class_id: classId,
        subject_name: subjectName,
        theory_max: theoryMax,
        practical_max: practicalMax,
        pass_marks: passMarks
    };

    fetch("api/subject_add.php", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload)
    })
        .then(res => res.json())
        .then(data => {
            if (data.status === "success") {
                Swal.fire("Success", data.message, "success");

                // Reset fields to default values
                document.getElementById("subject_name").value = "";
                document.getElementById("theory_max").value = "100";
                document.getElementById("practical_max").value = "0";
                document.getElementById("pass_marks").value = "33";

                // Refresh the subject list table
                loadSubjects();
            } else {
                Swal.fire("Error", data.message, "error");
            }
        })
        .catch(err => {
            console.error("Fetch Error:", err);
            Swal.fire("Error", "Could not connect to the server", "error");
        });
}



// load Subjects();
let subjects = [];
let groupedSubjects = []; // 🔑 Store grouped data here
let subjectPage = 1;
let subjectRows = 10;

/* 2️⃣ Load subjects */
function loadSubjects() {
    fetch("api/subject_list.php")
        .then(res => res.json())
        .then(data => {
            subjects = data;
            groupData(data); // 🔑 Group data immediately after fetch
            subjectPage = 1;
            showSubjects();
            subjectPagination();
        });
}

/* 🔑 Helper function to group subjects by Class */
/* Helper function to group subjects and update the badge */
function groupData(dataArray) {
    const groups = dataArray.reduce((acc, current) => {
        const className = current.class_name;
        if (!acc[className]) {
            acc[className] = {
                class_name: className,
                class_id: current.class_id,
                subject_list: []
            };
        }
        acc[className].subject_list.push(current);
        return acc;
    }, {});

    groupedSubjects = Object.values(groups);

    // Update the badge count
    const badge = document.getElementById("totalClassesBadge");
    if (badge) {
        badge.innerText = `${groupedSubjects.length} Classes`;
    }
}

// search function 
function searchSubjects() {
    let keyword = document.getElementById("subjectSearch").value.toLowerCase();

    // Filter the original flat list, then re-group
    let filtered = subjects.filter(s =>
        s.subject_name.toLowerCase().includes(keyword) ||
        s.class_name.toLowerCase().includes(keyword)
    );

    groupData(filtered);
    subjectPage = 1;
    showSubjects();
    subjectPagination();
}

/* 3️⃣ Show subject table */
function showSubjects() {
    let start = (subjectPage - 1) * subjectRows;
    let end = start + subjectRows;

    let rows = groupedSubjects.slice(start, end);
    let html = "";

    rows.forEach((g, index) => {
        // Create badges for all subjects in this class
        let subjectBadges = g.subject_list.map(s => {
            let safeName = s.subject_name.replace(/'/g, "\\'");

            // Label for marks breakdown (e.g., 80Th + 20Pr)
            let marksLabel = `<small class="d-block text-white-50" style="font-size:0.65rem;">
                ${s.theory_max}Th + ${s.practical_max}Pr (Pass: ${s.pass_marks})
            </small>`;

            return `
                <div class="btn-group m-1 shadow-sm">
                    <span class="badge ${s.status == 1 ? 'bg-primary' : 'bg-secondary'} p-2 text-start" style="min-width: 100px;">
                        <div class="fw-bold">${s.subject_name}</div>
                        ${marksLabel}
                    </span>
                    <button class="btn btn-warning btn-sm py-0 d-flex align-items-center" 
                        title="Edit Marks/Name"
                        onclick="editSubject(${s.id}, '${safeName}', ${s.class_id}, ${s.theory_max}, ${s.practical_max}, ${s.pass_marks})">
                        <i class="fas fa-edit small"></i>
                    </button>
                    <button class="btn btn-danger btn-sm py-0 d-flex align-items-center" 
                        onclick="deleteSubject(${s.id})">
                        &times;
                    </button>
                </div>`;
        }).join("");

        html += `<tr>
            <td>${start + index + 1}</td>
            <td class="fw-bold text-primary">
                ${g.class_name}
            </td>
            <td>
                <div class="d-flex flex-wrap">
                    ${subjectBadges}
                </div>
            </td>
            <td class="text-center">
                <span class="badge rounded-pill bg-light text-dark border">
                    ${g.subject_list.length} Subjects
                </span>
            </td>
        </tr>`;
    });

    document.getElementById("subjectTable").innerHTML = html;
}

/* 4️⃣ Pagination buttons */
function subjectPagination() {
    let totalPages = Math.ceil(groupedSubjects.length / subjectRows);

    if (totalPages <= 1) {
        document.getElementById("subjectPagination").innerHTML = "";
        return;
    }

    let html = "";
    for (let i = 1; i <= totalPages; i++) {
        html += `
        <button class="btn btn-sm ${i == subjectPage ? 'btn-primary' : 'btn-outline-primary'} mx-1"
            onclick="subjectGo(${i})">${i}</button>`;
    }

    document.getElementById("subjectPagination").innerHTML = html;
}

function subjectGo(p) {
    subjectPage = p;
    showSubjects();
    subjectPagination();
}



/* 5️⃣ PAGE CLICK FUNCTION ← PUT IT HERE */
window.subjectGo = function (page) {
    subjectPage = page;
    showSubjects();
    subjectPagination();
};


/* 6️⃣ Call on page load */
loadSubjects();


// ================== edit subject ==============

function editSubject(id, name, classId, thMax, prMax, pMarks) {
    Swal.fire({
        title: "Edit Subject",
        html: `
            <style>
                .swal-custom-container { text-align: left; }
                .swal-label { display: block; margin: 10px 0 5px 0; font-size: 14px; font-weight: bold; color: #444; }
                .swal-grid { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 15px; }
                .swal-grid-item { flex: 1; min-width: 100px; }
                .swal2-input.custom-input { width: 100% !important; margin: 5px 0 !important; box-sizing: border-box; }
                @media (max-width: 480px) { .swal-grid-item { flex: 1 1 100%; } }
            </style>
            <div class="swal-custom-container">
                <label class="swal-label">Class Name</label>
                <select id="edit_class" class="swal2-input custom-input"></select>
                
                <label class="swal-label">Subject Name</label>
                <input id="edit_subject" class="swal2-input custom-input" placeholder="Subject Name" value="${name}">

                <div class="swal-grid">
                    <div class="swal-grid-item">
                        <label style="font-size: 12px; font-weight: bold;">Theory Max</label>
                        <input type="number" id="edit_theory_max" class="swal2-input custom-input" value="${thMax}">
                    </div>
                    <div class="swal-grid-item">
                        <label style="font-size: 12px; font-weight: bold;">Practical Max</label>
                        <input type="number" id="edit_practical_max" class="swal2-input custom-input" value="${prMax}">
                    </div>
                    <div class="swal-grid-item">
                        <label style="font-size: 12px; font-weight: bold;">Pass Marks</label>
                        <input type="number" id="edit_pass_marks" class="swal2-input custom-input" value="${pMarks}">
                    </div>
                </div>
            </div>
        `,
        showCancelButton: true,
        confirmButtonText: "Update",
        focusConfirm: false,
        didOpen: async () => {
            const classSelect = document.getElementById("edit_class");
            try {
                const resClass = await fetch("api/class_list_dropdown.php");
                const classes = await resClass.json();
                classSelect.innerHTML = classes.map(c =>
                    `<option value="${c.id}" ${c.id == classId ? 'selected' : ''}>
                        ${c.class_name}
                    </option>`).join('');
            } catch (e) {
                console.error("Error loading classes", e);
            }
        },
        preConfirm: () => {
            const newClassId = document.getElementById("edit_class").value;
            const newName = document.getElementById("edit_subject").value.trim();
            const newThMax = parseInt(document.getElementById("edit_theory_max").value) || 0;
            const newPrMax = parseInt(document.getElementById("edit_practical_max").value) || 0;
            const newPassMarks = parseInt(document.getElementById("edit_pass_marks").value) || 0;

            if (!newClassId || !newName) {
                Swal.showValidationMessage("Class and Subject Name are required");
                return false;
            }
            if (newPassMarks > (newThMax + newPrMax)) {
                Swal.showValidationMessage("Pass marks exceed total marks");
                return false;
            }

            return {
                id,
                class_id: newClassId,
                subject_name: newName,
                theory_max: newThMax,
                practical_max: newPrMax,
                pass_marks: newPassMarks
            };
        }
    }).then(async (result) => {
        if (result.isConfirmed) {
            try {
                const res = await fetch("api/subject_update.php", {
                    method: "POST",
                    headers: { "Content-Type": "application/json" },
                    body: JSON.stringify(result.value)
                });
                const data = await res.json();

                if (data.status === "success") {
                    Swal.fire("Updated!", data.message, "success");
                    loadSubjects();
                } else {
                    Swal.fire("Error", data.message, "error");
                }
            } catch (err) {
                Swal.fire("Error", "Server connection failed", "error");
            }
        }
    });
}
//================== exam term add js ===================
document.addEventListener('DOMContentLoaded', function () {
    const examForm = document.getElementById('examTermForm');
    const saveBtn = document.getElementById('saveExamBtn');

    if (examForm) {
        examForm.addEventListener('submit', function (e) {
            e.preventDefault();

            // Disable button and show loading state
            saveBtn.disabled = true;
            const originalText = saveBtn.innerHTML;
            saveBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Saving...';

            const formData = new FormData(examForm);

            fetch('api/results/add_exam_term_action.php', {
                method: 'POST',
                body: formData
            })
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'success') {
                        Swal.fire({
                            icon: 'success',
                            title: 'Added!',
                            text: 'Exam term created successfully.',
                            timer: 1500,
                            showConfirmButton: false
                        }).then(() => {
                            window.location.reload();
                        });
                    } else {
                        Swal.fire('Error!', data.message || 'Failed to save.', 'error');
                    }
                })
                .catch(error => {
                    console.error('Error:', error);
                    Swal.fire('Error!', 'Could not connect to the server.', 'error');
                })
                .finally(() => {
                    saveBtn.disabled = false;
                    saveBtn.innerHTML = originalText;
                });
        });
    }
});
// ================== load exam terms =================
/// 1. Global State
let currentPage = 1;
let searchQuery = '';
let searchTimeout = null;

document.addEventListener('DOMContentLoaded', () => {
    // Initial Load
    loadExamTerms(1);

    // 2. Search Logic (Fixed)
    const searchInput = document.getElementById('searchTerm');
    if (searchInput) {
        searchInput.addEventListener('input', (e) => {
            clearTimeout(searchTimeout);
            searchQuery = e.target.value;

            searchTimeout = setTimeout(() => {
                currentPage = 1; // Always reset to page 1 on a new search
                loadExamTerms(1);
            }, 500);
        });
    }
});

// 3. Main Load Function (Fixed)
async function loadExamTerms(page = 1) {
    currentPage = page;
    const tableBody = document.getElementById('examTermsTable');
    const paginationControls = document.getElementById('paginationControls');

    try {
        // Construct URL with query parameters
        const url = `api/results/get_exam_terms.php?page=${currentPage}&q=${encodeURIComponent(searchQuery)}`;
        const response = await fetch(url);
        const result = await response.json();

        if (result.status === 'success') {
            renderTable(result.data);
            renderPagination(result.pagination);
        }
    } catch (error) {
        console.error("Error loading data:", error);
    }
}

// 4. Render Table
function renderTable(terms) {
    const tableBody = document.getElementById('examTermsTable');
    tableBody.innerHTML = '';

    if (terms.length === 0) {
        tableBody.innerHTML = '<tr><td colspan="5" class="text-center">No results found</td></tr>';
        return;
    }

    terms.forEach((term, index) => {

        const serialNo = ((currentPage - 1) * 10) + (index + 1);
        const row = `
            <tr>
                <td>${serialNo}</td>
                <td>${term.term_name}</td>
                <td>${term.max_marks}</td>

                <td><span class="badge ${term.status == 1 ? 'bg-success' : 'bg-danger'}">${term.status == 1 ? 'Active' : 'Inactive'}</span></td>
                <td>${new Date(term.created_at).toLocaleDateString()}</td>
                <td class="text-center">
                    <button class="btn btn-sm edit-btn btn btn-sm btn-outline-info" 
    data-id="${term.id}" 
    data-name="${term.term_name}" 
    data-marks="${term.max_marks}" 
    data-status="${term.status}">
    <i class="fas fa-edit"></i>
</button>
                    <button class="btn btn-sm btn-outline-danger delete-btn" 
        data-id="${term.id}" 
        title="Delete Term">
    <i class="fas fa-trash-alt"></i>
</button>
                </td>
            </tr>`;
        tableBody.insertAdjacentHTML('beforeend', row);
    });
}

// 5. Render Pagination (Fixed)
function renderPagination(meta) {
    const container = document.getElementById('paginationControls');
    container.innerHTML = '';

    if (meta.total_pages <= 1) return;

    // Previous Button
    const prevDisabled = (currentPage === 1) ? 'disabled' : '';
    container.innerHTML += `
        <li class="page-item ${prevDisabled}">
            <button class="page-link" onclick="loadExamTerms(${currentPage - 1})">Previous</button>
        </li>`;

    // Page Numbers
    for (let i = 1; i <= meta.total_pages; i++) {
        const activeClass = (i === currentPage) ? 'active' : '';
        container.innerHTML += `
            <li class="page-item ${activeClass}">
                <button class="page-link" onclick="loadExamTerms(${i})">${i}</button>
            </li>`;
    }

    // Next Button
    const nextDisabled = (currentPage === meta.total_pages) ? 'disabled' : '';
    container.innerHTML += `
        <li class="page-item ${nextDisabled}">
            <button class="page-link" onclick="loadExamTerms(${currentPage + 1})">Next</button>
        </li>`;
    // This forces the function to be visible to the HTML buttons
}
window.loadExamTerms = loadExamTerms;
//  ==========for edit exam terms ============================
// 1. Listen for clicks on the table (Event Delegation)
document.getElementById('examTermsTable').addEventListener('click', (e) => {
    // 1. Handle Edit Button
    const editBtn = e.target.closest('.edit-btn');
    if (editBtn) {
        const id = editBtn.getAttribute('data-id');
        const name = editBtn.getAttribute('data-name');
        const marks = editBtn.getAttribute('data-marks');

        const status = editBtn.getAttribute('data-status');

        document.getElementById('edit_term_id').value = id;
        document.getElementById('edit_term_name').value = name;
        document.getElementById('edit_max_marks').value = marks;

        document.getElementById('edit_status').value = status;

        const editModal = new bootstrap.Modal(document.getElementById('editExamModal'));
        editModal.show();
    }

    // 2. Handle Delete Button (ADDED THIS PART)
    const deleteBtn = e.target.closest('.delete-btn');
    if (deleteBtn) {
        const id = deleteBtn.getAttribute('data-id');
        deleteTerm(id); // Now the function below will actually run!
    }
});

// 2. Handle the Edit Form Submission
document.getElementById('editExamForm').addEventListener('submit', async (e) => {
    e.preventDefault();

    const formData = new FormData(e.target);
    // Add the action parameter for your API
    const url = `api/results/exam_term_manager.php?action=update`;

    try {
        const response = await fetch(url, {
            method: 'POST',
            body: formData
        });
        const result = await response.json();

        if (result.status === 'success') {
            Swal.fire('Updated!', 'Exam term updated successfully.', 'success');
            // Hide modal
            bootstrap.Modal.getInstance(document.getElementById('editExamModal')).hide();
            // Reload the current page of data
            loadExamTerms(currentPage);
        } else {
            Swal.fire('Error', result.message, 'error');
        }
    } catch (error) {
        console.error("Update Error:", error);
    }
});

// for delete exam terms ======================
async function deleteTerm(id) {
    const confirm = await Swal.fire({
        title: 'Are you sure?',
        text: "You won't be able to revert this!",
        icon: 'warning',
        showCancelButton: true,
        confirmButtonColor: '#d33',
        confirmButtonText: 'Yes, delete it!'
    });

    if (confirm.isConfirmed) {
        const formData = new FormData();
        formData.append('id', id);

        const response = await fetch('api/results/exam_term_manager.php?action=delete', {
            method: 'POST',
            body: formData
        });

        const result = await response.json();
        if (result.status === 'success') {
            Swal.fire('Deleted!', result.message, 'success');
            loadExamTerms(currentPage); // Refresh table
        } else {
            Swal.fire('Error!', result.message, 'error');
        }
    }
}


// =================load section dropdown for marks entry=================
document.addEventListener('DOMContentLoaded', () => {
    // 1. Initial Data Load
    loadClasses();
    loadMediums();
    loadExamTermsdropdown();

    const classSelect = document.getElementById('class_select');
    const sectionSelect = document.getElementById('section_select');
    const subjectSelect = document.getElementById('subject_select');
    const studentMarksTable = document.getElementById('studentMarksTable');

    /**
     * Function to fetch Subjects based on Class
     */
    async function updateSubjects(classId) {
        const subjectSelect = document.getElementById('subject_select');

        // Clear and show loading state
        subjectSelect.innerHTML = '<option value="">Loading subjects...</option>';
        subjectSelect.disabled = true;

        if (!classId) {
            subjectSelect.innerHTML = '<option value="">Select Subject</option>';
            return;
        }

        try {
            // Fetch subjects filtered only by Class
            const res = await fetch(`api/results/get_subjects.php?class_id=${classId}`);
            const subRes = await res.json();

            if (subRes.status === 'success') {
                // Clear loading option
                subjectSelect.innerHTML = '';

                if (subRes.data && subRes.data.length > 0) {
                    // Add default "Select" option
                    const defaultOpt = document.createElement('option');
                    defaultOpt.value = "";
                    defaultOpt.textContent = "Select Subject";
                    subjectSelect.appendChild(defaultOpt);

                    // Populate subjects
                    subRes.data.forEach(sub => {
                        const option = document.createElement('option');
                        option.value = sub.id;
                        option.textContent = sub.subject_name;
                        subjectSelect.appendChild(option);
                    });

                    subjectSelect.disabled = false;
                } else {
                    subjectSelect.innerHTML = '<option value="">No subjects found for this class</option>';
                    subjectSelect.disabled = true;
                }
            } else {
                subjectSelect.innerHTML = '<option value="">Error fetching subjects</option>';
                subjectSelect.disabled = true;
            }
        } catch (error) {
            console.error("Subject fetch error:", error);
            subjectSelect.innerHTML = '<option value="">Connection error</option>';
            subjectSelect.disabled = true;
        }
    }

    // 2. Class Change Listener
    classSelect.addEventListener('change', async function () {
        const classId = this.value;

        // Reset and Load UI for sections
        sectionSelect.innerHTML = '<option value="">Loading sections...</option>';
        sectionSelect.disabled = true;

        if (!classId) {
            sectionSelect.innerHTML = '<option value="">Select Section</option>';
            subjectSelect.innerHTML = '<option value="">Select Subject</option>';
            return;
        }

        try {
            // Fetch Sections
            const secRes = await fetch(`api/results/get_sections.php?class_id=${classId}`).then(r => r.json());

            // Populate Sections
            if (secRes.status === 'success') {
                sectionSelect.innerHTML = '<option value="">Select Section</option>';
                if (secRes.data.length > 0) {
                    secRes.data.forEach(sec => {
                        const opt = document.createElement('option');
                        opt.value = sec.id;
                        opt.textContent = sec.section_name;
                        sectionSelect.appendChild(opt);
                    });
                    sectionSelect.disabled = false;
                } else {
                    sectionSelect.innerHTML = '<option value="">No sections found</option>';
                }
            }

            // Load Subjects for the class
            updateSubjects(classId);

        } catch (error) {
            console.error('Error loading class details:', error);
            sectionSelect.innerHTML = '<option value="">Error loading sections</option>';
        }
    });

    // 3. Live Total Calculation
    studentMarksTable.addEventListener('input', (e) => {
        if (e.target.classList.contains('theory-input') || e.target.classList.contains('practical-input')) {
            const row = e.target.closest('tr');
            const theory = parseFloat(row.querySelector('.theory-input').value) || 0;
            const practical = parseFloat(row.querySelector('.practical-input').value) || 0;
            row.querySelector('.total-cell').textContent = (theory + practical).toFixed(1);
        }
    });

    // 4. Fetch Students and Open Modal
    document.getElementById('marksFilterForm').addEventListener('submit', async (e) => {
        e.preventDefault();

        const mediumSelect = document.getElementById('medium_select');
        const mediumId = mediumSelect.value;
        const mediumName = mediumId ? mediumSelect.options[mediumSelect.selectedIndex].text : '';

        const criteria = {
            class_id: classSelect.value,
            medium_id: mediumId,
            section_id: sectionSelect.value,
            subject_id: subjectSelect.value,
            term_id: document.getElementById('term_select').value
        };

        // Section Validation check
        const availableSections = sectionSelect.querySelectorAll('option:not([value=""])');
        const isSectionRequired = availableSections.length > 0;

        // Updated Validation Logic (Stream check removed)
        if (!criteria.class_id || !criteria.medium_id || !criteria.subject_id || !criteria.term_id ||
            (isSectionRequired && !criteria.section_id)) {

            Swal.fire('Required', 'Please ensure Class, Medium, Section, Subject, and Term are selected.', 'warning');
            return;
        }

        try {
            const submitBtn = e.target.querySelector('button[type="submit"]');
            const originalBtnText = submitBtn.innerHTML;
            submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Fetching...';
            submitBtn.disabled = true;

            // URL cleaned of stream_id
            const url = `api/results/get_students_for_marks.php?class_id=${criteria.class_id}&medium=${criteria.medium_id}&section_id=${criteria.section_id}&subject_id=${criteria.subject_id}&term_id=${criteria.term_id}`;

            const response = await fetch(url);
            const result = await response.json();

            submitBtn.innerHTML = originalBtnText;
            submitBtn.disabled = false;

            if (result.status === 'success') {
                const maxAllowed = result.max_allowed || 100;
                const tableBody = document.getElementById('studentMarksTable');
                tableBody.innerHTML = '';

                if (!result.data || result.data.length === 0) {
                    Swal.fire('No Data', 'No students found for the selected criteria.', 'info');
                    return;
                }

                // Update UI Labels
                document.getElementById('display_class').textContent = `Class: ${classSelect.options[classSelect.selectedIndex].text} (${mediumName})`;
                document.getElementById('display_section').textContent = `Section: ${criteria.section_id ? sectionSelect.options[sectionSelect.selectedIndex].text : 'N/A'}`;
                document.getElementById('display_subject').textContent = `Subject: ${subjectSelect.options[subjectSelect.selectedIndex].text}`;
                document.getElementById('display_term').textContent = `Term: ${document.getElementById('term_select').options[document.getElementById('term_select').selectedIndex].text}`;

                // Inject Hidden IDs
                document.getElementById('hidden_class_id').value = criteria.class_id;
                document.getElementById('hidden_section_id').value = criteria.section_id;
                document.getElementById('hidden_subject_id').value = criteria.subject_id;
                document.getElementById('hidden_term_id').value = criteria.term_id;
                if (document.getElementById('hidden_medium_id')) {
                    document.getElementById('hidden_medium_id').value = criteria.medium_id;
                }

                result.data.forEach(student => {
                    const theory = student.theory_marks !== null ? student.theory_marks : '';
                    const practical = student.practical_marks !== null ? student.practical_marks : '';
                    const total = (Number(theory) || 0) + (Number(practical) || 0);

                    const row = `
                        <tr>
                            <td class="ps-4 fw-bold">${student.roll_no}</td>
                            <td>${student.student_name}</td>
                            <td>
                                <input type="number" name="marks[${student.student_id}][theory]" 
                                    class="form-control theory-input" min="0" max="${maxAllowed}" step="0.5" value="${theory}">
                            </td>
                            <td class="practical-col">
                                <input type="number" name="marks[${student.student_id}][practical]" 
                                    class="form-control practical-input" min="0" max="${maxAllowed}" step="0.5" value="${practical}">
                            </td>
                            <td class="pe-4 text-end fw-bold total-cell">${total}</td>
                        </tr>`;
                    tableBody.insertAdjacentHTML('beforeend', row);
                });

                const showPractical = maxAllowed > 25;
                document.querySelectorAll('.practical-col, .practical-col-header').forEach(el => el.style.display = showPractical ? 'table-cell' : 'none');

                bootstrap.Modal.getOrCreateInstance(document.getElementById('markEntryModal')).show();
            } else {
                Swal.fire('Error', result.message, 'error');
            }
        } catch (error) {
            console.error(error);
            Swal.fire('Error', 'An unexpected error occurred.', 'error');
        }
    });
});
//================= for medium =============== 
async function loadMediums() {
    const mediumSelect = document.getElementById('medium_select');
    if (!mediumSelect) return;

    try {
        const res = await fetch("api/mediums/get_mediums.php");
        const result = await res.json(); // Renamed variable to 'result' for clarity

        // Access the 'data' property specifically
        if (result.status && Array.isArray(result.data)) {
            mediumSelect.innerHTML = '<option value="">Select</option>';
            result.data.forEach(m => {
                const option = document.createElement('option');
                option.value = m.id; // Use ID here instead of name
                option.textContent = m.medium_name;
                mediumSelect.appendChild(option);
            });
        } else {
            console.error("API Error or Empty Data:", result.msg);
            mediumSelect.innerHTML = '<option value="">No Mediums Found</option>';
        }
    } catch (e) {
        console.error("Fetch Error:", e);
        mediumSelect.innerHTML = '<option value="">Error</option>';
    }
}
// Updated loadClasses (Removed static loadSections from bottom)
async function loadClasses() {
    const classSelect = document.getElementById('class_select');
    try {
        const response = await fetch('api/results/get_classes.php');
        const result = await response.json();
        if (result.status === 'success') {
            classSelect.innerHTML = '<option value="">Select Class</option>';
            result.data.forEach(cls => {
                const option = document.createElement('option');
                option.value = cls.id;
                option.textContent = cls.class_name;
                classSelect.appendChild(option);
            });
        }
    } catch (error) { console.error('Error loading classes:', error); }
}

async function loadExamTermsdropdown() {
    const termSelect = document.getElementById('term_select');
    try {
        const response = await fetch('api/results/get_exam_terms.php');
        const result = await response.json();
        if (result.status === 'success') {
            termSelect.innerHTML = '<option value="">Select Term</option>';
            result.data.filter(t => t.status == 1).forEach(term => {
                const option = document.createElement('option');
                option.value = term.id;
                option.textContent = term.term_name;
                termSelect.appendChild(option);
            });
        }
    } catch (error) { console.error('Error loading terms:', error); }
}

// =============save marks =======================
document.getElementById('saveMarksForm').addEventListener('submit', async function (e) {
    e.preventDefault();

    const btn = e.target.querySelector('button[type="submit"]');
    const originalContent = btn.innerHTML;

    btn.disabled = true;
    btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Saving...';

    try {
        const myFormData = new FormData(this);

        // --- UPDATED: stream_id removed. Only medium_id is appended from the main filter ---
        const mediumVal = document.getElementById('medium_select').value;
        myFormData.append('medium_id', mediumVal || 0);

        const response = await fetch('api/results/save_marks.php', {
            method: 'POST',
            body: myFormData
        });

        const rawResponse = await response.text();

        let result;
        try {
            result = JSON.parse(rawResponse);
        } catch (parseError) {
            console.error("JSON Parse Error. Server sent:", rawResponse);
            throw new Error("Server response was not valid JSON.");
        }

        if (result.status === 'success') {
            Swal.fire({
                icon: 'success',
                title: 'Saved!',
                text: result.message,
                timer: 2000,
                showConfirmButton: false
            });

            const modalElem = document.getElementById('markEntryModal');
            const modalInstance = bootstrap.Modal.getInstance(modalElem);
            if (modalInstance) modalInstance.hide();
        } else {
            Swal.fire('Error', result.message, 'error');
        }
    } catch (err) {
        Swal.fire('Error', err.message, 'error');
    } finally {
        btn.disabled = false;
        btn.innerHTML = originalContent;
    }
});
document.getElementById('studentMarksTable').addEventListener('input', function (e) {
    if (e.target.type === 'number') {
        const input = e.target;
        const val = parseFloat(input.value);
        const max = parseFloat(input.getAttribute('max'));

        // 1. Prevent Negative Values
        if (val < 0) {
            input.value = 0;
        }

        // 2. Prevent Exceeding Max Marks
        if (max && val > max) {
            input.value = max;
        }

        // 3. Update the Total column immediately
        const row = input.closest('tr');
        const theory = parseFloat(row.querySelector('.theory-input').value) || 0;
        const practical = parseFloat(row.querySelector('.practical-input').value) || 0;

        // This targets the <td> with class "total-cell" in this specific row
        const totalCell = row.querySelector('.total-cell');
        if (totalCell) {
            totalCell.textContent = (theory + practical).toFixed(2);
        }
    }
});

// ==================tabulation all  the students ======================
//  ===========class , section and exam terms dropdown ==============
// Run on page load
document.addEventListener('DOMContentLoaded', () => {
    initDropdowns();
});

// --- LOADER UTILITY ---
function showLoader(status) {
    const loader = document.getElementById('loader');
    const content = document.getElementById('tabulationResultCard');

    if (status) {
        loader.classList.remove('d-none');
        content.classList.add('d-none');
    } else {
        setTimeout(() => {
            loader.classList.add('d-none');
            content.classList.remove('d-none');
        }, 300);
    }
}

async function initDropdowns() {
    try {
        // Fetch Class, Term, and Medium data in parallel
        const [classRes, termRes, medRes] = await Promise.all([
            fetch('api/results/get_classes.php'),
            fetch('api/results/get_exam_terms.php'),
            fetch('api/mediums/get_mediums.php')
        ]);

        const classes = await classRes.json();
        const terms = await termRes.json();
        const mediums = await medRes.json();

        // 1. Populate Classes
        const classSelect = document.getElementById('tab_class');
        if (classSelect) {
            let classHtml = '<option value="">-- Choose Class --</option>';
            if (classes.status === 'success' || classes.status === true) {
                classes.data.forEach(c => classHtml += `<option value="${c.id}">${c.class_name}</option>`);
            }
            classSelect.innerHTML = classHtml;
        }

        // 2. Populate Terms
        const termSelect = document.getElementById('tab_term');
        if (termSelect) {
            let termHtml = '<option value="">-- Choose Term --</option>';
            if (terms.status === 'success' || terms.status === true) {
                terms.data.forEach(t => termHtml += `<option value="${t.id}">${t.term_name}</option>`);
            }
            termSelect.innerHTML = termHtml;
        }

        // 3. Populate Mediums (Flexible Status Check)
        const medSelect = document.getElementById('tab_medium');
        if (medSelect) {
            let medHtml = '<option value="">-- Choose Medium --</option>';

            // This check now handles BOTH "success" (string) and true (boolean)
            const isMedSuccess = (mediums.status === 'success' || mediums.status === true);

            if (isMedSuccess && Array.isArray(mediums.data)) {
                mediums.data.forEach(m => {
                    medHtml += `<option value="${m.id}">${m.medium_name}</option>`;
                });
            } else {
                console.error("Medium Load Error:", mediums.message || mediums.msg || "Unknown error");
                medHtml = '<option value="">Failed to load</option>';
            }
            medSelect.innerHTML = medHtml;
        }

    } catch (err) {
        console.error("Critical Initialization Failure:", err);
    }
}

async function handleClassChange(classId) {
    const secSelect = document.getElementById('tab_section');
    const classSelect = document.getElementById('tab_class');

    // Reset Section dropdown if no class is selected
    if (!classId) {
        secSelect.disabled = true;
        secSelect.innerHTML = '<option value="">Select Class First</option>';
        return;
    }

    // Stream Logic removed: No more checking for Class 11/12 or toggling containers

    // --- SECTION LOGIC ---
    try {
        const res = await fetch(`api/results/get_sections.php?class_id=${classId}`);
        const result = await res.json();

        let html = '<option value="">-- Choose Section --</option>';

        if (result.status === 'success' && result.data.length > 0) {
            secSelect.disabled = false;
            result.data.forEach(s => {
                html += `<option value="${s.id}">${s.section_name}</option>`;
            });
            secSelect.innerHTML = html;
        } else {
            // Default to "No Sections" if array is empty or call fails
            secSelect.innerHTML = '<option value="0">No Sections Available</option>';
            secSelect.disabled = true;

            // Trigger filter check immediately since no further selection is needed here
            if (typeof checkFilters === "function") {
                checkFilters();
            }
        }
    } catch (err) {
        console.error("Error fetching sections:", err);
        secSelect.innerHTML = '<option value="">Error loading sections</option>';
        secSelect.disabled = true;
    }
}

// Helper to load streams for the tabulation form


function checkFilters() {
    const classId = document.getElementById('tab_class').value;
    const mediumId = document.getElementById('tab_medium').value;
    const termId = document.getElementById('tab_term').value;

    const sectionSelect = document.getElementById('tab_section');
    const sectionId = sectionSelect.value;

    // Logic for validation: Section is valid if the dropdown is disabled (no sections) 
    // or if a section is actually selected.
    const isSectionValid = sectionSelect.disabled ? true : (sectionId !== "");

    // Stream validation logic removed completely

    // Must have Class, Medium, Term, and valid Section
    if (classId && mediumId && termId && isSectionValid) {
        showLoader(true);
        // Load data with stream parameter removed
        loadTabulationData(classId, sectionId, termId, mediumId);
    } else {
        // Hide result card if filters are incomplete
        document.getElementById('tabulationResultCard').classList.add('d-none');
    }
}
// ==============load tabulation data result ===============
let currentSchoolInfo = {}; // Global variable to hold school data
// Added mediumId and streamId to arguments
async function loadTabulationData(classId, sectionId, termId, mediumId) {
    const tabBody = document.getElementById('tabBody');
    const tabHead = document.getElementById('tabHead');
    const tabInfo = document.getElementById('tabulationInfo');

    const cleanSectionId = (sectionId === "0" || !sectionId) ? "" : sectionId;

    tabBody.innerHTML = `
        <tr>
            <td colspan="100" class="text-center py-5">
                <div class="spinner-border text-primary"></div>
                <p class="mt-2 text-muted">Calculating Tabulation...</p>
            </td>
        </tr>
    `;

    try {
        const url = `api/results/get_tabulation.php?class_id=${classId}&section_id=${cleanSectionId}&term_id=${termId}&medium_id=${mediumId}`;
        const response = await fetch(url);
        const res = await response.json();

        if (res.status !== 'success') {
            tabBody.innerHTML = `<tr><td colspan="100" class="text-center text-danger py-4 font-monospace">${res.message}</td></tr>`;
            if (typeof showLoader === "function") showLoader(false);
            return;
        }

        window.lastResponse = res;
        const { subjects, students, term_max } = res;
        const finalTermMax = parseInt(term_max) || 100;
        const isAnnual = (finalTermMax === 100);
        
        // Logic: Pass mark is 30% of subject max (e.g. 7.5 for 25, 30 for 100)
        const passThreshold = finalTermMax * 0.3;

        if (tabInfo) {
            tabInfo.innerHTML = `
                <div class="d-flex flex-wrap gap-2 mb-3">
                    <span class="badge bg-secondary p-2">Class: ${res.class_name}</span>
                    <span class="badge bg-info text-dark p-2">Medium: ${res.medium_name}</span>
                    <span class="badge bg-dark p-2">Pass Mark: ${passThreshold} / ${finalTermMax}</span>
                </div>
            `;
        }

        /* ---------- DYNAMIC TABLE HEADER ---------- */
        let headerRow1 = `<tr class="text-center bg-light align-middle"><th rowspan="2">Roll</th><th rowspan="2" style="min-width:200px;">Student & Father's Name</th>`;
        let headerRow2 = `<tr class="text-center bg-light">`;

        subjects.forEach(s => {
            const hasPr = parseInt(s.practical_max) > 0;
            headerRow1 += `<th colspan="${hasPr ? 3 : 1}" class="border-start border-end">${s.subject_name}</th>`;
            if (hasPr) {
                headerRow2 += `<th class="small text-muted border-start">TH</th><th class="small text-muted">PR</th><th class="small fw-bold">TOT</th>`;
            } else {
                headerRow2 += `<th class="small text-muted border-start border-end">Marks</th>`;
            }
        });

        headerRow1 += `<th rowspan="2" class="bg-light border-start">Grand Total</th><th rowspan="2" class="bg-light">%</th><th rowspan="2">Division/Honors</th><th rowspan="2" class="d-print-none">Action</th></tr>`;
        tabHead.innerHTML = headerRow1 + headerRow2 + `</tr>`;

        /* ---------- STUDENT ROWS ---------- */
        tabBody.innerHTML = students.map(st => {
            let rowTotal = 0;
            let hasFailedSubject = false;
            const totalPossibleWeight = subjects.length * finalTermMax;

            const marksCells = subjects.map(sub => {
                const m = st.marks?.[sub.id];
                const hasPr = parseInt(sub.practical_max) > 0;
                const tot = m ? (Number(m.tot) || 0) : 0;
                rowTotal += tot;

                // CHECK: Did the student pass this specific subject?
                if (tot < passThreshold) {
                    hasFailedSubject = true;
                }

                let letterMark = (isAnnual && tot >= 80) ? '<span class="text-danger fw-bold"> (L)</span>' : '';
                
                // Visual Indicator: Fail marks shown in red
                const cellStyle = (tot < passThreshold) ? 'text-danger fw-bold' : '';

                if (hasPr) {
                    return `<td class="text-center border-start">${m?.th || 0}</td><td class="text-center">${m?.pr || 0}</td><td class="text-center fw-bold bg-light ${cellStyle}">${tot}${letterMark}</td>`;
                } else {
                    return `<td class="text-center border-start border-end fw-bold bg-light ${cellStyle}">${tot}${letterMark}</td>`;
                }
            }).join('');

            const percentage = totalPossibleWeight ? (rowTotal / totalPossibleWeight) * 100 : 0;

            /* ---------- DIVISION LOGIC (ENFORCED PASS) ---------- */
            let studentDivision = "FAILED";
            let badgeClass = "bg-danger";

            // ONLY calculate division if student passed ALL subjects
            if (!hasFailedSubject) {
                if (percentage >= 60) {
                    studentDivision = "1st Division";
                    badgeClass = "bg-primary";
                } else if (percentage >= 45) {
                    studentDivision = "2nd Division";
                    badgeClass = "bg-info text-dark";
                } else if (percentage >= 30) {
                    studentDivision = "3rd Division";
                    badgeClass = "bg-secondary";
                }

                // Honors: Only for Annual (100 marks) AND Passed all subjects
                if (isAnnual) {
                    if (percentage >= 95) {
                        studentDivision = "Stand Mark";
                        badgeClass = "bg-warning text-dark border border-dark fw-bold";
                    } else if (percentage >= 85) {
                        studentDivision = "Distinction";
                        badgeClass = "bg-success shadow-sm fw-bold";
                    } else if (percentage >= 75) {
                        studentDivision = "Star Mark";
                        badgeClass = "bg-success";
                    }
                }
            }

            return `
                <tr class="${hasFailedSubject ? 'table-warning' : ''}">
                    <td class="text-center fw-bold align-middle">${st.roll}</td>
                    <td class="align-middle">
                        <div class="fw-bold text-primary">${st.name}</div>
                        <div class="small text-muted" style="font-size: 0.75rem;">F: ${st.father_name || '---'}</div>
                    </td>
                    ${marksCells}
                    <td class="text-center fw-bold text-dark bg-light align-middle border-start">${rowTotal} / ${totalPossibleWeight}</td>
                    <td class="text-center fw-bold bg-light align-middle">${percentage.toFixed(1)}%</td>
                    <td class="text-center align-middle"><span class="badge ${badgeClass} py-2 px-3">${studentDivision}</span></td>
                    <td class="text-center d-print-none align-middle">
                        <button class="btn btn-sm btn-outline-dark" onclick="downloadSinglePDF(${st.sid}, ${classId}, ${termId})">
                            <i class="fas fa-print"></i>
                        </button>
                    </td>
                </tr>`;
        }).join('');

        if (typeof showLoader === "function") showLoader(false);

    } catch (err) {
        console.error("Tabulation Error:", err);
        tabBody.innerHTML = `<tr><td colspan="100" class="text-center text-danger py-4">Error loading data.</td></tr>`;
        if (typeof showLoader === "function") showLoader(false);
    }
}
// ================single students marks sheet =================
function downloadSinglePDF(studentId, classId, termId) {
           
    // 1. Check if the tabulation data was actually loaded
    // Fixed logic: (window.lastResponse.status !== 'success')
    if (!window.lastResponse || window.lastResponse.status !== 'success') {
        Swal.fire({
            icon: 'warning',
            title: 'Data Not Loaded',
            text: 'Please click "Search" to load the tabulation first.'
        });
        return;
    }

    // 3. Final validation before opening the PDF
    if (!studentId || !termId || !classId) {
        console.error("Missing Data:", { studentId, termId, classId });
        Swal.fire('Error', 'Required IDs are missing. Please refresh and try again.', 'error');
        return;
    }

    // 4. Corrected variable names in the URL string
    const url = `api/results/generate_marksheet_single_pdf.php?student_id=${studentId}&class_id=${classId}&term_id=${termId}`;

    // Open in new tab
    window.open(url, '_blank');
}

//================= export to excel csv ============
function exportToExcel() {
    const table = document.getElementById("tabulationTable");
    let csv = [];
    const rows = table.querySelectorAll("tr");

    for (let i = 0; i < rows.length; i++) {
        let row = [], cols = rows[i].querySelectorAll("td, th");
        for (let j = 0; j < cols.length; j++) {
            // Clean text and handle commas
            let data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, "").replace(/,/g, ";");
            row.push(data);
        }
        csv.push(row.join(","));
    }

    const csvFile = new Blob([csv.join("\n")], { type: "text/csv" });
    const downloadLink = document.createElement("a");
    downloadLink.download = `Tabulation_Sheet_${new Date().toLocaleDateString()}.csv`;
    downloadLink.href = window.URL.createObjectURL(csvFile);
    downloadLink.style.display = "none";
    document.body.appendChild(downloadLink);
    downloadLink.click();
}

//================= print pdf all marksheet =================
function downloadAllMarksheetsPDF() {
    if (!window.lastResponse) {
        Swal.fire('Error', "Please load the tabulation data first.", 'warning');
        return;
    }

    // Get current filter values
    const classId = document.getElementById('tab_class').value;
    const termId = document.getElementById('tab_term').value;
    const mediumId = document.getElementById('tab_medium').value;
    const sectionId = document.getElementById('tab_section').value;

    // Construct URL with parameters
    const params = new URLSearchParams({
        class_id: classId,
        term_id: termId,
        medium_id: mediumId,
        section_id: sectionId || 0,
        bulk: 1 // Flag to tell PHP to generate all marksheets
    });

    // Open in new tab to trigger download
    window.open(`api/results/generate_all_marksheets_pdf.php?${params.toString()}`, '_blank');
}
//===============  for class wise ==============
function downloadTabulationPDF() {
    const classId = document.getElementById('tab_class').value;
    const termId = document.getElementById('tab_term').value;
    const mediumId = document.getElementById('tab_medium').value;
    const sectionId = document.getElementById('tab_section').value;

    // Validation: Ensure the core filters are selected
    if (!classId || !termId || !mediumId) {
        Swal.fire({
            icon: 'warning',
            title: 'Incomplete Filters',
            text: 'Please select Class, Term, and Medium first'
        });
        return;
    }

    // Prepare parameters without stream_id
    const params = new URLSearchParams({
        class_id: classId,
        term_id: termId,
        medium_id: mediumId,
        section_id: sectionId || '' // Section remains optional (0 or empty means "All")
    });

    // Open the PDF generation script in a new tab
    const pdfUrl = `api/results/generate_tabulation_pdf.php?${params.toString()}`;
    window.open(pdfUrl, '_blank');
}