// ── TOTP (RFC 6238) helpers ────────────────────────────────────────────────
//
// Thin wrapper around speakeasy so the controllers stay small and the verify
// logic is unit-testable in isolation. TOTP is opt-in per user: we generate a
// base32 secret, show the user a QR (otpauth URL) to add to their authenticator,
// confirm one code before enabling, and verify a code at login for users who
// have it enabled.

const speakeasy = require('speakeasy')
const QRCode = require('qrcode')

const brand = require('../config/brand')

const ISSUER = process.env.TOTP_ISSUER || brand.name

// Generate a new secret. Returns the base32 secret to persist plus the otpauth
// URL to encode in a QR code.
function generateSecret(username) {
  const secret = speakeasy.generateSecret({
    length: 20,
    name: `${ISSUER} (${username})`,
    issuer: ISSUER,
  })
  return { base32: secret.base32, otpauthUrl: secret.otpauth_url }
}

// Render an otpauth URL to a PNG data URL for <img src>.
async function qrDataUrl(otpauthUrl) {
  return QRCode.toDataURL(otpauthUrl)
}

// Verify a user-supplied 6-digit code against a stored base32 secret. A window
// of 1 tolerates minor clock skew (±30s). Returns false for missing inputs
// rather than throwing.
function verifyCode(base32Secret, token) {
  if (!base32Secret || !token) return false
  return speakeasy.totp.verify({
    secret: base32Secret,
    encoding: 'base32',
    token: String(token).trim(),
    window: 1,
  })
}

module.exports = { generateSecret, qrDataUrl, verifyCode, ISSUER }
