'use strict';

// Signup email-verification tokens. The emailed token is random and stored ONLY as a
// SHA-256 hash (single-use, same discipline as recovery codes / api tokens) — the
// plaintext lives just in the email link. One pending token per user, kept on the users
// row (email_verify_hash + email_verify_expires), so a resend simply overwrites the old.

const crypto = require('crypto');
const { db } = require('../db/database');
const { hashToken } = require('../middleware/apiToken');

const TTL_SEC = 24 * 3600; // link valid for 24h

// Mint a fresh token for the user, store its hash + expiry, return the PLAINTEXT (emailed once).
function issue(userId) {
  const token = crypto.randomBytes(32).toString('hex');
  const expires = Math.floor(Date.now() / 1000) + TTL_SEC;
  db.prepare('UPDATE users SET email_verify_hash = ?, email_verify_expires = ? WHERE id = ?')
    .run(hashToken(token), expires, userId);
  return token;
}

// Consume a token: mark the matching user verified + clear the token. Returns the user id on
// success, else null (unknown / expired / already-used). Single-use — the hash is cleared.
function consume(token) {
  if (!token || typeof token !== 'string') return null;
  const row = db.prepare('SELECT id, email_verify_expires FROM users WHERE email_verify_hash = ?')
    .get(hashToken(token));
  if (!row) return null;
  if (!row.email_verify_expires || row.email_verify_expires < Math.floor(Date.now() / 1000)) return null;
  db.prepare("UPDATE users SET email_verified = 1, email_verify_hash = NULL, email_verify_expires = NULL, updated_at = strftime('%s','now') WHERE id = ?")
    .run(row.id);
  return row.id;
}

module.exports = { issue, consume, TTL_SEC };
