const { database } = require('../database.backup')
const { matiereSysteme } = require('../function/System')
const { convertArrayAndString } = require('../function/StringArrayConvertion')

/**
 * function uset to create matiere
 * @param {*} nom
 * @returns Promise
 */
async function createMatiere(nom, credit, uniter, ue) {
  const query = database.prepare(
    'INSERT INTO matieres (nom, unite_enseignement, credit, heure, ue) VALUES (?, ?, ?, ?, ?)'
  )

  const uniterHeure = database.prepare('SELECT uniter_heure FROM nessesaryTable').get()
  const heure = credit * uniterHeure.uniter_heure

  try {
    response = await query.run(nom, uniter, credit, heure, ue)

    return response
  } catch (error) {
    return error
  }
}

/**
 * function to get all matieres
 * @returns Promise
 */
async function getMatiere() {
  const query = database.prepare('SELECT m.*, n.nom AS niveau_nom FROM matieres m LEFT JOIN niveaus n ON m.niveau_id = n.id ORDER BY m.id DESC')

  try {
    let response = await query.all()

    return response
  } catch (error) {
    return error
  }
}

async function displayMatiereFromForm(niveau, mention_id, parcours) {
  // Fetch the semestre array
  let semestre = await matiereSysteme(niveau) // Ensure this returns an array with at least 2 items

  if (niveau !== 'L1') {
    if (semestre.length < 2) {
      console.error('Error: Semestre array does not contain enough elements.')
      return
    }

    // Prepare the query
    let matiereQuery = database.prepare(`
      SELECT DISTINCT m.*
      FROM matieres m
      JOIN matiere_semestre ms ON m.id = ms.matiere_id
      JOIN semestres s ON ms.semestre_id = s.id
      JOIN parcoursmatiere pm ON m.id = pm.matiere_id
      JOIN parcours p ON pm.parcour_id = p.id
      WHERE (s.nom LIKE ? OR s.nom LIKE ?)
        AND ms.mention_id = ?
        AND p.nom = ?
    `)

    try {
      // Execute the query with parameters
      let response = matiereQuery.all(`%${semestre[0]}%`, `%${semestre[1]}%`, mention_id, parcours)

      console.log(response)
      // Log the response
      return response
    } catch (error) {
      return error
    }
  } else {
    if (semestre.length < 2) {
      console.error('Error: Semestre array does not contain enough elements.')
      return
    }

    // Prepare the query
    let matiereQuery = database.prepare(`
      SELECT DISTINCT m.*
      FROM matieres m
      JOIN matiere_semestre ms ON m.id = ms.matiere_id
      JOIN semestres s ON ms.semestre_id = s.id
      WHERE (s.nom LIKE ? OR s.nom LIKE ?)
        AND ms.mention_id = ?
    `)

    try {
      // Execute the query with parameters
      let response = matiereQuery.all(`%${semestre[0]}%`, `%${semestre[1]}%`, mention_id)
      console.log(response)
      // Log the response
      return response
    } catch (error) {
      return error
    }
  }
}

/**
 * function to get single matiere
 * @param {*} id
 * @returns promise
 */
async function getSingleMatiere(id) {
  const query = await database.prepare('SELECT * FROM matieres WHERE id = ?')

  try {
    let response = query.get(id)

    return response
  } catch (error) {
    return error
  }
}

/**
 * function used when updating matiere
 * @param {*} nom
 * @param {*} id
 * @returns promise
 */
async function updateMatiere(nom, id, credit, uniter, ue) {
  const query = database.prepare(
    'UPDATE matieres SET nom = ?, credit = ?, unite_enseignement = ?, heure = ?, ue = ? WHERE id = ?'
  )

  const uniterHeure = await database.prepare('SELECT uniter_heure FROM nessesaryTable').get()
  const heure = credit * uniterHeure.uniter_heure

  try {
    response = await query.run(nom, credit, uniter, heure, ue, id)

    return response
  } catch (error) {
    return error
  }
}


async function updateMatiereNiveau(formData) {
  console.log('formdata:', formData);
  const { niveau_id, id } = formData;
  const sql = 'UPDATE matieres SET niveau_id = ? WHERE id = ?';

  try {
    const [result] = await pool.query(sql, [niveau_id, id]);

    if (result.affectedRows === 0) {
      return {
        success: false,
        message: 'Matière non trouvée ou aucune modification effectuée.'
      };
    }

    return {
      success: true,
      message: 'Niveau mis à jour avec succès.'
    };
  } catch (error) {
    console.error(error);
    return {
      success: false,
      error: 'Erreur lors de la mise à jour du niveau : ' + error.message
    };
  }
}

async function deleteMatiere(id) {
  const query = database.prepare('DELETE FROM matieres WHERE id = ?')

  try {
    let response = query.run(id)

    return response
  } catch (error) {
    return error
  }
}

