/*
* This file contains functions to validate user input.
* It includes a function to check if a password meets certain criteria.
*/

// GLOBAL VARIABLES
const asciiRegex = new RegExp("^[\x00-\x7F]+$");
const upperRegex = new RegExp("[A-Z]");
const lowerRegex = new RegExp("[a-z]");
const digitRegex = new RegExp("[0-9]");
const specialCharRegex = new RegExp("[!@#$%^&*(),.?\":{}|<>]");

const phoneNumberValidationError = {
  INVALID_COUNTRY_CODE: 1,
  TOO_SHORT: 2,
  TOO_LONG: 3
};

/**
* Function to show a spinner in the form button.
* It replaces the button text with a loading spinner.
* If the button is not found, it logs an error to the console.
* @returns {void}
*/
function showSpinner(button) {
  button.html('<img src="img/three-dots.svg" width="50" alt="Loading...">');
}

/**
* Function to hide the spinner in the form button.
* It replaces the spinner with a message.
* @param {jQuery} button - The jQuery object representing the button.
* @param {string} message - The message to display after hiding the spinner.
* @returns {void}
*/
function hideSpinner(button, message = "Submit") {
  button.html(message);
}

/**
* Function to check if a password meets the following criteria:
* 1. At least 8 characters long
* 2. Contains at least one uppercase letter
* 3. Contains at least one lowercase letter
* 4. Contains at least one digit
* 5. Contains at least one special character (e.g., !@#$%^&*)
*
* @param {string} password - The password to validate.
* @returns {Object} An object with a `valid` property indicating if the password is valid,
* and a `message` property with details if it is not valid.
*/
function validatePassword(password) {
  if (!password) {
    return {
      valid: false,
      message: "Password cannot be empty."
    }
  }

  if (!asciiRegex.test(password)) {
    return {
      valid: false,
      message: "Password must contain only ASCII characters."
    }
  }

  if (password.length < 8) {
    return {
      valid: false,
      message: "Password must be at least 8 characters long."
    }
  }

  const hasUpperCase = upperRegex.test(password);
  const hasLowerCase = lowerRegex.test(password);
  const hasDigit = digitRegex.test(password);
  const hasSpecialChar = specialCharRegex.test(password);
  if (!hasUpperCase || !hasLowerCase || !hasDigit || !hasSpecialChar) {
    return {
      valid: false,
      message: "Password must contain at least one uppercase letter, one lowercase letter, one digit, and one special character."
    }
  }

  return {
    valid: true,
    message: ""
  };
}

/**
* Function to validate a phone number using the libphonenumber-js library.
* It checks if the phone number is valid, and if not, returns an appropriate error message.
*
* @param {Object} phoneNumberInput - An instance of the intl-tel-input library.
* @returns {Object} An object with a `valid` property indicating if the phone number is valid,
* and a `message` property with details if it is not valid.
*/
function validatePhoneNumber(phoneNumberInput) {
  const isPhoneNumberValid = phoneNumberInput.isValidNumber(); // Changed from isValid to isValidNumber
  if (isPhoneNumberValid) {
    return {
      valid: true,
      message: ""
    };
  }

  const errorCode = phoneNumberInput.getValidationError();
  let errorMessage = "Invalid phone number.";
  switch (errorCode) {
    case phoneNumberValidationError.INVALID_COUNTRY_CODE:
      errorMessage = 'Invalid country code.'
      break;
    case phoneNumberValidationError.TOO_SHORT:
      errorMessage = 'Phone number is too short.'
      break;
    case phoneNumberValidationError.TOO_LONG:
      errorMessage = 'Phone number is too long.'
      break;
    default:
      break;
  }

  return {
    valid: false,
    message: errorMessage
  };
}

/**
* Function to validate if the parent and student email addresses are different.
* It checks if both emails are provided and if they are the same (case-insensitive).
*
* @param {string} parentEmail - The parent's email address.
* @param {string} studentEmail - The student's email address.
* @returns {Object} An object with a `valid` property indicating if the emails are different,
* and a `message` property with details if they are the same.
*/
function validateEmails(parentEmail, studentEmail) {
  if (parentEmail && parentEmail.length > 100) {
    return {
      valid: false,
      message: "Parent’s e-mail address is too long."
    }
  }

  if (studentEmail && studentEmail.length > 100) {
    return {
      valid: false,
      message: "Student’s e-mail address is too long."
    }
  }

  if (parentEmail && !asciiRegex.test(parentEmail)) {
    return {
      valid: false,
      message: "Parent’s e-mail address must contain only ASCII characters."
    }
  }

  if (studentEmail && !asciiRegex.test(studentEmail)) {
    return {
      valid: false,
      message: "Student’s e-mail address must contain only ASCII characters."
    }
  }

  if (parentEmail && studentEmail && parentEmail.toLowerCase() === studentEmail.toLowerCase()) {
    return {
      valid: false,
      message: "Parent’s e-mail address must be different from student’s e-mail address."
    }
  }

  return {
    valid: true,
    message: ""
  };
}

/**
* Function to validate first and last names.
* It checks if the names are provided, their lengths, and if they contain valid characters.
* @param {string} name - The name to validate.
* @param {boolean} isLastName - Indicates if the name is a last name (default is false for first name).
* @returns {Object} An object with a `valid` property indicating if the name is valid,
* and a `message` property with details if it is not valid.
*/
function validateName(name, isLastName = false) {
  const nameType = isLastName ? "Last name" : "First name";
  if (!name || name.length === 0) {
    return {
      valid: false,
      message: `${nameType} information cannot be empty.`
    }
  }

  if (!asciiRegex.test(name)) {
    return {
      valid: false,
      message: `${nameType} must contain only ASCII characters.`
    }
  }

  if (name.length > 100) {
    return {
      valid: false,
      message: `${nameType} is too long.`
    }
  }

  if (name.length < 2) {
    return {
      valid: false,
      message: `${nameType} must be at least 2 characters long.`
    }
  }

  return {
    valid: true,
    message: ""
  };
}

/**
* Function to validate a school name.
* It checks if the school name is provided, its length, and if it contains valid ASCII characters.
* @param {string} schoolName - The name of the school to validate.
* @returns {Object} An object with a `valid` property indicating if the school name is valid,
* and a `message` property with details if it is not valid.
*/
function validateSchool(schoolName) {
  if (!schoolName || schoolName.length === 0) {
    return {
      valid: false,
      message: "School name cannot be empty."
    }
  }

  if (!asciiRegex.test(schoolName)) {
    return {
      valid: false,
      message: "School name must contain only ASCII characters."
    }
  }

  if (schoolName.length > 100) {
    return {
      valid: false,
      message: "School name is too long."
    }
  }

  return {
    valid: true,
    message: ""
  };
}