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

// SQL for the revoked_sessions denylist. Rows are keyed on a session's JWT `jti`
// and carry the token's own expiry so they can be pruned once the underlying JWT
// would fail verification anyway. This is the web/cookie analogue of
// mobile_refresh_tokens (opaque, DB-stored, revocable).

// Add a jti to the denylist. INSERT IGNORE makes a repeat logout of the same
// session a harmless no-op (the PK already exists). Returns rows changed.
async function add({ jti, userId = null, expiresAt }) {
  const res = await query(
    `INSERT IGNORE INTO revoked_sessions (jti, user_id, expires_at)
     VALUES (?, ?, ?)`,
    [jti, userId, new Date(expiresAt)],
  )
  return Number(res.affectedRows || 0)
}

// True if this jti is on the denylist and not yet past its stored expiry. Past
// expiry the token itself is already invalid, so a lingering row need not match.
async function isRevoked(jti) {
  if (!jti) return false
  const rows = await query(
    'SELECT 1 FROM revoked_sessions WHERE jti = ? AND expires_at > NOW() LIMIT 1',
    [jti],
  )
  return rows.length > 0
}

// Housekeeping: drop rows whose token has already expired. Returns rows removed.
async function pruneExpired() {
  const res = await query('DELETE FROM revoked_sessions WHERE expires_at < NOW()')
  return Number(res.affectedRows || 0)
}

module.exports = {
  add,
  isRevoked,
  pruneExpired,
}
