const express = require('express');
const router  = express.Router();
const { getDb, getSetting, setSetting } = require('../db/database');
const { requireAuth, requireUser, requireAdmin } = require('../middleware/requireAuth');
const { sendTestEmail } = require('../services/notificationService');
const { sendTestPush }  = require('../services/notificationService')._push || {};
const { decryptSecret } = require('../services/encryptionService');
const { encryptSecret } = require('../services/encryptionService');

// ── Admin: SMTP configuration ─────────────────────────────────────────────────

// GET /api/notifications/admin — read all SMTP settings (password masked)
router.get('/admin', requireAuth, requireAdmin, (req, res) => {
  const keys = [
    'notify_smtp_enabled', 'notify_sender_name', 'notify_sender_address',
    'notify_smtp_host', 'notify_smtp_port', 'notify_smtp_encryption',
    'notify_smtp_self_signed', 'notify_smtp_username', 'notify_smtp_password',
    'notify_allow_user_config', 'notify_global_recipient',
  ];
  const settings = {};
  for (const k of keys) settings[k] = getSetting(k) || '';
  // Mask password in response
  if (settings.notify_smtp_password) settings.notify_smtp_password = '••••••••';
  res.json(settings);
});

// PUT /api/notifications/admin — save SMTP settings
router.put('/admin', requireAuth, requireAdmin, (req, res) => {
  const allowed = [
    'notify_smtp_enabled', 'notify_sender_name', 'notify_sender_address',
    'notify_smtp_host', 'notify_smtp_port', 'notify_smtp_encryption',
    'notify_smtp_self_signed', 'notify_smtp_username',
    'notify_allow_user_config', 'notify_global_recipient',
  ];
  for (const key of allowed) {
    if (req.body[key] !== undefined) setSetting(key, req.body[key]);
  }
  // Only update password if a real value was sent (not the masked placeholder)
  if (req.body.notify_smtp_password && !req.body.notify_smtp_password.startsWith('•')) {
    setSetting('notify_smtp_password', encryptSecret(req.body.notify_smtp_password));
  }
  res.json({ success: true });
});

// POST /api/notifications/test — send a test email
router.post('/test', requireAuth, requireAdmin, async (req, res) => {
  const { to } = req.body;
  if (!to) return res.status(400).json({ error: 'Recipient address required' });
  try {
    await sendTestEmail(to);
    res.json({ success: true });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// ── User: notification preferences ───────────────────────────────────────────

// GET /api/notifications/me — user prefs + whether admin has enabled it
router.get('/me', requireAuth, requireUser, (req, res) => {
  const db   = getDb();
  const user = db.prepare(`
    SELECT notification_email, notifications_enabled,
           notify_3d, notify_1d, notify_due, notify_overdue, notify_amount_change
    FROM users WHERE id = ?
  `).get(req.user.id);

  res.json({
    smtp_enabled:          getSetting('notify_smtp_enabled') === 'true',
    allow_user_config:     getSetting('notify_allow_user_config') === 'true',
    notification_email:    user.notification_email  || '',
    notifications_enabled: !!user.notifications_enabled,
    notify_3d:             !!user.notify_3d,
    notify_1d:             !!user.notify_1d,
    notify_due:            !!user.notify_due,
    notify_overdue:        !!user.notify_overdue,
    notify_amount_change:  user.notify_amount_change !== 0,
  });
});

// PUT /api/notifications/me — save user prefs
router.put('/me', requireAuth, requireUser, (req, res) => {
  const db = getDb();
  const {
    notification_email, notifications_enabled,
    notify_3d, notify_1d, notify_due, notify_overdue, notify_amount_change,
  } = req.body;

  db.prepare(`
    UPDATE users SET
      notification_email    = ?,
      notifications_enabled = ?,
      notify_3d             = ?,
      notify_1d             = ?,
      notify_due            = ?,
      notify_overdue        = ?,
      notify_amount_change  = ?,
      updated_at            = datetime('now')
    WHERE id = ?
  `).run(
    notification_email      || null,
    notifications_enabled   ? 1 : 0,
    notify_3d   !== false   ? 1 : 0,
    notify_1d   !== false   ? 1 : 0,
    notify_due  !== false   ? 1 : 0,
    notify_overdue !== false ? 1 : 0,
    notify_amount_change !== false ? 1 : 0,
    req.user.id,
  );

  res.json({ success: true });
});

// POST /api/notifications/test-push — send a test push notification to the current user
router.post('/test-push', requireAuth, requireUser, async (req, res) => {
  const db   = getDb();
  const user = db.prepare(`
    SELECT notify_push_enabled, push_channel, push_url, push_token, push_chat_id
    FROM users WHERE id = ?
  `).get(req.user.id);

  if (!user?.push_channel || !user?.push_url) {
    return res.status(400).json({ error: 'Push notification channel not configured' });
  }

  // Decrypt for sending
  const safeDecrypt = (v) => { try { return v ? decryptSecret(v) : ''; } catch { return v || ''; } };
  const userForPush = {
    ...user,
    notify_push_enabled: 1,
    push_url:   safeDecrypt(user.push_url),
    push_token: safeDecrypt(user.push_token),
  };

  try {
    if (!sendTestPush) throw new Error('Push service not initialised');
    await sendTestPush(userForPush);
    res.json({ success: true });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

module.exports = router;
