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

/**
 * function to insert new user
 * @param {String} username
 * @param {String} email
 * @param {String} password
 * @param {String} roles
 * @returns {Object}
 */
async function insertUser(username, email, password, roles) {
  const saltRound = 10

  try {
    const hashedPassword = await bcrypt.hash(password, saltRound)

    const sql = `
      INSERT INTO users (username, email, password, roles) VALUES (?, ?, ?, ?)
    `
    const [result] = await pool.query(sql, [username, email, hashedPassword, roles])

    // result.insertId contains the new user ID
    return {
      success: true,
      id: result.insertId
    }
  } catch (error) {
    return { success: false, error: error }
  }
}

/**
 * function to get all users
 * @returns {Array}
 */
async function getAllUsers() {
  const sql = `SELECT * FROM users`

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

    return rows
  } catch (error) {
    return 'failled to get users'
  }
}

/**
 * function to get one users
 * @param {Number} id
 * @returns {Object}
 */
async function getUserById(id) {
  const sql = `SELECT * FROM users WHERE id = ?`
  const [rows] = await pool.query(sql, [id])

  if (rows.length > 0) {
    return rows[0]
  } else {
    return null
  }
}

/**
 * function used when users try to log in
 * @param {String} username
 * @param {String} password
 * @returns {Object}
 */
async function loginUsers(username, password) {
  const sql = `SELECT * FROM users WHERE LOWER(username) = ?`

  try {
    const [rows] = await pool.query(sql, [username.toLowerCase()])

    if (rows.length === 0) {
      return { success: false, error: 'Utilisateur inexistant' }
    }

    const user = rows[0]

    // compare the password
    const passwordMatch = await bcrypt.compare(password, user.password)

    if (!passwordMatch) {
      return { success: false, error: 'Mot de passe incorrect' }
    }

    // delete the key password before return a user object
    delete user.password

    return { success: true, user }
  } catch (error) {
    return { error: 'erreur lors du login' }
  }
}

/**
 * function to update users
 * @param {String} username
 * @param {String} email
 * @param {String} password
 * @param {Number} id
 * @returns {Object}
 */
async function updateUser(username, email, password, id) {
  let sql, params

  if (password !== null || password !== '') {
    const hashedPassword = await bcrypt.hash(password, 10)
    sql = `UPDATE users SET username = ?, email = ?, password = ? WHERE id = ?`
    params = [username, email, hashedPassword, id]
  } else {
    sql = `UPDATE users SET username = ?, email = ? WHERE id = ?`
    params = [username, email, id]
  }

  try {
    const [result] = await pool.query(sql, params)

    if (result.affectedRows === 0) {
      return {
        success: false,
        message: 'Utilisateur non trouvé ou aucune modification effectuée.'
      }
    }
    const [rows] = await pool.query('SELECT * FROM users WHERE id = ?', [id])

    return {
      success: true,
      message: 'Utilisateur mis à jour avec succès.',
      users: rows[0]
    }
  } catch (error) {
    return { success: false, error: 'Erreur veullez réeseyer' }
  }
}

/**
 * function to delete users
 * @param {Number} id
 * @returns {Object}
 */
async function deleteUser(id) {
  const sql = `DELETE FROM users WHERE id = ?`

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

    if (result.affectedRows === 0) {
      return {
        success: false,
        message: 'Utilisateur non trouvé.'
      }
    }

    return {
      success: true,
      message: 'Utilisateur supprimé avec succès.'
    }
  } catch (error) {
    console.error(error)
    return {
      success: false,
      error: 'Erreur lors de la suppression, veuillez réessayer.'
    }
  }
}

module.exports = {
  insertUser,
  getAllUsers,
  getUserById,
  loginUsers,
  updateUser,
  deleteUser
}
