'use strict';

const router = require('express').Router();
const bcrypt = require('bcryptjs');
const { v4: uuidv4 } = require('uuid');
const { body, validationResult } = require('express-validator');
const { query, queryOne } = require('../config/db');
const { requireAuth, requireAdmin, generateApiKey } = require('../middleware/auth');
const { logAudit } = require('../services/audit');
const { refreshAll } = require('../services/prices');
const COINS = require('../config/coins');

// All routes require admin
router.use(requireAuth, requireAdmin);

// ── GET /admin/stats ──────────────────────────────────────────────
router.get('/stats', async (req, res) => {
  try {
    const [users, licenses, invoices, revenue] = await Promise.all([
      queryOne('SELECT COUNT(*) as total, SUM(plan!="free") as pro, SUM(status="suspended") as suspended FROM users'),
      queryOne('SELECT COUNT(*) as total, SUM(status="active") as active, SUM(status="revoked") as revoked, SUM(status="expired") as expired FROM licenses'),
      queryOne(`SELECT COUNT(*) as total, SUM(status="confirmed") as confirmed, SUM(status IN ("pending","detected")) as pending, SUM(status="expired") as expired FROM invoices`),
      queryOne('SELECT COALESCE(SUM(amount_fiat),0) as total_revenue, COALESCE(SUM(fee_fiat),0) as platform_fees FROM invoices WHERE status = "confirmed"'),
    ]);

    // Weekly signups
    const weeklySignups = await query(
      `SELECT DATE(created_at) as date, COUNT(*) as count
       FROM users WHERE created_at > DATE_SUB(NOW(), INTERVAL 7 DAY)
       GROUP BY DATE(created_at) ORDER BY date ASC`
    );

    // Top coins by volume
    const topCoins = await query(
      `SELECT coin, COUNT(*) as count, SUM(amount_fiat) as volume
       FROM invoices WHERE status = "confirmed"
       GROUP BY coin ORDER BY volume DESC LIMIT 5`
    );

    return res.json({
      users:        { ...users },
      licenses:     { ...licenses },
      invoices:     { ...invoices },
      revenue:      { ...revenue },
      weekly_signups: weeklySignups,
      top_coins:    topCoins,
    });
  } catch (err) {
    console.error('[ADMIN] Stats error:', err);
    return res.status(500).json({ error: 'Failed to fetch stats.' });
  }
});

// ── GET /admin/users ──────────────────────────────────────────────
router.get('/users', async (req, res) => {
  const { plan, status, search, limit = 50, offset = 0 } = req.query;

  let sql    = 'SELECT u.*, (SELECT COUNT(*) FROM invoices i WHERE i.user_id = u.id AND i.status = "confirmed") as invoice_count FROM users u WHERE 1=1';
  const params = [];

  if (plan)   { sql += ' AND u.plan = ?';   params.push(plan); }
  if (status) { sql += ' AND u.status = ?'; params.push(status); }
  if (search) { sql += ' AND (u.email LIKE ? OR u.name LIKE ?)'; params.push(`%${search}%`, `%${search}%`); }

  sql += ' ORDER BY u.created_at DESC LIMIT ? OFFSET ?';
  params.push(parseInt(limit), parseInt(offset));

  try {
    const rows  = await query(sql, params);
    const total = await queryOne('SELECT COUNT(*) as cnt FROM users u WHERE 1=1' + (plan ? ' AND plan=?' : '') + (status ? ' AND status=?' : ''), params.slice(0, -2));
    return res.json({ users: rows.map(u => ({ ...u, password_hash: undefined })), total: total.cnt });
  } catch (err) {
    return res.status(500).json({ error: 'Failed to fetch users.' });
  }
});

// ── GET /admin/users/:id ──────────────────────────────────────────
router.get('/users/:id', async (req, res) => {
  try {
    const user = await queryOne(
      `SELECT u.*, us.*,
              (SELECT COUNT(*) FROM invoices i WHERE i.user_id = u.id) as total_invoices,
              (SELECT COALESCE(SUM(amount_fiat),0) FROM invoices i WHERE i.user_id = u.id AND i.status='confirmed') as total_revenue
       FROM users u LEFT JOIN user_settings us ON us.user_id = u.id
       WHERE u.id = ?`,
      [req.params.id]
    );
    if (!user) return res.status(404).json({ error: 'User not found.' });

    const stores  = await query('SELECT * FROM stores WHERE user_id = ?',   [req.params.id]);
    const apiKeys = await query('SELECT * FROM api_keys WHERE user_id = ?', [req.params.id]);
    const licKey  = await queryOne('SELECT * FROM licenses WHERE user_id = ? AND status = "active" LIMIT 1', [req.params.id]);

    return res.json({ user: { ...user, password_hash: undefined }, stores, api_keys: apiKeys, license: licKey });
  } catch (err) {
    return res.status(500).json({ error: 'Failed.' });
  }
});

