/* =========================================================
   ZA-FARM-KH — Admin Routes
   Features: List users, Top up balance, Edit user, Delete user
   Protected by: JWT + role "admin"
   ========================================================= */

const express = require("express");
const jwt = require("jsonwebtoken");
const { query, queryOne, insert } = require("../db");
const { notifySecurityAlert } = require("../telegram");

const router = express.Router();
const JWT_SECRET = process.env.JWT_SECRET || "fallback";

// ═══════════════════════════════════════════════════════════
// 🛡️ Admin Auth Middleware
// ═══════════════════════════════════════════════════════════
async function requireAdmin(req, res, next) {
  try {
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith("Bearer ")) {
      return res.status(401).json({ message: "Unauthorized" });
    }

    const token = authHeader.split(" ")[1];
    const decoded = jwt.verify(token, JWT_SECRET);

    const user = await queryOne("SELECT id, username, email, role FROM users WHERE id = ?", [decoded.id]);
    if (!user || user.role !== "admin") {
      return res.status(403).json({ message: "Forbidden — Admin only" });
    }

    req.admin = user;
    next();
  } catch (err) {
    return res.status(401).json({ message: "Token invalid or expired" });
  }
}

// ═══════════════════════════════════════════════════════════
// GET /zapi/admin/users — List all users
// ═══════════════════════════════════════════════════════════
router.get("/users", requireAdmin, async (req, res) => {
  try {
    const users = await query(
      "SELECT id, username, email, telegram, balance, role, apiKey, createdAt FROM users ORDER BY createdAt DESC"
    );
    res.json(users);
  } catch (err) {
    console.error("[Admin] List users error:", err.message);
    res.status(500).json({ message: "Server error" });
  }
});

// ═══════════════════════════════════════════════════════════
// POST /zapi/admin/topup — Top up balance for a user
// ═══════════════════════════════════════════════════════════
router.post("/topup", requireAdmin, async (req, res) => {
  try {
    const { userId, amount, note } = req.body;

    if (!userId || !amount) {
      return res.status(400).json({ message: "userId និង amount ត្រូវការ" });
    }

    const topupAmount = parseFloat(amount);
    if (isNaN(topupAmount) || topupAmount <= 0 || topupAmount > 10000) {
      return res.status(400).json({ message: "Amount មិនត្រឹមត្រូវ (0 < amount <= 10000)" });
    }

    const user = await queryOne("SELECT id, username, balance FROM users WHERE id = ?", [userId]);
    if (!user) {
      return res.status(404).json({ message: "រកមិនឃើញ user" });
    }

    const newBalance = parseFloat(user.balance) + topupAmount;
    await query("UPDATE users SET balance = ? WHERE id = ?", [newBalance, userId]);

    // Log the topup (ignore if table doesn't exist)
    try {
      await query(
        `INSERT INTO admin_logs (adminId, action, targetUserId, amount, note, createdAt)
         VALUES (?, ?, ?, ?, ?, ?)`,
        [req.admin.id, "topup", userId, topupAmount, note || "", new Date()]
      );
    } catch (e) { /* admin_logs table might not exist */ }

    console.log(`💰 [Admin] ${req.admin.username} topped up $${topupAmount} to ${user.username} (new balance: $${newBalance.toFixed(3)})`);

    res.json({
      message: `បញ្ចូល $${topupAmount.toFixed(3)} ទៅ ${user.username} រួចរាល់`,
      newBalance: newBalance,
    });
  } catch (err) {
    console.error("[Admin] Topup error:", err.message);
    res.status(500).json({ message: "Server error" });
  }
});

