/**
 * Custom JavaScript for Result Management System for Institutions plugin.
 * Handles dynamic dropdown population, modal display/hide logic, form validation,
 * clipboard operations, and mark calculations across various admin pages.
 *
 * Features:
 * - Dynamically loads departments, exams, subjects, and sections via AJAX based on selected class/department.
 * - Updates hidden fields for class/department/exam year as needed.
 * - Modal show/hide logic for add/edit forms on multiple admin pages.
 * - Validates CSV file uploads for record addition.
 * - Copies URLs to clipboard with fallback for older browsers.
 * - Loads Bootstrap CSS for student listing page.
 * - Calculates total marks in add-mark and exam-name pages.
 * - Handles grade row display logic in settings page.
 *
 * Dependencies:
 * - jQuery
 * - WordPress AJAX object (`astgdrmsys_ajax_object`)
 *
 * @file custom.js
 * @since 1.0.0
 */
jQuery(document).ready(function ($) {
  function astgdrmsysEscapeHtml(value) {
    var str = value === null || value === undefined ? "" : String(value);

    return str
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
  }

  function astgdrmsysEscapeAttribute(value) {
    return astgdrmsysEscapeHtml(value);
  }

  const isBulkCsvPage = window.location.href.includes(
    "admin.php?page=astgdrmsys-generate-bulk-csv"
  );

  if (isBulkCsvPage) {
    const $partialForm = $(".astgdrmsys-partial-form");
    if ($partialForm.length) {
      const $partialClass = $partialForm.find(".astgdrmsys-partial-class");
      const $partialExam = $partialForm.find(".astgdrmsys-partial-exam");
      const $partialSubject = $partialForm.find(".astgdrmsys-partial-subject");

      const parseExamId = (examValue) => {
        if (!examValue) {
          return "";
        }

        const parts = examValue.split(",");
        return parts[0] || "";
      };

      const setPartialSubjectPlaceholder = (message) => {
        $partialSubject.html(
          '<option value="" selected disabled>' + astgdrmsysEscapeHtml(message) + "</option>"
        );
      };

      const loadPartialSubjects = (examId, preselectedSubject = "") => {
        if (!examId) {
          setPartialSubjectPlaceholder("Select Exam First");
          return;
        }

        $partialSubject.html('<option value="">Loading...</option>');

        $.ajax({
          url: astgdrmsys_ajax_object.ajaxurl,
          type: "POST",
          dataType: "json",
          data: {
            action: "astgdrmsys_get_subjects_by_exam",
            exam_id: examId,
            nonce: astgdrmsys_ajax_object.nonce,
          },
          success: function (response) {
            if (response.success && Array.isArray(response.data) && response.data.length) {
              let options =
                '<option value="" disabled>Select Subject</option>';
              response.data.forEach(function (subject) {
                const value = subject.id + "|" + subject.subcode;
                options +=
                  '<option value="' +
                  astgdrmsysEscapeAttribute(value) +
                  '" ' +
                  (value === preselectedSubject ? "selected" : "") +
                  ">" +
                  astgdrmsysEscapeHtml(subject.subname) +
                  " - " +
                  astgdrmsysEscapeHtml(subject.subcode) +
                  "</option>";
              });

              $partialSubject.html(options);

              if (!preselectedSubject && response.data.length === 1) {
                $partialSubject.val(response.data[0].id + "|" + response.data[0].subcode);
              }
            } else {
              setPartialSubjectPlaceholder("No subjects found for the selected exam");
            }
          },
          error: function () {
            setPartialSubjectPlaceholder("Failed to load subjects");
          },
        });
      };

      $partialClass.on("change", function () {
        const classId = $(this).val();

        if (!classId) {
          $partialExam.html(
            '<option value="" selected disabled>Select Class First</option>'
          );
          setPartialSubjectPlaceholder("Select Exam First");
          return;
        }

        $partialExam.html('<option value="">Loading...</option>');
        setPartialSubjectPlaceholder("Select Exam First");

        $.ajax({
          url: astgdrmsys_ajax_object.ajaxurl,
          type: "POST",
          dataType: "json",
          data: {
            action: "astgdrmsys_get_exam_names_by_class",
            class: classId,
            nonce: astgdrmsys_ajax_object.nonce,
          },
          success: function (response) {
            if (response.success && Array.isArray(response.data) && response.data.length) {
              let options =
                '<option value="" disabled>Select Exam</option>';
              response.data.forEach(function (exam) {
                const optionValue = exam.id + "," + exam.exam_year_id;
                options +=
                  '<option value="' +
                  astgdrmsysEscapeAttribute(optionValue) +
                  '">' +
                  astgdrmsysEscapeHtml(exam.exam_name) +
                  " - " +
                  astgdrmsysEscapeHtml(exam.exam_year) +
                  "</option>";
              });
              $partialExam.html(options);

               if (response.data.length === 1) {
                 const autoExamValue = response.data[0].id + "," + response.data[0].exam_year_id;
                 $partialExam.val(autoExamValue);
                 loadPartialSubjects(parseExamId(autoExamValue));
               }
            } else {
              $partialExam.html(
                '<option value="" selected disabled>No exams found</option>'
              );
            }
          },
          error: function () {
            $partialExam.html(
              '<option value="" selected disabled>Failed to load exams</option>'
            );
          },
        });
      });

      $partialExam.on("change", function () {
        const examValue = $(this).val();

        if (!examValue) {
          setPartialSubjectPlaceholder("Select Exam First");
          return;
        }

        const examId = parseExamId(examValue);
        loadPartialSubjects(examId);
      });

      const preselectedExamValue = $partialExam.val();
      if (preselectedExamValue) {
        loadPartialSubjects(parseExamId(preselectedExamValue), $partialSubject.val());
      }
    }
  }

  function setBulkCsvExamPlaceholder(message) {
    if (!isBulkCsvPage) {
      return;
    }
    $(".astgdrmsys-bulk-csv-form .selectExam").html(
      '<option value="" selected disabled>' + astgdrmsysEscapeHtml(message) + "</option>"
    );
  }

  // Handle class change

  $(".selectClass").on("change", function () {
    var class_id = $(this).val();

    if (isBulkCsvPage) {
      var $form = $(".astgdrmsys-bulk-csv-form");
      var $departmentSelect = $form.find(".selectDepartment");

      setBulkCsvExamPlaceholder("Select Department First");

      if (!class_id) {
        $departmentSelect.html(
          '<option value="" selected disabled>Select Class First</option>'
        );
        return;
      }

      $departmentSelect.html('<option value="">Loading...</option>');

      $.ajax({
        url: astgdrmsys_ajax_object.ajaxurl,
        type: "POST",
        dataType: "json",
        data: {
          action: "astgdrmsys_get_departments_by_class",
          class: class_id,
          nonce: astgdrmsys_ajax_object.nonce,
        },
        success: function (response) {
          if (response.success && Array.isArray(response.data) && response.data.length) {
            var options =
              '<option value="" selected disabled>Select Department</option>';
            response.data.forEach(function (department) {
              options +=
                '<option value="' +
                astgdrmsysEscapeAttribute(department.id) +
                '">' +
                astgdrmsysEscapeHtml(department.department) +
                "</option>";
            });
            $departmentSelect.html(options);
          } else {
            $departmentSelect.html(
              '<option value="" selected disabled>No departments found</option>'
            );
          }
        },
        error: function () {
          $departmentSelect.html(
            '<option value="" selected disabled>Failed to load departments</option>'
          );
        },
      });

      return;
    }

    var $departmentSelect = $(".selectDepartment");
    var $examSelect = $(".selectExam");
    var $subjectSelect = $(".selectSubject");

    if (!class_id) {
      if ($departmentSelect.length) {
        $departmentSelect.html(
          '<option value="" selected disabled>Select Class First</option>'
        );
      }

      if ($examSelect.length) {
        $examSelect.html(
          '<option value="" selected disabled>Select Class First</option>'
        );
      }

      if ($subjectSelect.length) {
        $subjectSelect.html(
          '<option value="" selected disabled>Select Class First</option>'
        );
      }

      return;
    }

    if (!$departmentSelect.length) {
      if ($examSelect.length) {
        $examSelect.html('<option value="">Loading...</option>');

        $.ajax({
          url: astgdrmsys_ajax_object.ajaxurl,
          type: "POST",
          dataType: "json",
          data: {
            action: "astgdrmsys_get_exam_names_by_class",
            class: class_id,
            nonce: astgdrmsys_ajax_object.nonce,
          },
          success: function (response) {
            if (response.success && Array.isArray(response.data) && response.data.length) {
              var options =
                '<option value="" selected disabled>Select Exam</option>';

              response.data.forEach(function (exam) {
                options +=
                  '<option value="' +
                  astgdrmsysEscapeAttribute(exam.id) +
                  "," +
                  astgdrmsysEscapeAttribute(exam.exam_year_id) +
                  '">' +
                  astgdrmsysEscapeHtml(exam.exam_name) +
                  " - " +
                  astgdrmsysEscapeHtml(exam.exam_year) +
                  "</option>";
              });

              $examSelect.html(options);
            } else {
              $examSelect.html(
                '<option value="" selected disabled>No exams found</option>'
              );
            }
          },
          error: function () {
            $examSelect.html(
              '<option value="" selected disabled>Failed to load exams</option>'
            );
          },
        });
      }

      if ($subjectSelect.length) {
        $subjectSelect.html(
          '<option value="" selected disabled>Select Exam First</option>'
        );
      }

      return;
    }

    $departmentSelect.html('<option value="">Loading...</option>');

    if ($examSelect.length) {
      $examSelect.html(
        '<option value="" selected disabled>Select Department First</option>'
      );
    }

    if ($subjectSelect.length) {
      $subjectSelect.html(
        '<option value="" selected disabled>Select Department First</option>'
      );
    }

    $.ajax({
      url: astgdrmsys_ajax_object.ajaxurl,
      type: "POST",
      dataType: "json",
      data: {
        action: "astgdrmsys_get_departments_by_class",
        class: class_id,
        nonce: astgdrmsys_ajax_object.nonce,
      },
      success: function (response) {
        if (response.success && Array.isArray(response.data) && response.data.length) {
          var departmentOptions =
            '<option value="" selected disabled>Select Department</option>';

          response.data.forEach(function (department) {
            departmentOptions +=
              '<option value="' +
              astgdrmsysEscapeAttribute(department.id) +
              '">' +
              astgdrmsysEscapeHtml(department.department) +
              "</option>";
          });

          $departmentSelect.html(departmentOptions);
        } else {
          console.error("Error:", response.data);
          $departmentSelect.html(
            '<option value="" selected disabled>No departments found</option>'
          );

          if ($examSelect.length) {
            $examSelect.html(
              '<option value="" selected disabled>No exams available</option>'
            );
          }

          if ($subjectSelect.length) {
            $subjectSelect.html(
              '<option value="" selected disabled>No subjects available</option>'
            );
          }
        }
      },
      error: function (xhr, status, error) {
        console.error("AJAX error:", xhr, status, error);
        $departmentSelect.html(
          '<option value="" selected disabled>Failed to load departments</option>'
        );

        if ($examSelect.length) {
          $examSelect.html(
            '<option value="" selected disabled>Failed to load exams</option>'
          );
        }

        if ($subjectSelect.length) {
          $subjectSelect.html(
            '<option value="" selected disabled>Failed to load subjects</option>'
          );
        }
      },
    });
  });

  // Handle department change
  $(".selectDepartment").on("change", function () {
    var department_id = $(this).val();
    var includePublished = $(this).data("includePublished") ? 1 : 0;

    if (isBulkCsvPage) {
      $(".selectSection").html(
        '<option value="" selected disabled>Select Section</option>'
      );

      $.ajax({
        url: astgdrmsys_ajax_object.ajaxurl,
        type: "POST",
        dataType: "json",
        data: {
          action: "astgdrmsys_get_sections_by_department",
          department: department_id,
          nonce: astgdrmsys_ajax_object.nonce,
        },
        success: function (response) {
          if (response.success) {
            var sections = response.data;
            var sectionOptions =
              '<option value="" selected disabled>Select Section</option>';
            sections.forEach(function (section) {
              sectionOptions +=
                '<option value="' +
                astgdrmsysEscapeAttribute(section.id) +
                '">' +
                astgdrmsysEscapeHtml(section.section) +
                "</option>";
            });
            $(".selectSection").html(sectionOptions);
          } else {
            $(".selectSection").html(
              '<option value="" selected disabled>Failed to load sections</option>'
            );
          }
        },
        error: function (_xhr, status, error) {
          console.error("AJAX error:", status, error);
          $(".selectSection").html(
            '<option value="" selected disabled>Failed to load sections</option>'
          );
        },
      });

      var classId = $(".astgdrmsys-bulk-csv-form .selectClass").val();
      var $examSelect = $(".astgdrmsys-bulk-csv-form .selectExam");

      if (!department_id) {
        setBulkCsvExamPlaceholder("Select Department");
        return;
      }

      if (!classId) {
        setBulkCsvExamPlaceholder("Select Class First");
        return;
      }

      $examSelect.html('<option value="">Loading...</option>');

      var bulkExamRequest = {
        action: "astgdrmsys_get_exam_names_by_class_and_department",
        class: classId,
        department: department_id,
        nonce: astgdrmsys_ajax_object.nonce,
      };

      if (includePublished) {
        bulkExamRequest.include_published = 1;
      }

      $.ajax({
        url: astgdrmsys_ajax_object.ajaxurl,
        type: "POST",
        dataType: "json",
        data: bulkExamRequest,
        success: function (response) {
          if (response.success && Array.isArray(response.data) && response.data.length) {
            var options =
              '<option value="" selected disabled>Select Exam</option>';
            response.data.forEach(function (exam) {
              options +=
                '<option value="' +
                astgdrmsysEscapeAttribute(exam.id) +
                "," +
                astgdrmsysEscapeAttribute(exam.exam_year_id) +
                '">' +
                astgdrmsysEscapeHtml(exam.exam_name) +
                " - " +
                astgdrmsysEscapeHtml(exam.exam_year) +
                "</option>";
            });
            $examSelect.html(options);
          } else {
            setBulkCsvExamPlaceholder("No exams found");
          }
        },
        error: function () {
          setBulkCsvExamPlaceholder("Failed to load exams");
        },
      });

      return;
    }

    // Clear the sections dropdown
    $(".selectSection").html('<option value="">Loading...</option>');

    // Make the AJAX request to fetch sections
    $.ajax({
      url: astgdrmsys_ajax_object.ajaxurl,
      type: "POST",
      dataType: "json",
      data: {
        action: "astgdrmsys_get_sections_by_department",
        department: department_id,
        nonce: astgdrmsys_ajax_object.nonce,
      },
      success: function (response) {
        if (response.success) {
          var sections = response.data; // Access the data directly
          var sectionOptions =
            '<option value="" selected disabled>Select Section</option>';
          sections.forEach(function (section) {
            sectionOptions +=
              '<option value="' +
              astgdrmsysEscapeAttribute(section.id) +
              '">' +
              astgdrmsysEscapeHtml(section.section) +
              "</option>";
          });
          $(".selectSection").html(sectionOptions);
        } else {
          console.error("Error:", response.data);
          $(".selectSection").html(
            '<option value="">Error loading sections</option>'
          );
        }
      },
      error: function (_xhr, status, error) {
        console.error("AJAX error:", status, error);
        $(".selectSection").html(
          '<option value="">Failed to load sections</option>'
        );
      },
    });

    var currentClassId = $(".selectClass").val();
    var $generalExamSelect = $(".selectExam");
    var $generalSubjectSelect = $(".selectSubject");

    if ($generalExamSelect.length) {
      if (!department_id) {
        $generalExamSelect.html(
          '<option value="" selected disabled>Select Department</option>'
        );
      } else if (!currentClassId) {
        $generalExamSelect.html(
          '<option value="" selected disabled>Select Class First</option>'
        );
      } else {
        $generalExamSelect.html('<option value="">Loading...</option>');

        var examRequest = {
          action: "astgdrmsys_get_exam_names_by_class_and_department",
          class: currentClassId,
          department: department_id,
          nonce: astgdrmsys_ajax_object.nonce,
        };

        if (includePublished) {
          examRequest.include_published = 1;
        }

        $.ajax({
          url: astgdrmsys_ajax_object.ajaxurl,
          type: "POST",
          dataType: "json",
          data: examRequest,
          success: function (response) {
            if (response.success && Array.isArray(response.data) && response.data.length) {
              var options =
                '<option value="" selected disabled>Select Exam</option>';

              response.data.forEach(function (exam) {
                options +=
                  '<option value="' +
                  astgdrmsysEscapeAttribute(exam.id) +
                  "," +
                  astgdrmsysEscapeAttribute(exam.exam_year_id) +
                  '">' +
                  astgdrmsysEscapeHtml(exam.exam_name) +
                  " - " +
                  astgdrmsysEscapeHtml(exam.exam_year) +
                  "</option>";
              });

              $generalExamSelect.html(options);
            } else {
              $generalExamSelect.html(
                '<option value="" selected disabled>No exams available</option>'
              );
            }
          },
          error: function () {
            $generalExamSelect.html(
              '<option value="" selected disabled>Failed to load exams</option>'
            );
          },
        });
      }
    }

    if ($generalSubjectSelect.length) {
      if (!department_id) {
        $generalSubjectSelect.html(
          '<option value="" selected disabled>Select Department</option>'
        );
      } else if (!currentClassId) {
        $generalSubjectSelect.html(
          '<option value="" selected disabled>Select Class First</option>'
        );
      } else {
        $generalSubjectSelect.html('<option value="">Loading...</option>');

        $.ajax({
          url: astgdrmsys_ajax_object.ajaxurl,
          type: "POST",
          dataType: "json",
          data: {
            action: "astgdrmsys_get_subjects_by_class_and_department",
            class: currentClassId,
            department: department_id,
            nonce: astgdrmsys_ajax_object.nonce,
          },
          success: function (response) {
            if (response.success && Array.isArray(response.data) && response.data.length) {
              var subjectOptions =
                '<option value="" selected disabled>Select Subject</option>';

              response.data.forEach(function (subject) {
                subjectOptions +=
                  '<option value="' +
                  astgdrmsysEscapeAttribute(subject.id) +
                  "," +
                  astgdrmsysEscapeAttribute(subject.subcode) +
                  '">' +
                  astgdrmsysEscapeHtml(subject.subname) +
                  " - " +
                  astgdrmsysEscapeHtml(subject.subcode) +
                  "</option>";
              });

              $generalSubjectSelect.html(subjectOptions);
            } else {
              $generalSubjectSelect.html(
                '<option value="" selected disabled>No subjects available</option>'
              );
            }
          },
          error: function () {
            $generalSubjectSelect.html(
              '<option value="" selected disabled>Failed to load subjects</option>'
            );
          },
        });
      }
    }
  });

  // To hide the modal when clicked outside in add-class.php ln: 369
  if (window.location.href.includes("admin.php?page=astgdrmsys-class")) {
    $(".close-class-modal, .cancel-button").on("click", function () {
      $("#addmodal").hide();
    });
  }

  // To hide the modal when clicked outside in add-department.php ln: 406
  if (window.location.href.includes("admin.php?page=astgdrmsys-department")) {
    $(window).on("click", function (event) {
      if ($(event.target).is("#add-dept-modal")) {
        $("#add-dept-modal").hide();
      }
    });
  }

  // To check if the file uploaded is a CSV file in add-record.php ln:220
  if (window.location.href.includes("admin.php?page=astgdrmsys-add-record")) {
    $(".add-record-form").on("submit", function (event) {
      var fileInput = $("#CSV_file");
      var filePath = fileInput.val();

      if (filePath === "") {
        alert("Please select a CSV file before submitting.");
        event.preventDefault(); // Prevent form submission
        return;
      }

      var allowedExtension = /\.csv$/i;
      if (!allowedExtension.test(filePath)) {
        alert("Please upload a valid CSV file for.");
        fileInput.val(""); // Clear the input field
        event.preventDefault(); // Prevent form submission
        return;
      }
    });
  }

  // To copy the URL to clipboard in astgdrmsys-settings.php ln: 753
  if (window.location.href.includes("admin.php?page=astgdrmsys-settings")) {
    // Copy the URL to clipboard
    $(document).on("click", "#copy-button", function () {
      var button = $(this);
      var text = $("#saved-url").text().trim();

      if (!text) {
        alert("No URL found!");
        return;
      }

      if (navigator.clipboard && navigator.clipboard.writeText) {
        // Modern way to copy text
        navigator.clipboard
          .writeText(text)
          .then(function () {
            button.text("URL Copied").css("color", "white");
          })
          .catch(function (error) {
            console.error("Clipboard API failed: ", error);
            fallbackCopyText(text, button);
          });
      } else {
        // Fallback for older browsers
        console.warn("Clipboard API not supported, using fallback.");
        fallbackCopyText(text, button);
      }

      setTimeout(function () {
        button.text("Copy").css("color", "");
      }, 3000);
    });

    // Fallback function using execCommand
    function fallbackCopyText(text, button) {
      var tempInput = $("<input>");
      $("body").append(tempInput);
      tempInput.val(text).select();
      document.execCommand("copy");
      tempInput.remove();
      button.text("URL Copied").css("color", "white");
    }
  }

  if (window.location.href.includes("admin.php?page=astgdrmsys-all-students")) {
    // Use CDN for Bootstrap to ensure proper loading
    var styles = `<link rel="stylesheet" href="${astgdrmsys_ajax_object.pluginUrl}css/bootstrap.css" type="text/css">`;
    var done = $("head").append(styles);
    if (done) {
      console.log("Bootstrap CSS loaded successfully!");
    }

    var $filterForm = $(".filter-form");
    if ($filterForm.length) {
      var $classSelect = $filterForm.find(".astgdrmsys-filter-class");
      var $departmentSelect = $filterForm.find(".astgdrmsys-filter-department");
      var $examSelect = $filterForm.find(".astgdrmsys-filter-exam");
      var $sectionSelect = $filterForm.find(".astgdrmsys-filter-section");

      var placeholders = {
        department: $departmentSelect.find("option:first").text() || "All Departments",
        exam: $examSelect.find("option:first").text() || "All Exams",
        section: $sectionSelect.find("option:first").text() || "All Sections",
      };

      function setOptions($select, placeholder, items, selectedValue) {
        var markup = `<option value="">${placeholder}</option>`;

        if (Array.isArray(items) && items.length) {
          items.forEach(function (item) {
            var value = item.value !== undefined ? item.value : item.id;
            var label = item.label !== undefined ? item.label : item.name;
            var selected = selectedValue && parseInt(selectedValue, 10) === parseInt(value, 10) ? "selected" : "";
            markup += `<option value="${value}" ${selected}>${label}</option>`;
          });
        }

        $select.html(markup);
      }

      function fetchDepartments(classId) {
        if (!classId) {
          setOptions($departmentSelect, placeholders.department, []);
          return;
        }

        $departmentSelect.html('<option value="">Loading...</option>');

        $.ajax({
          url: astgdrmsys_ajax_object.ajaxurl,
          type: "POST",
          dataType: "json",
          data: {
            action: "astgdrmsys_get_departments_by_class",
            class: classId,
            nonce: astgdrmsys_ajax_object.nonce,
          },
          success: function (response) {
            if (response.success && Array.isArray(response.data) && response.data.length) {
              var departments = response.data.map(function (department) {
                return { value: department.id, label: department.department };
              });
              setOptions($departmentSelect, placeholders.department, departments);
            } else {
              setOptions($departmentSelect, placeholders.department, []);
            }
          },
          error: function () {
            setOptions($departmentSelect, placeholders.department, []);
          },
        });
      }

      function fetchExams(classId, departmentId) {
        if (!classId) {
          setOptions($examSelect, placeholders.exam, []);
          return;
        }

        $examSelect.html('<option value="">Loading...</option>');

        var ajaxAction = departmentId
          ? "astgdrmsys_get_exam_names_by_class_and_department"
          : "astgdrmsys_get_exam_names_by_class";

        var requestData = {
          action: ajaxAction,
          class: classId,
          nonce: astgdrmsys_ajax_object.nonce,
        };

        if (departmentId) {
          requestData.department = departmentId;
        }

        $.ajax({
          url: astgdrmsys_ajax_object.ajaxurl,
          type: "POST",
          dataType: "json",
          data: requestData,
          success: function (response) {
            if (response.success && Array.isArray(response.data) && response.data.length) {
              var exams = response.data.map(function (exam) {
                var labelParts = [];
                if (exam.exam_name) {
                  labelParts.push(exam.exam_name);
                }
                if (exam.exam_year) {
                  labelParts.push(exam.exam_year);
                }
                return {
                  value: exam.id,
                  label: labelParts.join(" - ") || exam.id,
                };
              });
              setOptions($examSelect, placeholders.exam, exams);
            } else {
              setOptions($examSelect, placeholders.exam, []);
            }
          },
          error: function () {
            setOptions($examSelect, placeholders.exam, []);
          },
        });
      }

      function fetchSections(departmentId) {
        if (!departmentId) {
          setOptions($sectionSelect, placeholders.section, []);
          return;
        }

        $sectionSelect.html('<option value="">Loading...</option>');

        $.ajax({
          url: astgdrmsys_ajax_object.ajaxurl,
          type: "POST",
          dataType: "json",
          data: {
            action: "astgdrmsys_get_sections_by_department",
            department: departmentId,
            nonce: astgdrmsys_ajax_object.nonce,
          },
          success: function (response) {
            if (response.success && Array.isArray(response.data) && response.data.length) {
              var sections = response.data.map(function (section) {
                return { value: section.id, label: section.section };
              });
              setOptions($sectionSelect, placeholders.section, sections);
            } else {
              setOptions($sectionSelect, placeholders.section, []);
            }
          },
          error: function () {
            setOptions($sectionSelect, placeholders.section, []);
          },
        });
      }

      $classSelect.on("change", function () {
        var classId = parseInt($(this).val(), 10) || 0;
        $departmentSelect.val("");
        $examSelect.val("");
        $sectionSelect.val("");

        setOptions($departmentSelect, placeholders.department, []);
        setOptions($examSelect, placeholders.exam, []);
        setOptions($sectionSelect, placeholders.section, []);

        if (!classId) {
          return;
        }

        fetchDepartments(classId);
        fetchExams(classId, 0);
      });

      $departmentSelect.on("change", function () {
        var departmentId = parseInt($(this).val(), 10) || 0;
        var classId = parseInt($classSelect.val(), 10) || 0;

        setOptions($sectionSelect, placeholders.section, []);

        if (departmentId) {
          fetchSections(departmentId);
        }

        fetchExams(classId, departmentId);
      });
    }
  }

  // To hide the modal
  if (window.location.href.includes("admin.php?page=astgdrmsys-exam-name")) {
    var $addSubjectsWrapper = $("#exam-subjects-wrapper");
    var $updateSubjectsWrapper = $("#update-exam-subjects-wrapper");
    var $autoSeedToggle = $("#auto-seed-students");
    var $sectionFilterToggle = $("#filter-by-section");
    var $sectionFilterSelect = $("#section-filter-select");
    var addCombinedManager = null;
    var updateCombinedManager = null;

    function updateSectionFilterState() {
      if (!$sectionFilterToggle.length || !$sectionFilterSelect.length) {
        return;
      }

      var autoSeedEnabled =
        !$autoSeedToggle.length || $autoSeedToggle.is(":checked");
      var enabled = autoSeedEnabled && $sectionFilterToggle.is(":checked");

      $sectionFilterToggle.prop("disabled", !autoSeedEnabled);
      $sectionFilterSelect.prop("disabled", !enabled);

      if (!enabled) {
        $sectionFilterSelect.val([]);
      }
    }

    if ($sectionFilterToggle.length && $sectionFilterSelect.length) {
      $sectionFilterToggle.on("change", updateSectionFilterState);
      $autoSeedToggle.on("change", updateSectionFilterState);
      updateSectionFilterState();
    }

    function escapeHtml(value) {
      var str = value === null || value === undefined ? "" : String(value);

      return str
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
    }

    function escapeAttribute(value) {
      return escapeHtml(value);
    }

    function setSectionFilterOptions(message, sections) {
      if (!$sectionFilterSelect.length) {
        return;
      }

      if (!Array.isArray(sections) || !sections.length) {
        $sectionFilterSelect.html(
          '<option value="" disabled>' + escapeHtml(message || "") + "</option>"
        );
        updateSectionFilterState();
        return;
      }

      var sectionOptions = "";
      sections.forEach(function (section) {
        sectionOptions +=
          '<option value="' +
          escapeAttribute(section.id) +
          '">' +
          escapeHtml(section.section) +
          "</option>";
      });

      $sectionFilterSelect.html(sectionOptions);
      updateSectionFilterState();
    }

    function fetchSectionFilterOptions(departmentId, classId) {
      if (!$sectionFilterSelect.length) {
        return;
      }

      if (!departmentId) {
        setSectionFilterOptions("Select a department first.", []);
        return;
      }

      if (!classId) {
        setSectionFilterOptions("Select a class first.", []);
        return;
      }

      setSectionFilterOptions("Loading sections...", []);

      $.ajax({
        url: astgdrmsys_ajax_object.ajaxurl,
        type: "POST",
        dataType: "json",
        data: {
          action: "astgdrmsys_get_sections_by_department",
          department: departmentId,
          class: classId,
          nonce: astgdrmsys_ajax_object.nonce,
        },
        success: function (response) {
          if (
            response.success &&
            Array.isArray(response.data) &&
            response.data.length
          ) {
            setSectionFilterOptions("", response.data);
          } else {
            setSectionFilterOptions("No sections found for this class and department.", []);
          }
        },
        error: function () {
          setSectionFilterOptions("Failed to load sections.", []);
        },
      });
    }

    function getWrapperMessage($wrapper, key, fallback) {
      if (!$wrapper || !$wrapper.length) {
        return fallback;
      }

      var message = $wrapper.data(key);

      if (typeof message === "string" && message.length) {
        return message;
      }

      return fallback;
    }

    function setSubjectsMessage($wrapper, message) {
      if (!$wrapper || !$wrapper.length) {
        return;
      }

      var $tbody = $wrapper.find(".exam-subjects-body");

      if (!$tbody.length) {
        return;
      }

      var text = message || getWrapperMessage($wrapper, "placeholder", "");

      $tbody.html(
        '<tr class="exam-subjects-placeholder"><td colspan="3">' +
          escapeHtml(text) +
          "</td></tr>"
      );
    }

    function renderSubjects($wrapper, subjects) {
      if (!$wrapper || !$wrapper.length) {
        return;
      }

      var $tbody = $wrapper.find(".exam-subjects-body");
      if (!$tbody.length) {
        return;
      }

      if (!Array.isArray(subjects) || !subjects.length) {
        setSubjectsMessage(
          $wrapper,
          getWrapperMessage(
            $wrapper,
            "empty",
            getWrapperMessage($wrapper, "placeholder", "")
          )
        );
        return;
      }

      var prefix = $wrapper.data("field-prefix") || "exam_subjects";
      var rowsHtml = "";

      subjects.forEach(function (subject) {
        var subjectId = parseInt(subject.id, 10) || 0;

        if (!subjectId) {
          return;
        }

        var name = subject.name || subject.subname || "";
        var code = subject.code || subject.subcode || "";
        var fullMark = subject.full_mark;

        if (fullMark === undefined || fullMark === null || fullMark === "") {
          fullMark =
            subject.total !== undefined && subject.total !== null
              ? subject.total
              : "";
        }

        var fullMarkValue =
          fullMark === null || fullMark === undefined ? "" : String(fullMark);

        rowsHtml += '<tr data-subject-id="' + subjectId + '">';
        rowsHtml +=
          "<td>" +
          escapeHtml(name) +
          '<input type="hidden" name="' +
          prefix +
          "[" +
          subjectId +
          '][name]" value="' +
          escapeAttribute(name) +
          '"><input type="hidden" name="' +
          prefix +
          "[" +
          subjectId +
          '][code]" value="' +
          escapeAttribute(code) +
          '"></td>';
        rowsHtml += "<td>" + escapeHtml(code) + "</td>";
        rowsHtml +=
          '<td><input type="number" class="form-control" step="0.01" min="0" name="' +
          prefix +
          "[" +
          subjectId +
          '][full_mark]" value="' +
          escapeAttribute(fullMarkValue) +
          '"></td>';
        rowsHtml += "</tr>";
      });

      if (!rowsHtml.length) {
        setSubjectsMessage(
          $wrapper,
          getWrapperMessage(
            $wrapper,
            "empty",
            getWrapperMessage($wrapper, "placeholder", "")
          )
        );
        return;
      }

      $tbody.html(rowsHtml);
    }

    function parseIdList(value) {
      if (Array.isArray(value)) {
        return value
          .map(function (item) {
            return String(item);
          })
          .filter(function (item) {
            return item.length;
          });
      }

      if (value === undefined || value === null) {
        return [];
      }

      return String(value)
        .split(",")
        .map(function (item) {
          return item.trim();
        })
        .filter(function (item) {
          return item.length;
        });
    }

    function CombinedExamManager(options) {
      this.$category = $(options.categorySelector);
      this.$wrapper = $(options.wrapperSelector);
      this.enabled = this.$category.length && this.$wrapper.length;

      if (!this.enabled) {
        return;
      }

      this.$classTestsSelect = this.$wrapper.find(options.classTestsSelector);
      this.$generalSelect = this.$wrapper.find(options.generalSelector);
      this.getClassId = options.getClassId;
      this.getDepartmentId = options.getDepartmentId;
      this.loadingText = this.$wrapper.data("loading") || "Loading...";
      this.placeholderText = this.$wrapper.data("placeholder") || "";
      this.classTestsPlaceholder =
        this.$wrapper.data("classTestsPlaceholder") || this.placeholderText;
      this.generalPlaceholder =
        this.$wrapper.data("generalPlaceholder") || this.placeholderText;
      this.emptyClassTests =
        this.$wrapper.data("emptyClassTests") || this.placeholderText;
      this.emptyGeneral =
        this.$wrapper.data("emptyGeneral") || this.placeholderText;
      this.selectedClassTests = parseIdList(
        this.$wrapper.data("selectedClassTests")
      );
      var selectedGeneralRaw = this.$wrapper.data("selectedGeneral");
      this.selectedGeneral =
        selectedGeneralRaw === undefined || selectedGeneralRaw === null
          ? ""
          : String(selectedGeneralRaw);

      this.bindEvents();
      this.updateVisibility();
    }

    CombinedExamManager.prototype.bindEvents = function () {
      var self = this;

      this.$category.on("change", function () {
        self.updateVisibility();
      });

      if (this.$classTestsSelect.length) {
        this.$classTestsSelect.on("change", function () {
          var values = $(this).val();
          self.selectedClassTests = Array.isArray(values)
            ? values.map(function (item) {
                return String(item);
              })
            : [];
        });
      }

      if (this.$generalSelect.length) {
        this.$generalSelect.on("change", function () {
          var value = $(this).val();
          self.selectedGeneral = value ? String(value) : "";
        });
      }
    };

    CombinedExamManager.prototype.isActive = function () {
      return this.$category.val() === "combined_result";
    };

    CombinedExamManager.prototype.setPlaceholderOptions = function (
      $select,
      message,
      isMultiple
    ) {
      if (!$select || !$select.length) {
        return;
      }

      var text = message || this.placeholderText;
      var optionHtml = '<option value="" disabled' + (isMultiple ? "" : " selected") + ">" + escapeHtml(text) + "</option>";

      $select.html(optionHtml);
    };

    CombinedExamManager.prototype.updateVisibility = function () {
      if (!this.enabled) {
        return;
      }

      if (this.isActive()) {
        this.$wrapper.show();
        this.refreshOptions();
      } else {
        this.$wrapper.hide();
      }
    };

    CombinedExamManager.prototype.refreshOptions = function () {
      if (!this.enabled || !this.isActive()) {
        return;
      }

      var classId = parseInt(this.getClassId(), 10) || 0;
      var departmentId = parseInt(this.getDepartmentId(), 10) || 0;

      if (!classId || !departmentId) {
        this.setPlaceholderOptions(
          this.$classTestsSelect,
          this.classTestsPlaceholder,
          true
        );
        this.setPlaceholderOptions(
          this.$generalSelect,
          this.generalPlaceholder,
          false
        );
        return;
      }

      this.loadExamOptions(
        "class_test",
        classId,
        departmentId,
        this.$classTestsSelect,
        this.classTestsPlaceholder,
        this.emptyClassTests,
        this.selectedClassTests,
        true
      );

      var generalSelection = this.selectedGeneral ? [this.selectedGeneral] : [];

      this.loadExamOptions(
        "general_exam",
        classId,
        departmentId,
        this.$generalSelect,
        this.generalPlaceholder,
        this.emptyGeneral,
        generalSelection,
        false
      );
    };

    CombinedExamManager.prototype.loadExamOptions = function (
      category,
      classId,
      departmentId,
      $select,
      placeholder,
      emptyMessage,
      selectedValues,
      isMultiple
    ) {
      if (!$select || !$select.length) {
        return;
      }

      this.setPlaceholderOptions($select, this.loadingText, isMultiple);

      var self = this;
      $.ajax({
        url: astgdrmsys_ajax_object.ajaxurl,
        type: "POST",
        dataType: "json",
        data: {
          action: "astgdrmsys_get_exam_names_by_class_and_department",
          class: classId,
          department: departmentId,
          include_published: true,
          category: category,
          nonce: astgdrmsys_ajax_object.nonce,
        },
        success: function (response) {
          if (
            response &&
            response.success &&
            Array.isArray(response.data) &&
            response.data.length
          ) {
            var optionsHtml = "";

            if (isMultiple) {
              optionsHtml +=
                '<option value="" disabled>' +
                escapeHtml(placeholder) +
                "</option>";
            } else {
              var placeholderSelected =
                !selectedValues || !selectedValues.length ? " selected" : "";
              optionsHtml +=
                '<option value="" disabled' +
                placeholderSelected +
                ">" +
                escapeHtml(placeholder) +
                "</option>";
            }

            response.data.forEach(function (exam) {
              var labelParts = [];

              if (exam.exam_name) {
                labelParts.push(exam.exam_name);
              }

              if (exam.exam_year) {
                labelParts.push(exam.exam_year);
              }

              var optionLabel = labelParts.join(" - ") || String(exam.id);
              optionsHtml +=
                '<option value="' +
                escapeAttribute(exam.id) +
                '">' +
                escapeHtml(optionLabel) +
                "</option>";
            });

            $select.html(optionsHtml);

            if (selectedValues && selectedValues.length) {
              var normalized = selectedValues.map(function (item) {
                return String(item);
              });
              $select.val(normalized);
            }
          } else {
            self.setPlaceholderOptions($select, emptyMessage, isMultiple);
          }
        },
        error: function () {
          self.setPlaceholderOptions($select, emptyMessage, isMultiple);
        },
      });
    };

    function createCombinedManager(options) {
      var manager = new CombinedExamManager(options);
      return manager.enabled ? manager : null;
    }

    function fetchSubjectsForSelection(departmentId, classId, $wrapper) {
      if (!$wrapper || !$wrapper.length) {
        return;
      }

      if (!departmentId || !classId) {
        setSubjectsMessage(
          $wrapper,
          getWrapperMessage($wrapper, "placeholder", "")
        );
        return;
      }

      setSubjectsMessage(
        $wrapper,
        getWrapperMessage($wrapper, "loading", "Loading...")
      );

      $.ajax({
        url: astgdrmsys_ajax_object.ajaxurl,
        type: "POST",
        dataType: "json",
        data: {
          action: "astgdrmsys_get_subjects_by_class_and_department",
          class: classId,
          department: departmentId,
          nonce: astgdrmsys_ajax_object.nonce,
        },
        success: function (response) {
          if (
            response &&
            response.success &&
            Array.isArray(response.data) &&
            response.data.length
          ) {
            renderSubjects($wrapper, response.data);
          } else {
            setSubjectsMessage(
              $wrapper,
              getWrapperMessage(
                $wrapper,
                "empty",
                getWrapperMessage($wrapper, "placeholder", "")
              )
            );
          }
        },
        error: function () {
          setSubjectsMessage(
            $wrapper,
            getWrapperMessage(
              $wrapper,
              "error",
              getWrapperMessage(
                $wrapper,
                "empty",
                getWrapperMessage($wrapper, "placeholder", "")
              )
            )
          );
        },
      });
    }

    // Show modal
    $("#openModalBtn").on("click", function () {
      $("#addmodal").show();
    });

    // Hide modal
    $("#closeModalBtn").on("click", function () {
      $("#addmodal").hide();
    });

    var $addDepartmentSelect = $("#selectDepartmentId");
    var $addClassNameInput = $("#hiddenclassname");
    var $addClassIdInput = $("#hiddenclassid");

    function getSelectedClass($classSelect) {
      var $selectedClass = $classSelect.find("option:selected");
      return {
        id: parseInt($classSelect.val(), 10) || 0,
        name: (($selectedClass.data("class-name") || $selectedClass.text() || "") + "").trim(),
      };
    }

    if ($addClassIdInput.length) {
      $addClassIdInput.on("change", function () {
        var selectedClass = getSelectedClass($addClassIdInput);
        if ($addClassNameInput.length) {
          $addClassNameInput.val(selectedClass.name);
        }

        var departmentId = parseInt($addDepartmentSelect.val(), 10) || 0;
        fetchSubjectsForSelection(departmentId, selectedClass.id, $addSubjectsWrapper);
        fetchSectionFilterOptions(departmentId, selectedClass.id);
        if (addCombinedManager) {
          addCombinedManager.refreshOptions();
        }
      });
    }

    if ($addDepartmentSelect.length) {
      $addDepartmentSelect.on("change", function () {
        var $selected = $(this).find("option:selected");
        var selectedClass = getSelectedClass($addClassIdInput);

        if (!$selected.length || !$(this).val()) {
          setSubjectsMessage(
            $addSubjectsWrapper,
            getWrapperMessage($addSubjectsWrapper, "placeholder", "")
          );
          setSectionFilterOptions("Select a department first.", []);
          if (addCombinedManager) {
            addCombinedManager.refreshOptions();
          }
          return;
        }

        if ($addClassNameInput.length) {
          $addClassNameInput.val(selectedClass.name);
        }

        var departmentId = parseInt($selected.val(), 10) || 0;
        var classId = selectedClass.id;
        fetchSubjectsForSelection(departmentId, classId, $addSubjectsWrapper);
        fetchSectionFilterOptions(departmentId, classId);
        if (addCombinedManager) {
          addCombinedManager.refreshOptions();
        }
      });
    }

    var $updateDepartmentSelect = $("#updateSelectId");
    var $updateClassNameInput = $("#updateHiddenClassname");
    var $updateClassIdInput = $("#updateHiddenClassid");

    if ($updateClassIdInput.length) {
      $updateClassIdInput.on("change", function () {
        var selectedClass = getSelectedClass($updateClassIdInput);
        if ($updateClassNameInput.length) {
          $updateClassNameInput.val(selectedClass.name);
        }

        var departmentId = parseInt($updateDepartmentSelect.val(), 10) || 0;
        fetchSubjectsForSelection(departmentId, selectedClass.id, $updateSubjectsWrapper);
        if (updateCombinedManager) {
          updateCombinedManager.refreshOptions();
        }
      });
      $updateClassIdInput.trigger("change");
    }

    if ($updateDepartmentSelect.length) {
      $updateDepartmentSelect.on("change", function () {
        var $selected = $(this).find("option:selected");
        var selectedClass = getSelectedClass($updateClassIdInput);

        if (!$selected.length) {
          setSubjectsMessage(
            $updateSubjectsWrapper,
            getWrapperMessage($updateSubjectsWrapper, "placeholder", "")
          );
          if (updateCombinedManager) {
            updateCombinedManager.refreshOptions();
          }
          return;
        }

        var departmentId = parseInt($selected.val(), 10) || 0;

        if ($updateClassNameInput.length) {
          $updateClassNameInput.val(selectedClass.name);
        }

        var classId = selectedClass.id;
        fetchSubjectsForSelection(departmentId, classId, $updateSubjectsWrapper);
        if (updateCombinedManager) {
          updateCombinedManager.refreshOptions();
        }
      });
    }

    // Update hidden exam year ID
    $("#ExamYearId").on("change", function () {
      var selectedValue = $(this).val();
      var values = selectedValue.split("-");
      var examYearId = values[1];

      $("#hiddenExamYearId").val(examYearId);
    });

    addCombinedManager = createCombinedManager({
      categorySelector: "#exam_category",
      wrapperSelector: "#combined-exam-options",
      classTestsSelector: "#combined-class-tests",
      generalSelector: "#combined-general-exam",
      getClassId: function () {
        return $("#hiddenclassid").val();
      },
      getDepartmentId: function () {
        var value = $("#selectDepartmentId").val() || "";
        var parts = value.split("-");
        return parseInt(parts[0], 10) || 0;
      },
    });

    updateCombinedManager = createCombinedManager({
      categorySelector: "select[name='update_exam_category']",
      wrapperSelector: "#update-combined-exam-options",
      classTestsSelector: "#update-combined-class-tests",
      generalSelector: "#update-combined-general-exam",
      getClassId: function () {
        return $("#updateHiddenClassid").val();
      },
      getDepartmentId: function () {
        return $("#updateSelectId").val();
      },
    });

    function updateAssessmentFields($container, examType) {
      if (!$container || !$container.length) {
        return;
      }

      var normalizedType = (examType || "single").toString().trim();

      $container.find(".assessment-label-field").each(function () {
        var $field = $(this);
        var allowed = ($field.data("exam-types") || "").toString().split(",");
        var shouldShow = false;

        for (var i = 0; i < allowed.length; i += 1) {
          if (allowed[i].toString().trim() === normalizedType) {
            shouldShow = true;
            break;
          }
        }

        if (shouldShow) {
          $field.show();
        } else {
          $field.hide();
        }
      });
    }

    function maybeApplyAssessmentDefaults($container, examType) {
      if (!$container || !$container.length) {
        return;
      }

      var normalizedType = (examType || "single").toString().trim();

      $container.find(".assessment-display-input").each(function () {
        var $input = $(this);
        var defaults = {
          single: ($input.data("default-single") || "").toString(),
          composite: ($input.data("default-composite") || "").toString(),
          triple: ($input.data("default-triple") || "").toString(),
        };

        var currentValue = ($input.val() || "").toString().trim();
        var knownDefaults = [];

        Object.keys(defaults).forEach(function (key) {
          if (defaults[key]) {
            knownDefaults.push(defaults[key]);
          }
        });

        if (!currentValue || knownDefaults.indexOf(currentValue) !== -1) {
          var replacement = defaults[normalizedType] || "";
          if ($input.val() !== replacement) {
            $input.val(replacement);
          }
        }
      });
    }

    function bindAssessmentControls($select, $container) {
      if (!$select.length || !$container.length) {
        return;
      }

      function applySelection() {
        var examType = ($select.val() || "single").toString().trim();
        updateAssessmentFields($container, examType);
        maybeApplyAssessmentDefaults($container, examType);
      }

      $select.on("change", applySelection);
      applySelection();
    }

    bindAssessmentControls($("#exam_type"), $("#addmodal form"));
    bindAssessmentControls($("select[name='update_exam_type']"), $(".edit-form"));
  }

  // To hide message modal in csv-update
  if (window.location.href.includes("admin.php?page=astgdrmsys-update-marks-csv")) {
    $(".close-message").on("click", function () {
      $(this).closest("#message_div").hide();
    });
  }

  // To hide the modal for subject
  if (window.location.href.includes("admin.php?page=astgdrmsys-subject")) {
    $(".close-subject-modal, .cancel-button").on("click", function () {
      $("#addmodal").hide();
    });
    // Show modal
    $("#addsub").on("click", function () {
      $("#addmodal").show().css("display", "flex");
    });
  }

  // for add-mark.php or add-exam-name.php
  if (
    window.location.href.includes("admin.php?page=astgdrmsys-add-mark") ||
    window.location.href.includes("admin.php?page=astgdrmsys-exam-name")
  ) {
    $(".close-message").on("click", function () {
      $(this).closest("#message_div").hide();
    });
  }

  // for add-mark.php or insert-result.php
  if (
    window.location.href.includes("admin.php?page=astgdrmsys-add-mark") ||
    window.location.href.includes("admin.php?page=astgdrmsys-insert-result")
  ) {
    /**
     * Calculates the total obtained marks for a single row in the marks table.
     * It dynamically finds and adds values from practical, class, and final mark inputs.
     */
    function calculateTotal(row) {
      // Find the value of each input field. If it doesn't exist or is empty, default to 0.
      const practicalMark = parseFloat(row.find(".practical-mark").val()) || 0;
      const classMark = parseFloat(row.find(".class-mark").val()) || 0;
      const finalMark = parseFloat(row.find(".final-mark").val()) || 0;

      // Sum up all the marks found in the row.
      const total = practicalMark + classMark + finalMark;

      // Update the 'Total Obtained' field for that row.
      row.find(".total-mark").val(total);
    }

    $(".practical-mark, .class-mark, .final-mark").on("input", function () {
      // When any of these inputs change, find its parent table row.
      const row = $(this).closest("tr");
      // Recalculate the total for that specific row.
      calculateTotal(row);
    });

    function toggleNotTaken(row, isChecked) {
      const markInputs = row.find(".practical-mark, .class-mark, .final-mark");
      const totalField = row.find(".total-mark");
      const fourthRadio = row.find("input[type='radio'][name='fourth_subject']");

      markInputs.prop("disabled", isChecked);
      totalField.prop("disabled", isChecked);
      fourthRadio.prop("disabled", isChecked);

      if (isChecked) {
        markInputs.val("");
        totalField.val("");
        if (fourthRadio.is(":checked")) {
          fourthRadio.prop("checked", false);
        }
      } else {
        calculateTotal(row);
      }
    }

    $(".not-taken-checkbox").on("change", function () {
      const row = $(this).closest("tr");
      toggleNotTaken(row, $(this).is(":checked"));
    });

    $(".not-taken-checkbox").each(function () {
      const row = $(this).closest("tr");
      toggleNotTaken(row, $(this).is(":checked"));
    });
  }

  // For settings page
  if (window.location.href.includes("admin.php?page=astgdrmsys-settings")) {
    const $deleteClassSelect = $(".astgdrmsys-delete-class");
    const $deleteDepartmentSelect = $(".astgdrmsys-delete-department");
    const $deleteExamSelect = $(".astgdrmsys-delete-exam");
    const $deleteExamForm = $(".astgdrmsys-delete-exam-form");
    const $deleteAllForm = $(".astgdrmsys-delete-all-form");
    const $deleteExamPreview = $(".astgdrmsys-delete-exam-preview");

    function setDeletePreview($preview, students, marks, message) {
      if (!$preview.length) {
        return;
      }

      $preview.find('[data-count="students"]').text(students);
      $preview.find('[data-count="marks"]').text(marks);

      if (message) {
        $preview.find(".description").text(message);
      }
    }

    function resetExamDeletePreview(message) {
      setDeletePreview(
        $deleteExamPreview,
        0,
        0,
        message || "Select an exam to calculate affected records."
      );
    }

    function updateDeleteExamButtonState() {
      if (!$deleteExamForm.length) {
        return;
      }

      const hasClass = !!$deleteClassSelect.val();
      const hasDepartment = !!$deleteDepartmentSelect.val();
      const hasExam = !!$deleteExamSelect.val();
      const understood = $deleteExamForm
        .find(".astgdrmsys-delete-confirm-toggle")
        .is(":checked");

      $deleteExamForm
        .find(".astgdrmsys-delete-submit")
        .prop("disabled", !(hasClass && hasDepartment && hasExam && understood));
    }

    function updateDeleteAllButtonState() {
      if (!$deleteAllForm.length) {
        return;
      }

      const understood = $deleteAllForm
        .find(".astgdrmsys-delete-confirm-toggle")
        .is(":checked");
      const confirmation =
        $deleteAllForm.find(".astgdrmsys-delete-all-confirm").val() || "";

      $deleteAllForm
        .find(".astgdrmsys-delete-submit")
        .prop("disabled", !(understood && confirmation === "DELETE ALL"));
    }

    function loadDeleteExamPreview() {
      const classId = $deleteClassSelect.val();
      const departmentId = $deleteDepartmentSelect.val();
      const examValue = $deleteExamSelect.val();

      if (!classId || !departmentId || !examValue) {
        resetExamDeletePreview();
        updateDeleteExamButtonState();
        return;
      }

      resetExamDeletePreview("Calculating affected records...");

      $.ajax({
        url: astgdrmsys_ajax_object.ajaxurl,
        type: "POST",
        dataType: "json",
        data: {
          action: "astgdrmsys_get_delete_record_preview",
          preview_type: "exam",
          class: classId,
          department: departmentId,
          exam: examValue,
          nonce: astgdrmsys_ajax_object.nonce,
        },
      })
        .done(function (response) {
          if (response.success && response.data) {
            setDeletePreview(
              $deleteExamPreview,
              response.data.students || 0,
              response.data.marks || 0,
              "Review the affected records before deleting."
            );
          } else {
            resetExamDeletePreview("Could not calculate affected records.");
          }
          updateDeleteExamButtonState();
        })
        .fail(function () {
          resetExamDeletePreview("Failed to calculate affected records.");
          updateDeleteExamButtonState();
        });
    }

    function setDepartmentPlaceholder(message, keepDisabled = true) {
      if (!$deleteDepartmentSelect.length) {
        return;
      }
      $deleteDepartmentSelect.html(
        '<option value="" selected disabled>' + astgdrmsysEscapeHtml(message) + "</option>"
      );
      $deleteDepartmentSelect.prop("disabled", keepDisabled);
    }

    function setExamPlaceholder(message, keepDisabled = true) {
      if (!$deleteExamSelect.length) {
        return;
      }
      $deleteExamSelect.html(
        '<option value="" selected disabled>' + astgdrmsysEscapeHtml(message) + "</option>"
      );
      $deleteExamSelect.prop("disabled", keepDisabled);
    }

    if ($deleteClassSelect.length) {
      setDepartmentPlaceholder("Select a class first");
      setExamPlaceholder("Select a department first");
      resetExamDeletePreview();
      updateDeleteExamButtonState();
      updateDeleteAllButtonState();

      $deleteClassSelect.on("change", function () {
        const classId = $(this).val();

        setExamPlaceholder("Select a department first");
        resetExamDeletePreview();
        updateDeleteExamButtonState();

        if (!classId) {
          setDepartmentPlaceholder("Select a class first");
          return;
        }

        $deleteDepartmentSelect.prop("disabled", true);
        $deleteDepartmentSelect.html(
          '<option value="" selected disabled>Loading...</option>'
        );

        $.ajax({
          url: astgdrmsys_ajax_object.ajaxurl,
          type: "POST",
          dataType: "json",
          data: {
            action: "astgdrmsys_get_departments_by_class",
            class: classId,
            nonce: astgdrmsys_ajax_object.nonce,
          },
        })
          .done(function (response) {
            if (
              response.success &&
              Array.isArray(response.data) &&
              response.data.length
            ) {
              let options =
                '<option value="" selected disabled>Select a department</option>';
              response.data.forEach(function (department) {
                options +=
                  '<option value="' +
                  astgdrmsysEscapeAttribute(department.id) +
                  '">' +
                  astgdrmsysEscapeHtml(department.department) +
                  "</option>";
              });
              $deleteDepartmentSelect.html(options);
              $deleteDepartmentSelect.prop("disabled", false);
            } else {
              setDepartmentPlaceholder("No departments found", true);
            }
          })
          .fail(function () {
            setDepartmentPlaceholder("Failed to load departments", true);
          });
      });

      $deleteDepartmentSelect.on("change", function () {
        const classId = $deleteClassSelect.val();
        const departmentId = $(this).val();

        if (!classId) {
          setDepartmentPlaceholder("Select a class first");
          setExamPlaceholder("Select a class first");
          return;
        }

        if (!departmentId) {
          setExamPlaceholder("Select a department first");
          resetExamDeletePreview();
          updateDeleteExamButtonState();
          return;
        }

        $deleteExamSelect.prop("disabled", true);
        $deleteExamSelect.html(
          '<option value="" selected disabled>Loading...</option>'
        );

        $.ajax({
          url: astgdrmsys_ajax_object.ajaxurl,
          type: "POST",
          dataType: "json",
          data: {
            action: "astgdrmsys_get_exam_names_by_class_and_department",
            class: classId,
            department: departmentId,
            nonce: astgdrmsys_ajax_object.nonce,
          },
        })
          .done(function (response) {
            if (
              response.success &&
              Array.isArray(response.data) &&
              response.data.length
            ) {
              let options =
                '<option value="" selected disabled>Select an exam</option>';
              response.data.forEach(function (exam) {
                options +=
                  '<option value="' +
                  astgdrmsysEscapeAttribute(exam.id) +
                  "," +
                  astgdrmsysEscapeAttribute(exam.exam_year_id) +
                  '">' +
                  astgdrmsysEscapeHtml(exam.exam_name) +
                  " - " +
                  astgdrmsysEscapeHtml(exam.exam_year) +
                  "</option>";
              });
              $deleteExamSelect.html(options);
              $deleteExamSelect.prop("disabled", false);
              resetExamDeletePreview("Select an exam to calculate affected records.");
              updateDeleteExamButtonState();
            } else {
              setExamPlaceholder("No exams found for this selection", true);
              resetExamDeletePreview("No exams found for this selection.");
              updateDeleteExamButtonState();
            }
          })
          .fail(function () {
            setExamPlaceholder("Failed to load exams", true);
            resetExamDeletePreview("Failed to load exams.");
            updateDeleteExamButtonState();
          });
      });

      $deleteExamSelect.on("change", function () {
        loadDeleteExamPreview();
      });

      $deleteExamForm
        .find(".astgdrmsys-delete-confirm-toggle")
        .on("change", updateDeleteExamButtonState);

      $deleteAllForm
        .find(".astgdrmsys-delete-confirm-toggle, .astgdrmsys-delete-all-confirm")
        .on("change keyup input", updateDeleteAllButtonState);
    }

    // Show the new grade row when the button is clicked
    $("#astgdrmsys-show-new-grade").on("click", function () {
      // Show the hidden row
      $("#astgdrmsys-new-grade-row").show();

      // Add required attributes only when visible
      $("#astgdrmsys-new-grade-row")
        .find('input[name^="new_grade"]')
        .attr("required", true);

      // Hide the button itself
      $(this).hide();
    });

    // For Adding Custom Fields
    var $container = $("#custom-fields-container");
    var $addButton = $("#add-custom-field");
    var $template = $("#custom-field-template");
    var maxFields = 5;

    function updateAddButtonState() {
      var currentCount = $container.find(".custom-field-row").length;
      $addButton.prop("disabled", currentCount >= maxFields);
    }

    $addButton.on("click", function () {
      if ($container.find(".custom-field-row").length >= maxFields) {
        return;
      }

      $container.find(".no-fields-row").remove();

      var newFieldNumber = $container.find(".custom-field-row").length + 1;
      var newIndex = newFieldNumber - 1;

      var $clone = $($template.html()); // Clones the template content

      var $label = $clone.find("label");
      var $input = $clone.find("input");

      $label.text(`Student Custom Field ${newFieldNumber}`);
      $label.attr("for", `student_custom_field_${newIndex}`);
      $input.attr("id", `student_custom_field_${newIndex}`);

      $container.append($clone);

      updateAddButtonState();
    });

    // Remove custom field
    $container.on("click", ".remove-custom-field", function () {
      $(this).closest(".custom-field-row").remove();
      updateAddButtonState();
    });
    
    // call update button state
    updateAddButtonState();
  }
});
