const { query } = require('../../utils/db')

const COLS = 'id, token_hash, user_id, status, requested_ip, expires_at, created_at, used_at'

async function insert({ tokenHash, userId, requestedIp, expiresAt }) {
  const res = await query(
    `INSERT INTO password_resets (token_hash, user_id, requested_ip, expires_at)
     VALUES (?, ?, ?, ?)`,
    [tokenHash, userId, requestedIp ?? null, expiresAt],
  )
  return res.insertId
}

async function getById(id) {
  const rows = await query(`SELECT ${COLS} FROM password_resets WHERE id = ? LIMIT 1`, [id])
  return rows[0] || null
}

async function findByTokenHash(tokenHash) {
  const rows = await query(`SELECT ${COLS} FROM password_resets WHERE token_hash = ? LIMIT 1`, [tokenHash])
  return rows[0] || null
}

// Mark used only if still pending (atomic guard against a double-use race).
// Returns rows changed (1 = we won, 0 = already used).
async function markUsed(id) {
  const res = await query(
    `UPDATE password_resets SET status = 'used', used_at = NOW()
      WHERE id = ? AND status = 'pending'`,
    [id],
  )
  return res.affectedRows || 0
}

// Invalidate any still-pending resets for a user (e.g. after a successful reset,
// or when a fresh request supersedes older links). Idempotent.
async function invalidatePendingForUser(userId) {
  const res = await query(
    `UPDATE password_resets SET status = 'used', used_at = NOW()
      WHERE user_id = ? AND status = 'pending'`,
    [userId],
  )
  return res.affectedRows || 0
}

module.exports = { insert, getById, findByTokenHash, markUsed, invalidatePendingForUser }
