/**
 * routes/contact.js
 *
 * Admin → support contact form. Mounted under /api/admin/contact.
 *
 * IDOR safety:
 *  - requireLogin + requireRole('superadmin') gates every route.
 *  - author_user_id is ALWAYS derived from req.user.id (server-side).
 *    The client never gets to set it; the model never reads it from the body.
 *  - Primary key is a UUID v4 (model/contactMessage.js), not an integer, so
 *    other admins' message IDs cannot be guessed by enumeration.
 *  - getForUser() returns null for any id the requester doesn't own; the
 *    route returns 404 (not 403) so the existence of someone else's message
 *    is never leaked.
 *  - All read endpoints are scoped to the caller's user id in the WHERE
 *    clause, never a "list all" path.
 *  - apiLimiter on the write endpoint prevents spam-flooding the inbox.
 */

'use strict';

const express = require('express');
const { requireLogin, requireRole } = require('../middleware/auth');
const { api: apiLimiter } = require('../middleware/rateLimit');
const { logger } = require('../middleware/logger');
const Contact = require('../models/contactMessage');
const Audit   = require('../models/auditLog');

const router = express.Router();

// Every route below is superadmin-only.
router.use(requireLogin, requireRole('superadmin'));

// Validation helpers — keep payloads tight to avoid storage abuse and
// accidental disclosure of large blobs.
const SUBJECT_MAX = 200;
const BODY_MAX    = 4000;
function validPriority(p) {
  return p === undefined || p === null || p === '' || ['low', 'normal', 'high'].includes(p);
}

// POST /api/admin/contact — create a new message from the current admin.
router.post('/', apiLimiter, (req, res) => {
  try {
    const subject = (req.body && req.body.subject || '').toString().trim();
    const body    = (req.body && req.body.body    || '').toString().trim();
    const priority = (req.body && req.body.priority || 'normal').toString();

    if (!subject || subject.length > SUBJECT_MAX) {
      return res.status(400).json({ error: 'SUBJECT_REQUIRED', max: SUBJECT_MAX });
    }
    if (!body || body.length > BODY_MAX) {
      return res.status(400).json({ error: 'BODY_REQUIRED', max: BODY_MAX });
    }
    if (!validPriority(priority)) {
      return res.status(400).json({ error: 'BAD_PRIORITY' });
    }

    const id = Contact.create({
      authorUserId: req.user.id,
      subject, body, priority,
    });

    Audit.log({
      user_id:    req.user.id,
      action:     'contact.create',
      target_id:  id,
      ip:         req.ip,
      user_agent: (req.headers['user-agent'] || '').slice(0, 200),
      meta_json:  JSON.stringify({ subject_len: subject.length, body_len: body.length, priority }),
    }).catch(() => { /* audit is best-effort, never block user action */ });

    return res.status(201).json({ ok: true, id });
  } catch (err) {
    logger.error('contact.create.error', { message: err.message });
    return res.status(500).json({ error: 'INTERNAL_ERROR' });
  }
});

// GET /api/admin/contact — list the caller's own messages (most recent first).
// Never returns anyone else's messages. The limit caps at 200 server-side.
router.get('/', (req, res) => {
  try {
    const limit = Math.max(1, Math.min(200, parseInt(req.query.limit, 10) || 50));
    const rows  = Contact.listForUser({ authorUserId: req.user.id, limit });
    const total = Contact.countForUser({ authorUserId: req.user.id });
    return res.json({ items: rows, total });
  } catch (err) {
    logger.error('contact.list.error', { message: err.message });
    return res.status(500).json({ error: 'INTERNAL_ERROR' });
  }
});

// GET /api/admin/contact/:id — get one message IF AND ONLY IF the caller
// owns it. Returns 404 for any id that doesn't belong to req.user.id, so
// the existence of other admins' messages is never disclosed.
router.get('/:id', (req, res) => {
  try {
    const row = Contact.getForUser({ id: req.params.id, authorUserId: req.user.id });
    if (!row) return res.status(404).json({ error: 'NOT_FOUND' });
    return res.json(row);
  } catch (err) {
    logger.error('contact.get.error', { message: err.message });
    return res.status(500).json({ error: 'INTERNAL_ERROR' });
  }
});

module.exports = router;