// ═══════════════════════════════════════════════════════════
// POST /zapi/admin/deduct — Deduct balance from a user
// ═══════════════════════════════════════════════════════════
router.post("/deduct", requireAdmin, async (req, res) => {
  try {
    const { userId, amount, note } = req.body;

    if (!userId || !amount) {
      return res.status(400).json({ message: "userId និង amount ត្រូវការ" });
    }

    const deductAmount = parseFloat(amount);
    if (isNaN(deductAmount) || deductAmount <= 0) {
      return res.status(400).json({ message: "Amount មិនត្រឹមត្រូវ" });
    }

    const user = await queryOne("SELECT id, username, balance FROM users WHERE id = ?", [userId]);
    if (!user) {
      return res.status(404).json({ message: "រកមិនឃើញ user" });
    }

    const newBalance = Math.max(0, parseFloat(user.balance) - deductAmount);
    await query("UPDATE users SET balance = ? WHERE id = ?", [newBalance, userId]);

    try {
      await query(
        `INSERT INTO admin_logs (adminId, action, targetUserId, amount, note, createdAt)
         VALUES (?, ?, ?, ?, ?, ?)`,
        [req.admin.id, "deduct", userId, -deductAmount, note || "", new Date()]
      );
    } catch (e) { /* admin_logs table might not exist */ }

    res.json({
      message: `ដក $${deductAmount.toFixed(3)} ពី ${user.username} រួចរាល់`,
      newBalance: newBalance,
    });
  } catch (err) {
    console.error("[Admin] Deduct error:", err.message);
    res.status(500).json({ message: "Server error" });
  }
});

// ═══════════════════════════════════════════════════════════
// POST /zapi/admin/set-role — Change user role
// ═══════════════════════════════════════════════════════════
router.post("/set-role", requireAdmin, async (req, res) => {
  try {
    const { userId, role } = req.body;
    const validRoles = ["user", "admin"];

    if (!userId || !role || !validRoles.includes(role)) {
      return res.status(400).json({ message: "userId និង role (user/admin) ត្រូវការ" });
    }

    const user = await queryOne("SELECT id, username FROM users WHERE id = ?", [userId]);
    if (!user) {
      return res.status(404).json({ message: "រកមិនឃើញ user" });
    }

    await query("UPDATE users SET role = ? WHERE id = ?", [role, userId]);

    try {
      await query(
        `INSERT INTO admin_logs (adminId, action, targetUserId, amount, note, createdAt)
         VALUES (?, ?, ?, ?, ?, ?)`,
        [req.admin.id, "set-role", userId, 0, `Role changed to: ${role}`, new Date()]
      );
    } catch (e) { /* admin_logs table might not exist */ }

    res.json({ message: `${user.username} role ត្រូវបានប្ដូរទៅ ${role}` });
  } catch (err) {
    console.error("[Admin] Set role error:", err.message);
    res.status(500).json({ message: "Server error" });
  }
});

// ═══════════════════════════════════════════════════════════
// DELETE /zapi/admin/user/:id — Delete a user
// ═══════════════════════════════════════════════════════════
router.delete("/user/:id", requireAdmin, async (req, res) => {
  try {
    const userId = req.params.id;

    if (userId === req.admin.id) {
      return res.status(400).json({ message: "មិនអាចលុបខ្លួនឯងបានទេ" });
    }

    const user = await queryOne("SELECT id, username FROM users WHERE id = ?", [userId]);
    if (!user) {
      return res.status(404).json({ message: "រកមិនឃើញ user" });
    }

    await query("DELETE FROM users WHERE id = ?", [userId]);

    try {
      await query(
        `INSERT INTO admin_logs (adminId, action, targetUserId, amount, note, createdAt)
         VALUES (?, ?, ?, ?, ?, ?)`,
        [req.admin.id, "delete", userId, 0, `Deleted user: ${user.username}`, new Date()]
      );
    } catch (e) { /* admin_logs table might not exist */ }

    res.json({ message: `User ${user.username} ត្រូវបានលុប` });
  } catch (err) {
    console.error("[Admin] Delete user error:", err.message);
    res.status(500).json({ message: "Server error" });
  }
});

