/**
 * routes/adminWebhooks.js
 *
 * Admin endpoints for managing webhooks + email digest subscriptions.
 * The user just sets up: "send my weekly digest to this address"
 * + "POST takedown events to https://hooks.slack.com/...".
 *
 * Authentication: requireLogin + requireRole('user') — any logged-in
 * user can manage their own webhooks/digest subs. superadmins see
 * all.
 */

'use strict';

const express = require('express');
const router  = express.Router();
const { requireLogin } = require('../middleware/auth');
const webhook = require('../services/webhook');
const { db } = require('../config/db');

router.use(requireLogin);

// --- Webhooks ---

router.get('/webhooks', (req, res) => {
  // superadmins see all; users see their own
  const rows = req.user.role === 'superadmin'
    ? webhook.list()
    : db.prepare('SELECT * FROM webhooks WHERE owner_id = ? OR owner_id IS NULL ORDER BY created_at DESC').all(req.user.id);
  res.json({ ok: true, webhooks: rows });
});

router.post('/webhooks', (req, res) => {
  const { name, url, secret, event_filter } = req.body || {};
  if (!name || !url) return res.status(400).json({ error: 'name_and_url_required' });
  try { new URL(url); } catch (e) { return res.status(400).json({ error: 'invalid_url' }); }
  if (event_filter && typeof event_filter !== 'string') return res.status(400).json({ error: 'event_filter_must_be_string' });
  try {
    const row = webhook.create({ name, url, secret: secret || null, event_filter: event_filter || null, owner_id: req.user.id });
    res.json({ ok: true, webhook: row });
  } catch (e) { res.status(500).json({ error: 'CREATE_FAILED', message: e.message }); }
});

router.patch('/webhooks/:id', (req, res) => {
  const id = parseInt(req.params.id, 10);
  const existing = db.prepare('SELECT * FROM webhooks WHERE id = ?').get(id);
  if (!existing) return res.status(404).json({ error: 'NOT_FOUND' });
  if (req.user.role !== 'superadmin' && existing.owner_id !== req.user.id) {
    return res.status(403).json({ error: 'FORBIDDEN' });
  }
  const allowed = ['name','url','secret','event_filter','active'];
  const patch = {};
  for (const k of allowed) if (req.body && k in req.body) patch[k] = req.body[k];
  if (patch.url) { try { new URL(patch.url); } catch { return res.status(400).json({ error: 'invalid_url' }); } }
  const row = webhook.update(id, patch);
  res.json({ ok: true, webhook: row });
});

router.delete('/webhooks/:id', (req, res) => {
  const id = parseInt(req.params.id, 10);
  const existing = db.prepare('SELECT * FROM webhooks WHERE id = ?').get(id);
  if (!existing) return res.status(404).json({ error: 'NOT_FOUND' });
  if (req.user.role !== 'superadmin' && existing.owner_id !== req.user.id) {
    return res.status(403).json({ error: 'FORBIDDEN' });
  }
  webhook.remove(id);
  res.json({ ok: true });
});

router.get('/webhooks/:id/deliveries', (req, res) => {
  const id = parseInt(req.params.id, 10);
  const existing = db.prepare('SELECT * FROM webhooks WHERE id = ?').get(id);
  if (!existing) return res.status(404).json({ error: 'NOT_FOUND' });
  if (req.user.role !== 'superadmin' && existing.owner_id !== req.user.id) {
    return res.status(403).json({ error: 'FORBIDDEN' });
  }
  res.json({ ok: true, deliveries: webhook.listDeliveries(id, 50) });
});

// Send a test event to all (or one) webhook
router.post('/webhooks/test', async (req, res) => {
  const { webhook_id, event = 'test.ping', payload = {} } = req.body || {};
  if (webhook_id) {
    // Test a single webhook
    const w = db.prepare('SELECT * FROM webhooks WHERE id = ?').get(webhook_id);
    if (!w) return res.status(404).json({ error: 'NOT_FOUND' });
    if (req.user.role !== 'superadmin' && w.owner_id !== req.user.id) {
      return res.status(403).json({ error: 'FORBIDDEN' });
    }
    const r = await webhook.dispatch(event, { test: true, ...payload });
    res.json({ ok: true, ...r });
  } else {
    // Test all (used by the admin UI "ping all" button)
    const r = await webhook.dispatch(event, { test: true, ...payload });
    res.json({ ok: true, ...r });
  }
});

// --- Email digest subscriptions ---

router.get('/digest-subscriptions', (req, res) => {
  const rows = req.user.role === 'superadmin'
    ? db.prepare(`SELECT s.*, u.email as user_email FROM email_digest_subscriptions s LEFT JOIN users u ON u.id = s.user_id ORDER BY s.created_at DESC`).all()
    : db.prepare('SELECT * FROM email_digest_subscriptions WHERE user_id = ? ORDER BY created_at DESC').all(req.user.id);
  res.json({ ok: true, subscriptions: rows });
});

router.post('/digest-subscriptions', (req, res) => {
  const { email, cadence = 'weekly', day_of_week = 1, hour_utc = 9 } = req.body || {};
  if (!email) return res.status(400).json({ error: 'email_required' });
  if (!['daily','weekly'].includes(cadence)) return res.status(400).json({ error: 'cadence_must_be_daily_or_weekly' });
  if (day_of_week < 0 || day_of_week > 6) return res.status(400).json({ error: 'day_of_week_0_6' });
  if (hour_utc < 0 || hour_utc > 23) return res.status(400).json({ error: 'hour_utc_0_23' });
  const info = db.prepare(`INSERT INTO email_digest_subscriptions (user_id, email, cadence, day_of_week, hour_utc, active, created_at) VALUES (?, ?, ?, ?, ?, 1, ?)`)
    .run(req.user.id, email, cadence, day_of_week, hour_utc, Date.now());
  const row = db.prepare('SELECT * FROM email_digest_subscriptions WHERE id = ?').get(info.lastInsertRowid);
  res.json({ ok: true, subscription: row });
});

router.patch('/digest-subscriptions/:id', (req, res) => {
  const id = parseInt(req.params.id, 10);
  const sub = db.prepare('SELECT * FROM email_digest_subscriptions WHERE id = ?').get(id);
  if (!sub) return res.status(404).json({ error: 'NOT_FOUND' });
  if (req.user.role !== 'superadmin' && sub.user_id !== req.user.id) return res.status(403).json({ error: 'FORBIDDEN' });
  const sets = [], vals = [];
  for (const k of ['email','cadence','day_of_week','hour_utc','active']) {
    if (req.body && k in req.body) { sets.push(k + ' = ?'); vals.push(req.body[k]); }
  }
  if (!sets.length) return res.json({ ok: true, subscription: sub });
  vals.push(id);
  db.prepare(`UPDATE email_digest_subscriptions SET ${sets.join(', ')} WHERE id = ?`).run(...vals);
  res.json({ ok: true, subscription: db.prepare('SELECT * FROM email_digest_subscriptions WHERE id = ?').get(id) });
});

router.delete('/digest-subscriptions/:id', (req, res) => {
  const id = parseInt(req.params.id, 10);
  const sub = db.prepare('SELECT * FROM email_digest_subscriptions WHERE id = ?').get(id);
  if (!sub) return res.status(404).json({ error: 'NOT_FOUND' });
  if (req.user.role !== 'superadmin' && sub.user_id !== req.user.id) return res.status(403).json({ error: 'FORBIDDEN' });
  db.prepare('DELETE FROM email_digest_subscriptions WHERE id = ?').run(id);
  res.json({ ok: true });
});

module.exports = router;
