const mysql = require('mysql2/promise')
const bcrypt = require('bcryptjs')

  const pool = mysql.createPool({
    host: '192.168.200.200',
    user: 'root',
    password: 'stephane1313',
    database: 'university',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
})

async function createTables() {
  const connection = await pool.getConnection()

  try {
    // Users table
    await connection.query(`
      CREATE TABLE IF NOT EXISTS users (
        id INT AUTO_INCREMENT PRIMARY KEY,
        username VARCHAR(200) NOT NULL,
        email VARCHAR(250) NOT NULL UNIQUE,
        password TEXT NOT NULL,
        roles VARCHAR(250) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    // Status table
    await connection.query(`
      CREATE TABLE IF NOT EXISTS status (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nom VARCHAR(200) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    // Mentions table
    await connection.query(`
      CREATE TABLE IF NOT EXISTS mentions (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nom VARCHAR(250) NOT NULL,
        uniter VARCHAR(50) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS niveaus (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nom VARCHAR(50) UNIQUE NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS etudiants (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nom VARCHAR(250) DEFAULT NULL,
        prenom VARCHAR(250) DEFAULT NULL,
        photos TEXT DEFAULT NULL,
        date_de_naissances DATE DEFAULT NULL,
        niveau VARCHAR(250) NOT NULL,
        annee_scolaire VARCHAR(20) NOT NULL,
        status INT DEFAULT NULL,
        mention_id INT NOT NULL,
        num_inscription TEXT UNIQUE NOT NULL,
        sexe VARCHAR(20) DEFAULT NULL,
        cin VARCHAR(250) DEFAULT NULL,
        date_delivrance TEXT DEFAULT NULL,
        nationalite VARCHAR(250) DEFAULT NULL,
        annee_bacc TEXT DEFAULT NULL,
        serie VARCHAR(20) DEFAULT NULL,
        boursier VARCHAR(20) DEFAULT NULL,
        domaine VARCHAR(250) DEFAULT NULL,
        contact VARCHAR(20) DEFAULT NULL,
        parcours VARCHAR(250) DEFAULT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        FOREIGN KEY (status) REFERENCES status(id),
        FOREIGN KEY (mention_id) REFERENCES mentions(id)
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS matieres (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nom VARCHAR(250) UNIQUE NOT NULL,
        unite_enseignement VARCHAR(250) NOT NULL,
        credit INT NOT NULL,
        heure INT NOT NULL,
        ue VARCHAR(10) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS semestres (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nom VARCHAR(30) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS matiere_mention (
        id INT AUTO_INCREMENT PRIMARY KEY,
        matiere_id INT NOT NULL,
        mention_id INT NOT NULL,
        FOREIGN KEY (matiere_id) REFERENCES matieres(id),
        FOREIGN KEY (mention_id) REFERENCES mentions(id)
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS matiere_semestre (
        id INT AUTO_INCREMENT PRIMARY KEY,
        matiere_id INT NOT NULL,
        semestre_id INT NOT NULL,
        mention_id INT NOT NULL,
        FOREIGN KEY (matiere_id) REFERENCES matieres(id),
        FOREIGN KEY (semestre_id) REFERENCES semestres(id),
        FOREIGN KEY (mention_id) REFERENCES mentions(id)
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS notes (
        id INT AUTO_INCREMENT PRIMARY KEY,
        etudiant_id INT NOT NULL,
        matiere_id INT NOT NULL,
        etudiant_niveau VARCHAR(50) NOT NULL,
        mention_id INT NOT NULL,
        note FLOAT DEFAULT NULL,
        annee_scolaire VARCHAR(50) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        FOREIGN KEY (etudiant_id) REFERENCES etudiants(id),
        FOREIGN KEY (matiere_id) REFERENCES matieres(id),
        FOREIGN KEY (mention_id) REFERENCES mentions(id)
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS notesrepech (
        id INT AUTO_INCREMENT PRIMARY KEY,
        etudiant_id INT NOT NULL,
        matiere_id INT NOT NULL,
        etudiant_niveau VARCHAR(50) NOT NULL,
        mention_id INT NOT NULL,
        note FLOAT DEFAULT NULL,
        annee_scolaire VARCHAR(50) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        FOREIGN KEY (etudiant_id) REFERENCES etudiants(id),
        FOREIGN KEY (matiere_id) REFERENCES matieres(id),
        FOREIGN KEY (mention_id) REFERENCES mentions(id)
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS notesystems (
        id INT AUTO_INCREMENT PRIMARY KEY,
        admis FLOAT NOT NULL DEFAULT 10,
        redouble FLOAT NOT NULL DEFAULT 9.99,
        renvoyer FLOAT NOT NULL DEFAULT 7.99,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS anneescolaire (
        id INT AUTO_INCREMENT PRIMARY KEY,
        code VARCHAR(30) NOT NULL,
        debut DATE NOT NULL,
        fin DATE NOT NULL,
        is_current TINYINT(1) DEFAULT 0,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS traitmentsystem (
        id INT AUTO_INCREMENT PRIMARY KEY,
        code VARCHAR(30) NOT NULL,
        debut DATE NOT NULL,
        fin DATE NOT NULL,
        is_finished TINYINT(1) DEFAULT 0,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS nessesaryTable (
        id INT AUTO_INCREMENT PRIMARY KEY,
        uniter_heure INT NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS matiereEnseignants (
        id INT AUTO_INCREMENT PRIMARY KEY,
        matiere_id INT NOT NULL,
        nom_enseignant VARCHAR(250) NOT NULL,
        prenom_enseignant VARCHAR(250) NOT NULL,
        contact VARCHAR(11) NOT NULL,
        date DATE NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        FOREIGN KEY (matiere_id) REFERENCES matieres(id)
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS parcours (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nom VARCHAR(250) NOT NULL,
        uniter VARCHAR(250) NOT NULL,
        mention_id INT DEFAULT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS parcoursmatiere (
        id INT AUTO_INCREMENT PRIMARY KEY,
        matiere_id INT NOT NULL,
        parcour_id INT NOT NULL,
        FOREIGN KEY (matiere_id) REFERENCES matieres(id),
        FOREIGN KEY (parcour_id) REFERENCES parcours(id)
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS trancheecolage (
        id INT AUTO_INCREMENT PRIMARY KEY,
        etudiant_id INT NOT NULL,
        tranchename VARCHAR(255) NOT NULL,
        montant DOUBLE NOT NULL
      ) ENGINE=InnoDB;
    `)

    await connection.query(`
      CREATE TABLE IF NOT EXISTS ipconfig (
        id INT AUTO_INCREMENT PRIMARY KEY,
        ipname VARCHAR(255) NOT NULL
      ) ENGINE=InnoDB;
    `)
  } finally {
    connection.release()
  }
}

async function insertDefaultAdmin() {
  const conn = await pool.getConnection()
  try {
    const [rows] = await conn.query(`SELECT COUNT(*) as count FROM users WHERE username = ?`, [
      'admin'
    ])
    if (rows[0].count === 0) {
      const hashedPassword = bcrypt.hashSync('123456789', 10)
      await conn.query(
        `
        INSERT INTO users (username, email, password, roles)
        VALUES (?, ?, ?, ?)`,
        ['admin', 'admin@example.com', hashedPassword, 'admin']
      )
    }
  } finally {
    conn.release()
  }
}

async function insertStatusesIfNotExist() {
  const conn = await pool.getConnection()
  try {
    const statuses = ['Nouveau', 'Passant', 'Redoublant', 'Renvoyé', 'Ancien']
    for (let name of statuses) {
      const [rows] = await conn.query(`SELECT COUNT(*) as count FROM status WHERE nom = ?`, [name])
      if (rows[0].count === 0) {
        await conn.query(`INSERT INTO status (nom) VALUES (?)`, [name])
      }
    }
  } finally {
    conn.release()
  }
}

module.exports = {
  pool,
  createTables,
  insertDefaultAdmin,
  insertStatusesIfNotExist
}