// ═══════════════════════════════════════════════════════════
// GET /zapi/admin/stats — Dashboard stats
// ═══════════════════════════════════════════════════════════
router.get("/stats", requireAdmin, async (req, res) => {
  try {
    const totalUsers = await queryOne("SELECT COUNT(*) as count FROM users");
    const totalBalance = await queryOne("SELECT SUM(balance) as total FROM users");

    let totalOrders = { count: 0 };
    let todayOrders = { count: 0 };
    try {
      totalOrders = await queryOne("SELECT COUNT(*) as count FROM orders");
      todayOrders = await queryOne("SELECT COUNT(*) as count FROM orders WHERE DATE(createdAt) = CURDATE()");
    } catch (e) { /* orders table might not exist */ }

    let recentLogs = [];
    try {
      recentLogs = await query("SELECT * FROM admin_logs ORDER BY createdAt DESC LIMIT 20");
    } catch (e) { /* admin_logs table might not exist yet */ }

    res.json({
      totalUsers: totalUsers?.count || 0,
      totalBalance: parseFloat(totalBalance?.total || 0).toFixed(3),
      totalOrders: totalOrders?.count || 0,
      todayOrders: todayOrders?.count || 0,
      recentLogs,
    });
  } catch (err) {
    console.error("[Admin] Stats error:", err.message);
    res.status(500).json({ message: "Server error" });
  }
});

// ═══════════════════════════════════════════════════════════
// GET /zapi/admin/logs — Admin action logs
// ═══════════════════════════════════════════════════════════
router.get("/logs", requireAdmin, async (req, res) => {
  try {
    const logs = await query(
      `SELECT al.*, u.username as adminName, tu.username as targetName
       FROM admin_logs al
       LEFT JOIN users u ON al.adminId = u.id
       LEFT JOIN users tu ON al.targetUserId = tu.id
       ORDER BY al.createdAt DESC LIMIT 100`
    );
    res.json(logs);
  } catch (err) {
    res.json([]);
  }
});

// ═══════════════════════════════════════════════════════════
// GET /zapi/admin/orders — Recent orders with user details
// ═══════════════════════════════════════════════════════════
router.get("/orders", requireAdmin, async (req, res) => {
  try {
    const limit = parseInt(req.query.limit) || 50;
    const page  = parseInt(req.query.page)  || 1;
    const offset = (page - 1) * limit;
    const search = req.query.search || "";
    const userId = req.query.userId || "";

    let sql = `
      SELECT o.id, o.service, o.qty, o.total, o.status, o.createdAt,
             u.username, u.email, u.id as userId
      FROM orders o
      LEFT JOIN users u ON o.userId = u.id
    `;
    const params = [];
    const where = [];
    if (userId) {
      where.push("o.userId = ?");
      params.push(userId);
    }
    if (search) {
      where.push("(u.username LIKE ? OR u.email LIKE ? OR o.service LIKE ? OR o.id LIKE ?)");
      params.push(`%${search}%`, `%${search}%`, `%${search}%`, `%${search}%`);
    }
    if (where.length > 0) {
      sql += " WHERE " + where.join(" AND ");
    }
    sql += ` ORDER BY o.createdAt DESC LIMIT ? OFFSET ?`;
    params.push(limit, offset);

    const orders = await query(sql, params);

    let totalSql = `SELECT COUNT(*) as cnt FROM orders o LEFT JOIN users u ON o.userId = u.id`;
    const totalParams = [];
    if (where.length > 0) {
      totalSql += " WHERE " + where.join(" AND ");
      if (userId) totalParams.push(userId);
      if (search) totalParams.push(`%${search}%`, `%${search}%`, `%${search}%`, `%${search}%`);
    }
    const totalRow = await queryOne(totalSql, totalParams);

    res.json({ orders, total: totalRow?.cnt || 0, page, limit });
  } catch (err) {
    console.error("[Admin] Orders error:", err.message);
    res.json({ orders: [], total: 0 });
  }
});

