import crypto from 'node:crypto'

const SCRYPT_KEY_LENGTH = 64

function scryptAsync(password, salt) {
  return new Promise((resolve, reject) => {
    crypto.scrypt(password, salt, SCRYPT_KEY_LENGTH, (error, derivedKey) => {
      if (error) {
        reject(error)
        return
      }

      resolve(derivedKey)
    })
  })
}

export async function hashPassword(password) {
  const salt = crypto.randomBytes(16).toString('hex')
  const derivedKey = await scryptAsync(password, salt)
  return `${salt}:${derivedKey.toString('hex')}`
}

export async function verifyPassword(password, storedHash) {
  const [salt, originalHash] = storedHash.split(':')

  if (!salt || !originalHash) {
    return false
  }

  const derivedKey = await scryptAsync(password, salt)
  const originalBuffer = Buffer.from(originalHash, 'hex')

  if (originalBuffer.length !== derivedKey.length) {
    return false
  }

  return crypto.timingSafeEqual(originalBuffer, derivedKey)
}

export function createSessionToken() {
  return crypto.randomBytes(32).toString('hex')
}

export function hashSessionToken(token) {
  return crypto.createHash('sha256').update(token).digest('hex')
}
