const { pool } = require('../database')

/**
 * Function to insert notes into the database
 * @param {Object} formData - The form data containing subject names and values
 * @param {number} etudiant_id - The student ID
 * @param {string} etudiant_niveau - The student level
 * @returns {Promise} - Promise resolving to the database response or an error
 */
async function insertNoteRepech(
  etudiant_id,
  etudiant_niveau,
  mention_id,
  formData,
  annee_scolaire
) {
  const matiere_ids = Object.keys(formData)
  const values = Object.values(formData)

  const query = `
    INSERT INTO notesrepech
    (etudiant_id, matiere_id, etudiant_niveau, mention_id, note, annee_scolaire)
    VALUES (?, ?, ?, ?, ?, ?)
  `

  try {
    let response
    for (let j = 0; j < matiere_ids.length; j++) {
      const note = parseFloat(values[j].replace(',', '.')) || 0
      const [result] = await pool.query(query, [
        etudiant_id,
        matiere_ids[j],
        etudiant_niveau,
        mention_id,
        note,
        annee_scolaire
      ])
      response = result
    }
    return response
  } catch (error) {
    console.error('Insert error:', error)
    return error
  }
}

/**
 *
 * @returns promise
 */
async function getNoteOnline() {
  const sql = 'SELECT notes.* FROM notes '

  try {
    let [rows] = await pool.query(sql)

    return rows
  } catch (error) {
    return error
  }
}

/**
 *
 * @returns promise
 */
async function getNoteRepech(id, niveau) {
  const query = `
    SELECT notesrepech.*, matieres.*
    FROM notesrepech
    JOIN matieres ON notesrepech.matiere_id = matieres.id
    WHERE notesrepech.etudiant_id = ?
      AND notesrepech.etudiant_niveau = ?
  `

  try {
    const [rows] = await pool.query(query, [id, niveau])
    return rows
  } catch (error) {
    console.error('Error in getNoteRepech:', error)
    return error
  }
}

/**
 * Verify if a student has notes
 * @returns {Promise<Array>} - Promise resolving to an array of notes or an empty array
 */
async function verifyEtudiantIfHeHasNotesRepech() {
  const query = `SELECT DISTINCT etudiant_id, etudiant_niveau FROM notesrepech`

  try {
    const [rows] = await pool.query(query)
    return rows
  } catch (error) {
    console.error('Error verifying student notes:', error)
    throw error
  }
}

/**
 * function to show moyenne in screen
 *
 * @returns promise
 */
async function showMoyenRepech(niveau, scolaire) {
  try {
    // 1. Get distinct student IDs with notes repech
    const [etudiantWithNotes] = await pool.query(
      `SELECT DISTINCT etudiant_id FROM notesrepech WHERE etudiant_niveau = ? AND annee_scolaire = ?`,
      [niveau, scolaire]
    )

    const query2 = `
      SELECT notesrepech.*, etudiants.*, matieres.id AS matiere_id, matieres.nom AS nomMat, matieres.credit
      FROM notesrepech
      INNER JOIN etudiants ON notesrepech.etudiant_id = etudiants.id
      INNER JOIN matieres ON notesrepech.matiere_id = matieres.id
      WHERE notesrepech.etudiant_id = ?
    `

    let allEtudiantWithNotes = []

    // 2. Loop over each student and get their notes repech
    for (const etudiant of etudiantWithNotes) {
      const [rows] = await pool.query(query2, [etudiant.etudiant_id])
      allEtudiantWithNotes.push(rows)
    }

    return allEtudiantWithNotes
  } catch (error) {
    console.error('Error in showMoyenRepech:', error)
    return error
  }
}

/**
 * function used when updating note
 * @param {Object} formData - The form data containing subject names and values
 * @param {string} niveau - The student level
 * @returns {Promise} - Promise resolving to the database response or an error
 */
async function updateNoteRepech(formData, niveau, id) {
  const matiere_ids = Object.keys(formData)
  const values = Object.values(formData)

  const query = `
    UPDATE notesrepech
    SET note = ?
    WHERE etudiant_id = ? AND etudiant_niveau = ? AND matiere_id = ?
  `

  try {
    let response

    for (let index = 0; index < matiere_ids.length; index++) {
      let data = values[index]

      // Convert string number with comma to float, e.g. "12,5" => 12.5
      if (typeof data === 'string') {
        data = parseFloat(data.replace(',', '.'))
      } else {
        data = parseFloat(String(data).replace(',', '.'))
      }

      // Optional: console log to verify conversion
      console.log(data)

      const [result] = await pool.query(query, [data, id, niveau, matiere_ids[index]])
      response = result
    }

    return response
  } catch (error) {
    console.error('Error updating notes repech:', error)
    return error
  }
}

async function blockShowMoyeneRepech() {
  const query = `
    SELECT DISTINCT etudiant_niveau, annee_scolaire
    FROM notesrepech
    ORDER BY annee_scolaire DESC
  `

  const queryMention = `SELECT * FROM mentions`

  const query2 = `
    SELECT notesrepech.*,
           etudiants.id AS etudiantsId,
           etudiants.mention_id AS mentionId,
           etudiants.niveau,
           matieres.*
    FROM notesrepech
    INNER JOIN etudiants ON notesrepech.etudiant_id = etudiants.id
    INNER JOIN matieres ON notesrepech.matiere_id = matieres.id
    WHERE notesrepech.etudiant_niveau = ? AND notesrepech.annee_scolaire = ?
  `

  try {
    const [response] = await pool.query(query)
    const [mention] = await pool.query(queryMention)

    const niveau = response.map((item) => item.etudiant_niveau)
    const annee_scolaire = response.map((item) => item.annee_scolaire)

    let allData = []

    for (let i = 0; i < niveau.length; i++) {
      const [rows] = await pool.query(query2, [niveau[i], annee_scolaire[i]])
      allData.push(rows)
    }

    return { response, allData, mention }
  } catch (error) {
    console.error('Error in blockShowMoyeneRepech:', error)
    return error
  }
}

/**
 * get all note with matiere for single student
 * @param {*} id
 * @param {*} niveau
 * @param {*} annee_scolaire
 * @returns promise
 */
async function getMatiereAndNoteRepech(id, niveau, annee_scolaire) {
  const query = `
    SELECT *
    FROM notesrepech
    INNER JOIN matieres ON notesrepech.matiere_id = matieres.id
    WHERE notesrepech.etudiant_id = ?
      AND notesrepech.etudiant_niveau = ?
      AND notesrepech.annee_scolaire = ?
  `

  try {
    const [rows] = await pool.query(query, [id, niveau, annee_scolaire])
    return rows
  } catch (error) {
    console.error('Error in getMatiereAndNoteRepech:', error)
    return error
  }
}

module.exports = {
  insertNoteRepech,
  getNoteRepech,
  showMoyenRepech,
  getNoteOnline,
  verifyEtudiantIfHeHasNotesRepech,
  updateNoteRepech,
  blockShowMoyeneRepech,
  getMatiereAndNoteRepech
}
