// Current-user API token CRUD. The raw token is returned exactly once at
// creation time; only the SHA-256 hash and an 8-char display prefix are stored.
import express from 'express';
import pool from '../db/pool.js';
import { generateToken, hashToken, tokenDisplayPrefix } from '../auth/tokens.js';

const router = express.Router();

// GET / — list current user's tokens (prefix only, never the raw token)
router.get('/', async (req, res, next) => {
  try {
    const { rows } = await pool.query(
      `SELECT id, name, token_prefix AS prefix, bound_hostname, last_used_at, expires_at, created_at
       FROM api_tokens WHERE user_id = $1 ORDER BY created_at DESC`,
      [req.user.id]);
    res.json(rows);
  } catch (err) { next(err); }
});

// POST / — create a new token. Optional bound_hostname binds the token to a
// specific node-agent hostname (migration 019) — the /cluster/heartbeat handler
// rejects heartbeats whose body.hostname doesn't match a bound token.
router.post('/', async (req, res, next) => {
  try {
    const { name, expires_at, bound_hostname } = req.body || {};
    if (!name || typeof name !== 'string') return res.status(400).json({ error: 'name required' });
    if (bound_hostname !== undefined && bound_hostname !== null && typeof bound_hostname !== 'string') {
      return res.status(400).json({ error: 'bound_hostname must be a string' });
    }
    const raw = generateToken();
    const { rows } = await pool.query(
      `INSERT INTO api_tokens (user_id, name, token_hash, token_prefix, expires_at, bound_hostname)
       VALUES ($1, $2, $3, $4, $5, $6)
       RETURNING id, name, token_prefix AS prefix, bound_hostname, expires_at, created_at`,
      [req.user.id, name.trim(), hashToken(raw), tokenDisplayPrefix(raw),
       expires_at || null, bound_hostname?.trim() || null]);
    res.status(201).json({ ...rows[0], token: raw });   // raw token shown exactly once
  } catch (err) { next(err); }
});

// DELETE /:id — revoke; only the owner can revoke
router.delete('/:id', async (req, res, next) => {
  try {
    const { rowCount } = await pool.query(
      `DELETE FROM api_tokens WHERE id = $1 AND user_id = $2`,
      [req.params.id, req.user.id]);
    if (rowCount === 0) return res.status(404).json({ error: 'token not found' });
    res.status(204).end();
  } catch (err) { next(err); }
});

export default router;