async function asygnationToMention(formData, id) {
  const clearQuery = database.prepare('DELETE FROM matiere_mention WHERE matiere_id = ?')
  const query = database.prepare(
    'INSERT INTO matiere_mention (matiere_id, mention_id) VALUES (?,?)'
  )
  const selectedKeys = Object.keys(formData).filter((key) => formData[key])
  const placeholders = selectedKeys.map(() => '?').join(',')
  // Prepare the query with placeholders
  const clearSemestreMentionQuery = database.prepare(
    `DELETE FROM matiere_semestre WHERE matiere_id = ? AND mention_id NOT IN (${placeholders})`
  )

  const clearNoreQuery = database.prepare(
    `DELETE FROM notes WHERE matiere_id = ? AND mention_id NOT IN (${placeholders})`
  )

  try {
    let response
    await clearQuery.run(id)
    await clearNoreQuery.run(id, ...selectedKeys)
    clearSemestreMentionQuery.run(id, ...selectedKeys)
    // use transaction for speed execution
    database.transaction(() => {
      for (let index = 0; index < selectedKeys.length; index++) {
        response = query.run(id, selectedKeys[index])
      }
    })()

    return response
  } catch (error) {
    return error
  }
}

async function getMentionMatiere(id) {
  const query = database.prepare('SELECT * FROM matiere_mention WHERE matiere_id = ?')

  try {
    let response = await query.all(id)

    return response
  } catch (error) {
    return error
  }
}

async function getMentionMatiereChecked(matiere_id) {
  const getMentionMatiere = database.prepare('SELECT * FROM matiere_mention WHERE matiere_id = ?')
  let MentionArray = await getMentionMatiere.all(matiere_id)
  let arrayID = []

  for (let index = 0; index < MentionArray.length; index++) {
    arrayID.push(MentionArray[index].mention_id)
  }

  const mentionQuery = database.prepare(
    `SELECT * FROM mentions WHERE id IN (${arrayID.map(() => '?').join(', ')})`
  )

  try {
    const results = await mentionQuery.all(...arrayID)

    return results
  } catch (error) {
    return error
  }
}

async function getSemestreMatiere(id) {
  const query = database.prepare('SELECT * FROM matiere_semestre WHERE matiere_id = ?')

  try {
    let response = await query.all(id)

    return response
  } catch (error) {
    return error
  }
}

async function getSemestre() {
  const query = database.prepare('SELECT * FROM semestres')

  try {
    let response = await query.all()

    return response
  } catch (error) {
    return error
  }
}

async function insertUpdateMentionSemestre(matiere_id, formData) {
  const clearQuery = database.prepare('DELETE FROM matiere_semestre WHERE matiere_id = ?')
  clearQuery.run(matiere_id)

  const query = database.prepare(
    'INSERT INTO matiere_semestre (matiere_id, semestre_id, mention_id) VALUES (?, ?, ?)'
  )
  let response
  database.transaction(() => {
    for (const key in formData) {
      if (formData.hasOwnProperty(key)) {
        for (let jindex = 0; jindex < formData[key].length; jindex++) {
          response = query.run(matiere_id, formData[key][jindex], key)
        }
      }
    }
  })()
  return response
}

async function getEnseignants() {
  const getIdQuery = database.prepare(
    'SELECT id FROM matiereEnseignants GROUP BY matiere_id ORDER BY MAX(date) DESC'
  )

  const query = database.prepare(
    'SELECT * FROM matiereEnseignants WHERE id IN (' +
      new Array(getIdQuery.all().length).fill('?').join(',') +
      ')'
  )

  try {
    // Get the latest `id` for each `matiere_id`
    const latestIds = getIdQuery.all().map((row) => row.id)

    // If no ids exist, return an empty array
    if (latestIds.length === 0) {
      return []
    }

    // Fetch the full details using the filtered IDs
    let response = query.all(...latestIds)

    return response
  } catch (error) {
    return error
  }
}

async function insertNewProf(matiere_id, nom, prenom, contact, date) {
  const query = database.prepare(
    'INSERT INTO matiereEnseignants (matiere_id, nom_enseignant, prenom_enseignant, contact, date) VALUES (?, ?, ?, ?, ?)'
  )

  try {
    let response = query.run(matiere_id, nom, prenom, contact, date)

    return response
  } catch (error) {
    return error
  }
}

async function getSIngleProf(id) {
  try {
    const prof = await database
      .prepare('SELECT * FROM matiereEnseignants WHERE matiere_id = ?')
      .get(id)

    return prof
  } catch (error) {
    return error
  }
}

async function updateProf(matiere_id, nom, prenom, contact, date) {
  const query = database.prepare(
    'UPDATE matiereEnseignants SET nom_enseignant = ?, prenom_enseignant = ?, contact = ?, date = ? WHERE matiere_id = ?'
  )

  try {
    let response = query.run(nom, prenom, contact, date, matiere_id)

    return response
  } catch (error) {
    return error
  }
}

module.exports = {
  createMatiere,
  getSIngleProf,
  getMatiere,
  getSingleMatiere,
  updateMatiere,
  updateMatiereNiveau,
  displayMatiereFromForm,
  deleteMatiere,
  asygnationToMention,
  getMentionMatiere,
  getMentionMatiereChecked,
  getSemestreMatiere,
  getSemestre,
  insertUpdateMentionSemestre,
  getEnseignants,
  insertNewProf,
  updateProf
}