// ═══════════════════════════════════════════════════════════
// GET /zapi/admin/licenses — Get all license keys sold
// ═══════════════════════════════════════════════════════════
router.get("/licenses", requireAdmin, async (req, res) => {
  try {
    const search = req.query.search || "";
    let sql = "SELECT * FROM licenses";
    const params = [];
    if (search) {
      sql += " WHERE username LIKE ? OR license_key LIKE ? OR package_name LIKE ?";
      params.push(`%${search}%`, `%${search}%`, `%${search}%`);
    }
    sql += " ORDER BY created_at DESC LIMIT 100";
    const licenses = await query(sql, params);
    res.json({ licenses });
  } catch (err) {
    console.error("[Admin] Licenses error:", err.message);
    res.json({ licenses: [] });
  }
});

// ═══════════════════════════════════════════════════════════
// GET /zapi/admin/customer/:id/history — Full 360° Customer Inspection
// ═══════════════════════════════════════════════════════════
router.get("/customer/:id/history", requireAdmin, async (req, res) => {
  try {
    const { id } = req.params;
    const user = await queryOne("SELECT id, username, email, telegram, balance, role, createdAt FROM users WHERE id = ?", [id]);
    if (!user) return res.status(404).json({ message: "User not found" });

    const orders = await query("SELECT id, service, qty, total, status, createdAt FROM orders WHERE userId = ? ORDER BY createdAt DESC LIMIT 100", [id]);
    const licenses = await query("SELECT id, license_key, package_name, expiry_date, is_active, created_at FROM licenses WHERE user_id = ? ORDER BY created_at DESC LIMIT 100", [id]);
    const spendRow = await queryOne("SELECT SUM(total) as totalSpent, COUNT(*) as orderCount FROM orders WHERE userId = ? AND status = 'success'", [id]);

    res.json({
      user,
      stats: {
        totalSpent: parseFloat(spendRow?.totalSpent || 0).toFixed(3),
        orderCount: spendRow?.orderCount || 0,
        licenseCount: licenses.length
      },
      orders,
      licenses
    });
  } catch (err) {
    console.error("[Admin] Customer history error:", err.message);
    res.status(500).json({ message: "Error loading customer history" });
  }
});

// ═══════════════════════════════════════════════════════════
// GET /zapi/admin/top-buyers — Top buyers leaderboard
// ═══════════════════════════════════════════════════════════
router.get("/top-buyers", requireAdmin, async (req, res) => {
  try {
    const rows = await query(`
      SELECT u.id, u.username, u.email,
             COUNT(o.id) as orderCount,
             SUM(o.total) as totalSpent,
             MAX(o.createdAt) as lastOrder
      FROM users u
      LEFT JOIN orders o ON o.userId = u.id AND o.status = 'success'
      GROUP BY u.id, u.username, u.email
      ORDER BY totalSpent DESC
      LIMIT 20
    `);
    res.json(rows);
  } catch (err) {
    console.error("[Admin] Top buyers error:", err.message);
    res.json([]);
  }
});

// ═══════════════════════════════════════════════════════════
// GET /zapi/admin/revenue — Revenue overview (daily/weekly/total)
// ═══════════════════════════════════════════════════════════
router.get("/revenue", requireAdmin, async (req, res) => {
  try {
    const today    = await queryOne(`SELECT COALESCE(SUM(total),0) as v FROM orders WHERE status='success' AND DATE(createdAt)=CURDATE()`);
    const week     = await queryOne(`SELECT COALESCE(SUM(total),0) as v FROM orders WHERE status='success' AND createdAt >= DATE_SUB(NOW(),INTERVAL 7 DAY)`);
    const month    = await queryOne(`SELECT COALESCE(SUM(total),0) as v FROM orders WHERE status='success' AND createdAt >= DATE_SUB(NOW(),INTERVAL 30 DAY)`);
    const allTime  = await queryOne(`SELECT COALESCE(SUM(total),0) as v FROM orders WHERE status='success'`);
    const pending  = await queryOne(`SELECT COALESCE(SUM(total),0) as v FROM orders WHERE status='pending'`);
    const userBal  = await queryOne(`SELECT COALESCE(SUM(balance),0) as v FROM users`);

    // Daily breakdown for the last 7 days
    const daily = await query(`
      SELECT DATE(createdAt) as date, COALESCE(SUM(total),0) as revenue, COUNT(*) as count
      FROM orders WHERE status='success' AND createdAt >= DATE_SUB(NOW(),INTERVAL 7 DAY)
      GROUP BY DATE(createdAt) ORDER BY date ASC
    `);

    res.json({
      today:    parseFloat(today?.v  || 0),
      week:     parseFloat(week?.v   || 0),
      month:    parseFloat(month?.v  || 0),
      allTime:  parseFloat(allTime?.v|| 0),
      pending:  parseFloat(pending?.v|| 0),
      userBalanceTotal: parseFloat(userBal?.v || 0),
      daily,
    });
  } catch (err) {
    console.error("[Admin] Revenue error:", err.message);
    res.json({ today:0, week:0, month:0, allTime:0, pending:0, userBalanceTotal:0, daily:[] });
  }
});

