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

// Function to insert a user into the database
async function insertUser(username, email, password, roles) {
  const saltRounds = 10

  try {
    // Await the bcrypt hashing to complete before proceeding
    const hashedPassword = await bcrypt.hash(password, saltRounds)

    // Prepare and run the insert query using the hashed password
    const insertUserQuery = database.prepare(
      'INSERT INTO users (username, email, password, roles) VALUES (?, ?, ?, ?)'
    )
    const insertedUser = await insertUserQuery.run(username, email, hashedPassword, roles)

    return insertedUser
  } catch (err) {
    return err
  }
}

// Function to fetch all users from the database
async function getAllUsers() {
  const getUsersQuery = database.prepare('SELECT * FROM users')
  let response = await getUsersQuery.all()

  return response
}

// Function to login a user
async function loginUser(username, password) {
  // Prepare the query to get the user by username
  const loginUserQuery = database.prepare('SELECT * FROM users WHERE LOWER(username) = ?')

  try {
    // Execute the query and get the user from the database
    const user = await loginUserQuery.get(username.toLowerCase())

    if (user) {
      // Use bcrypt to compare the provided password with the stored hashed password
      const isPasswordValid = await bcrypt.compare(password, user.password)

      if (isPasswordValid) {
        // If password matches, return the user
        return user
      } else {
        // If password does not match
        console.log('Invalid password')
      }
    } else {
      // If no user is found with the provided username
      console.log('User not found')
    }
  } catch (err) {
    console.error('Error during login:', err)
  }
}

/**
 * function to use in forgit password
 *
 * @param {*} email
 * @param {*} password
 * @param {*} passwordConfirmation
 * @returns
 */
async function forgotPassword(email, password, passwordConfirmation) {
  const saltRounds = 10
  const forgotPasswordQuery = database.prepare('SELECT * FROM users WHERE email = ?')

  if (password == passwordConfirmation) {
    const user = await forgotPasswordQuery.get(email)

    if (user) {
      const updateQuery = database.prepare('UPDATE users SET password = ? WHERE email = ?')
      const hashedPassword = await bcrypt.hash(password, saltRounds)

      try {
        await updateQuery.run(hashedPassword, email)

        return { message: 'Mot de passe modifier avec succes', status: 200 }
      } catch (error) {
        console.error('Error updating password:', error)
      }
    } else {
      return { message: 'Email non trouver', status: 404 }
    }
  } else {
    return { message: 'Mot de passe ne correspond pas', status: 401 }
  }
}

/**
 * function to use when updatign the users
 *
 * @param {*} username
 * @param {*} email
 * @param {*} password
 * @param {*} id
 * @returns promise
 */
async function updateUser(username, email, password, id) {
  const saltRounds = 10

  try {
    let query
    let response

    if (password === '') {
      // Update without changing the password
      if (username === '' && email !== '') {
        query = database.prepare('UPDATE users SET email = ? WHERE id = ?')
        response = await query.run(email, id)
      } else if (email === '' && username !== '') {
        query = database.prepare('UPDATE users SET username = ? WHERE id = ?')
        response = await query.run(username, id)
      } else if (username !== '' && email !== '') {
        query = database.prepare('UPDATE users SET username = ?, email = ? WHERE id = ?')
        response = await query.run(username, email, id)
      }
    } else {
      // Update with a new hashed password
      const hashedPassword = await bcrypt.hash(password, saltRounds)
      query = database.prepare(
        'UPDATE users SET username = ?, email = ?, password = ? WHERE id = ?'
      )
      response = await query.run(username, email, hashedPassword, id)
    }

    // Fetch the updated user after the update
    const getUserQuery = database.prepare('SELECT * FROM users WHERE id = ?')
    const updatedUser = await getUserQuery.get(id)

    return updatedUser // Return the updated user
  } catch (error) {
    console.error('Error updating user:', error)
    throw error // Throw error to handle it in calling function if needed
  }
}

module.exports = {
  getAllUsers,
  insertUser,
  loginUser,
  forgotPassword,
  updateUser
}
