const router = require('express').Router();
const bcrypt = require('bcryptjs');
const pool = require('../config/db');
const auth = require('../middleware/auth');
const { requireRole } = require('../middleware/auth');
const { uid, logActivity } = require('../models/helpers');
const { getLogStats, getArchivePath, deleteArchive } = require('../models/logBackup');

const FIREWALL_KEY = 'report_firewall_password';

router.use(auth);

// === Report Firewall Password (master_admin only) ===
// Change firewall password — requires current master_admin account password + old firewall password
router.put('/firewall-password', requireRole('master_admin'), async (req, res) => {
  try {
    const { account_password, old_firewall, new_firewall, confirm_firewall } = req.body;
    if (!account_password || !old_firewall || !new_firewall || !confirm_firewall) {
      return res.status(400).json({ error: 'All fields are required' });
    }
    if (new_firewall !== confirm_firewall) {
      return res.status(400).json({ error: 'New password confirmation does not match' });
    }
    if (new_firewall.length < 4) {
      return res.status(400).json({ error: 'New password must be at least 4 characters' });
    }

    // Verify account password
    const [users] = await pool.query('SELECT password FROM users WHERE id = ?', [req.user.id]);
    if (users.length === 0) return res.status(401).json({ error: 'Account not found' });
    const accountOk = await bcrypt.compare(account_password, users[0].password);
    if (!accountOk) return res.status(401).json({ error: 'Account password is incorrect' });

    // Verify old firewall password
    const [rows] = await pool.query('SELECT value FROM app_settings WHERE key_name = ?', [FIREWALL_KEY]);
    if (rows.length === 0) return res.status(500).json({ error: 'Firewall not configured' });
    const oldOk = await bcrypt.compare(old_firewall, rows[0].value);
    if (!oldOk) return res.status(401).json({ error: 'Old firewall password is incorrect' });

    const hash = await bcrypt.hash(new_firewall, 10);
    await pool.query(
      'INSERT INTO app_settings (key_name, value) VALUES (?, ?) ON DUPLICATE KEY UPDATE value = VALUES(value)',
      [FIREWALL_KEY, hash]
    );
    await logActivity(pool, 'update', 'firewall', FIREWALL_KEY, 'Firewall password changed');
    res.json({ ok: true });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// === Payment Methods ===
// Get (all roles — needed for order creation)
router.get('/payment-methods', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM payment_methods ORDER BY name');
    res.json(rows.map(r => r.name));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Add (master_admin only)
router.post('/payment-methods', requireRole('master_admin'), async (req, res) => {
  try {
    const { name } = req.body;
    if (!name) return res.status(400).json({ error: 'Name required' });
    await pool.query('INSERT INTO payment_methods (name) VALUES (?)', [name.trim()]);
    res.status(201).json({ name: name.trim() });
  } catch (err) {
    if (err.code === 'ER_DUP_ENTRY') return res.status(400).json({ error: 'Already exists' });
    res.status(500).json({ error: err.message });
  }
});

// Delete (master_admin only)
router.delete('/payment-methods/:name', requireRole('master_admin'), async (req, res) => {
  try {
    await pool.query('DELETE FROM payment_methods WHERE name = ?', [req.params.name]);
    res.json({ message: 'Deleted' });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// === Activity Log (master_admin only) ===
router.get('/activity-log', requireRole('master_admin'), async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM activity_log ORDER BY created_at DESC LIMIT 50');
    res.json(rows);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Restore from activity log (master_admin only)
router.post('/activity-log/:id/restore', requireRole('master_admin'), async (req, res) => {
  const conn = await pool.getConnection();
  try {
    await conn.beginTransaction();

    const [logs] = await conn.query('SELECT * FROM activity_log WHERE id = ?', [req.params.id]);
    if (logs.length === 0) return res.status(404).json({ error: 'Not found' });

    const log = logs[0];
    const snapshot = typeof log.snapshot === 'string' ? JSON.parse(log.snapshot) : log.snapshot;

    if (!snapshot) return res.status(400).json({ error: 'No snapshot to restore' });

    if (snapshot.t === 'order_cancel') {
      await conn.query("UPDATE orders SET status = 'confirmed' WHERE id = ?", [snapshot.id]);
      for (const item of snapshot.items) {
        await conn.query('UPDATE products SET stock_qty = stock_qty - ? WHERE id = ?', [item.qty, item.product_id]);
      }
    } else if (snapshot.t === 'order_refund') {
      await conn.query("UPDATE orders SET status = 'confirmed' WHERE id = ?", [snapshot.id]);
    } else if (snapshot.t === 'client_del') {
      await conn.query('UPDATE clients SET is_deleted = 0 WHERE id = ?', [snapshot.id]);
    } else if (snapshot.t === 'prod_del') {
      const p = snapshot.prod;
      await conn.query(
        'INSERT INTO products (id, name, description, mg, ml, route, cost_price, retail_price, stock_qty, batch, expiry, supplier, low_threshold) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
        [p.id, p.name, p.description, p.mg, p.ml, p.route, p.cost_price, p.retail_price, p.stock_qty, p.batch, p.expiry, p.supplier, p.low_threshold]
      );
    }

    await conn.query('UPDATE activity_log SET restored = 1 WHERE id = ?', [req.params.id]);
    await logActivity(conn, 'restore', log.entity, log.entity_id, 'Restored');

    await conn.commit();
    res.json({ message: 'Restored successfully' });
  } catch (err) {
    await conn.rollback();
    res.status(500).json({ error: err.message });
  } finally {
    conn.release();
  }
});

// === Log Backup Management (master_admin only) ===
router.get('/logs/stats', requireRole('master_admin'), (req, res) => {
  try {
    const stats = getLogStats();
    res.json(stats);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

router.get('/logs/download/:filename', requireRole('master_admin'), (req, res) => {
  const fp = getArchivePath(req.params.filename);
  if (!fp) return res.status(404).json({ error: 'File not found' });
  res.setHeader('Content-Disposition', `attachment; filename=${req.params.filename}`);
  res.setHeader('Content-Type', 'application/x-ndjson');
  require('fs').createReadStream(fp).pipe(res);
});

router.delete('/logs/:filename', requireRole('master_admin'), (req, res) => {
  const ok = deleteArchive(req.params.filename);
  if (!ok) return res.status(400).json({ error: 'Cannot delete this file' });
  res.json({ message: 'Archive deleted' });
});

module.exports = router;