// ═══════════════════════════════════════════════════════════
// GET /zapi/admin/live — Live activity feed (last 20 orders)
// ═══════════════════════════════════════════════════════════
router.get("/live", requireAdmin, async (req, res) => {
  try {
    const rows = await query(`
      SELECT o.id, o.service, o.qty, o.total, o.status, o.createdAt,
             u.username, u.email
      FROM orders o
      LEFT JOIN users u ON o.userId = u.id
      ORDER BY o.createdAt DESC LIMIT 20
    `);
    res.json(rows);
  } catch (err) {
    res.json([]);
  }
});

// ═══════════════════════════════════════════════════════════
// GET /zapi/admin/user/:id — Single user detail + their orders
// ═══════════════════════════════════════════════════════════
router.get("/user/:id", requireAdmin, async (req, res) => {
  try {
    const user = await queryOne(
      "SELECT id, username, email, telegram, balance, role, apiKey, createdAt FROM users WHERE id = ?",
      [req.params.id]
    );
    if (!user) return res.status(404).json({ message: "User not found" });

    let orders = [];
    try {
      orders = await query(
        "SELECT id, service, qty, total, status, createdAt FROM orders WHERE userId = ? ORDER BY createdAt DESC LIMIT 30",
        [req.params.id]
      );
    } catch(e) {}

    const stats = await queryOne(
      `SELECT COUNT(*) as orderCount, COALESCE(SUM(total),0) as totalSpent
       FROM orders WHERE userId = ? AND status = 'success'`,
      [req.params.id]
    ).catch(() => ({ orderCount: 0, totalSpent: 0 }));

    res.json({ user, orders, stats });
  } catch (err) {
    res.status(500).json({ message: "Server error" });
  }
});

// ═══════════════════════════════════════════════════════════
// POST /zapi/admin/payments/:id/approve — Instant Admin Payment Override
// ═══════════════════════════════════════════════════════════
router.post("/payments/:id/approve", requireAdmin, async (req, res) => {
  try {
    const payment = await queryOne("SELECT * FROM payments WHERE id = ?", [req.params.id]);
    if (!payment) return res.status(404).json({ message: "Payment not found" });
    if (payment.status === "completed") {
      return res.json({ success: true, message: "Payment already completed" });
    }

    const newBalance = await require("../db").transaction(async (conn) => {
      await conn.execute(
        "UPDATE payments SET status = 'completed', paidAt = ? WHERE id = ?",
        [new Date(), req.params.id]
      );
      await conn.execute(
        "UPDATE users SET balance = balance + ? WHERE id = ?",
        [parseFloat(payment.amount), payment.userId]
      );
      const [rows] = await conn.execute("SELECT balance FROM users WHERE id = ?", [payment.userId]);
      return parseFloat(rows[0].balance);
    });

    res.json({ success: true, message: "Payment approved successfully", newBalance });
  } catch (err) {
    console.error("[Admin Payment Approve]", err.message);
    res.status(500).json({ message: "Error approving payment: " + err.message });
  }
});

module.exports = router;