// ── PATCH /admin/users/:id ────────────────────────────────────────
router.patch('/users/:id',
  [body('plan').optional().isIn(['free','pro','enterprise']),
   body('status').optional().isIn(['active','suspended','pending']),
   body('role').optional().isIn(['client','admin','superadmin'])],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });

    const { plan, status, role, name } = req.body;
    const updates = [];
    const params  = [];

    if (plan)   { updates.push('plan = ?');   params.push(plan); }
    if (status) { updates.push('status = ?'); params.push(status); }
    if (role)   { updates.push('role = ?');   params.push(role); }
    if (name)   { updates.push('name = ?');   params.push(name); }

    if (!updates.length) return res.status(400).json({ error: 'Nothing to update.' });

    try {
      params.push(req.params.id);
      await query(`UPDATE users SET ${updates.join(', ')} WHERE id = ?`, params);
      await logAudit(null, req.user.id, 'admin.user.update', 'user', req.params.id, req.body);
      return res.json({ ok: true, message: 'User updated.' });
    } catch (err) {
      return res.status(500).json({ error: 'Update failed.' });
    }
  }
);

// ── DELETE /admin/users/:id ───────────────────────────────────────
router.delete('/users/:id', async (req, res) => {
  if (String(req.params.id) === String(req.user.id)) {
    return res.status(400).json({ error: 'Cannot delete your own account.' });
  }
  try {
    await query('DELETE FROM users WHERE id = ?', [req.params.id]);
    await logAudit(null, req.user.id, 'admin.user.delete', 'user', req.params.id, {});
    return res.json({ ok: true, message: 'User deleted.' });
  } catch (err) {
    return res.status(500).json({ error: 'Delete failed.' });
  }
});

// ── GET /admin/invoices ───────────────────────────────────────────
router.get('/invoices', async (req, res) => {
  const { status, coin, user_id, limit = 50, offset = 0 } = req.query;

  let sql    = 'SELECT i.*, u.email, u.name FROM invoices i LEFT JOIN users u ON u.id = i.user_id WHERE 1=1';
  const params = [];

  if (status)  { sql += ' AND i.status = ?';  params.push(status); }
  if (coin)    { sql += ' AND i.coin = ?';    params.push(coin); }
  if (user_id) { sql += ' AND i.user_id = ?'; params.push(user_id); }

  sql += ' ORDER BY i.created_at DESC LIMIT ? OFFSET ?';
  params.push(parseInt(limit), parseInt(offset));

  try {
    const rows = await query(sql, params);
    return res.json({ invoices: rows });
  } catch (err) {
    return res.status(500).json({ error: 'Failed.' });
  }
});

// ── GET /admin/coins ──────────────────────────────────────────────
router.get('/coins', async (req, res) => {
  return res.json({ coins: COINS });
});

// ── POST /admin/prices/refresh ────────────────────────────────────
router.post('/prices/refresh', async (req, res) => {
  try {
    const prices = await refreshAll('USD');
    return res.json({ ok: true, prices, count: Object.keys(prices).length });
  } catch (err) {
    return res.status(500).json({ error: 'Price refresh failed.' });
  }
});

// ── GET /admin/audit ──────────────────────────────────────────────
router.get('/audit', async (req, res) => {
  try {
    const rows = await query(
      `SELECT al.*, u.email FROM audit_log al
       LEFT JOIN users u ON u.id = al.user_id
       ORDER BY al.created_at DESC LIMIT 200`
    );
    return res.json({ logs: rows });
  } catch (err) {
    return res.status(500).json({ error: 'Failed.' });
  }
});

// ── GET /admin/webhook-logs ───────────────────────────────────────
router.get('/webhook-logs', async (req, res) => {
  try {
    const rows = await query(
      `SELECT wl.*, u.email FROM webhook_logs wl
       JOIN webhooks w ON w.id = wl.webhook_id
       JOIN users u ON u.id = w.user_id
       ORDER BY wl.created_at DESC LIMIT 100`
    );
    return res.json({ logs: rows });
  } catch (err) {
    return res.status(500).json({ error: 'Failed.' });
  }
});

// ── POST /admin/reset-user-password ──────────────────────────────
router.post('/users/:id/reset-password',
  [body('password').isLength({ min: 8 })],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });

    try {
      const hash = await bcrypt.hash(req.body.password, 12);
      await query('UPDATE users SET password_hash = ? WHERE id = ?', [hash, req.params.id]);
      await logAudit(null, req.user.id, 'admin.user.password_reset', 'user', req.params.id, {});
      return res.json({ ok: true, message: 'Password reset.' });
    } catch (err) {
      return res.status(500).json({ error: 'Failed.' });
    }
  }
);

module.exports = router;
