const express = require("express");
const jwt = require("jsonwebtoken");
const crypto = require("crypto");
const { query, queryOne, transaction, queryLicense, queryOneLicense, insertLicense } = require("../db");
const { notifyLicensePurchase } = require("../telegram");

const router = express.Router();
const JWT_SECRET = process.env.JWT_SECRET || crypto.randomBytes(32).toString("hex");

// License packages config
const LICENSE_PACKAGES = {
  "1m": { name: "1 Month PRO (+3 Days Free)", price: 8, days: 33, type: "PRO" },
  "3m": { name: "3 Months PRO (+15 Days Free)", price: 24, days: 105, type: "PRO" },
  "6m": { name: "6 Months PRO (+60 Days Free)", price: 48, days: 240, type: "PRO" },
  "1y": { name: "1 Year PRO (+120 Days Free)", price: 96, days: 485, type: "PRO" },
  "3m_prem": { name: "3 Months PREMIUM (+15 Days)", price: 24, days: 105, type: "PREMIUM" },
  "6m_prem": { name: "6 Months PREMIUM (+60 Days)", price: 48, days: 240, type: "PREMIUM" },
  "1y_prem": { name: "1 Year PREMIUM (+120 Days)", price: 96, days: 485, type: "PREMIUM" }
};

// Auth middleware
async function auth(req, res, next) {
  const header = req.headers.authorization;
  if (!header) return res.status(401).json({ message: "No token" });
  const token = header.replace("Bearer ", "");
  try {
    const decoded = jwt.verify(token, JWT_SECRET);
    const user = await queryOne("SELECT * FROM users WHERE id = ?", [decoded.id]);
    if (!user) return res.status(401).json({ message: "User not found" });
    req.user = user;
    req.user.balance = parseFloat(user.balance);
    next();
  } catch {
    res.status(401).json({ message: "Invalid token" });
  }
}


// Auto-create licenses table if not exists
(async () => {
  try {
    await queryLicense(`CREATE TABLE IF NOT EXISTS licenses (
      id INT AUTO_INCREMENT PRIMARY KEY,
      user_name VARCHAR(100),
      license_key VARCHAR(100) UNIQUE,
      expiry_date DATE,
      is_active TINYINT(1) DEFAULT 1,
      package_type VARCHAR(20),
      hwid VARCHAR(255) DEFAULT NULL,
      reset_count INT DEFAULT 0,
      last_reset_date DATE DEFAULT NULL,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
  } catch (err) {
    console.error("[License] Table creation error:", err.message);
  }
})();

// Generate a license key
function generateLicenseKey(type) {
  const parts = [];
  for (let i = 0; i < 4; i++) {
    const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let part = "";
    for (let j = 0; j < 4; j++) {
      part += chars.charAt(crypto.randomInt(0, chars.length));
    }
    parts.push(part);
  }
  return `${type}-${parts.join("-")}`;
}

// GET /zapi/license/packages — list available packages
router.get("/packages", (req, res) => {
  const packages = Object.entries(LICENSE_PACKAGES).map(([id, pkg]) => ({
    id,
    name: pkg.name,
    price: pkg.price,
    days: pkg.days,
    type: pkg.type,
  }));
  res.json(packages);
});

// POST /zapi/license/buy — purchase a new license key
router.post("/buy", auth, async (req, res) => {
  try {
    const { packageId } = req.body;

    if (!packageId || !LICENSE_PACKAGES[packageId]) {
      return res.status(400).json({ message: "កញ្ចប់មិនត្រឹមត្រូវ" });
    }

    const pkg = LICENSE_PACKAGES[packageId];
    const price = pkg.price;

    // Use transaction for safe balance deduction
    let newBalance, licenseKey, expiryDate;
    try {
      const result = await transaction(async (conn) => {
        // Lock user row
        const [rows] = await conn.execute(
          "SELECT balance FROM users WHERE id = ? FOR UPDATE",
          [req.user.id]
        );
        const currentBalance = parseFloat(rows[0].balance);

        if (currentBalance < price) {
          throw new Error(`INSUFFICIENT_BALANCE:${price}:${currentBalance}`);
        }

        const updatedBalance = parseFloat((currentBalance - price).toFixed(3));
        await conn.execute("UPDATE users SET balance = ? WHERE id = ?", [updatedBalance, req.user.id]);

        // Generate license key
        const key = generateLicenseKey(pkg.type);
        const expiry = new Date();
        expiry.setDate(expiry.getDate() + pkg.days);
        const expiryStr = expiry.toISOString().split("T")[0];

        // Save license to DB
        await insertLicense(
          `INSERT INTO licenses (user_name, license_key, expiry_date, is_active, package_type, reset_count) VALUES (?, ?, ?, 1, ?, 0)`,
          [req.user.username, key, expiryStr, packageId]
        );

        return { newBalance: updatedBalance, licenseKey: key, expiryDate: expiryStr };
      });

      newBalance = result.newBalance;
      licenseKey = result.licenseKey;
      expiryDate = result.expiryDate;
    } catch (err) {
      if (err.message.startsWith("INSUFFICIENT_BALANCE:")) {
        const [, needed, have] = err.message.split(":");
        return res.status(400).json({
          message: `Balance មិនគ្រប់គ្រាន់ — ត្រូវការ $${parseFloat(needed).toFixed(2)} មាន $${parseFloat(have).toFixed(3)}`,
        });
      }
      throw err;
    }

    // Notify admin via Telegram
    notifyLicensePurchase({
      username: req.user.username,
      packageName: pkg.name,
      price,
      licenseKey,
      expiryDate,
    });

    res.json({
      message: "ទិញ License Key ជោគជ័យ! ✅",
      license: {
        key: licenseKey,
        package: pkg.name,
        type: pkg.type,
        expiryDate,
        days: pkg.days,
      },
      newBalance,
    });
  } catch (err) {
    console.error("[License Buy]", err.message);
    res.status(500).json({ message: "Server error — សូមព្យាយorg់ម្ដងទៀត" });
  }
});


// POST /zapi/license/renew — renew an existing license key
router.post("/renew", auth, async (req, res) => {
  try {
    const { licenseKey, packageId } = req.body;

    if (!licenseKey || !packageId || !LICENSE_PACKAGES[packageId]) {
      return res.status(400).json({ message: "ព័ត៌មានមិនត្រឹមត្រូវ" });
    }

    const pkg = LICENSE_PACKAGES[packageId];
    const price = pkg.price;

    // Check if key exists
    const existing = await queryOneLicense(
      "SELECT * FROM licenses WHERE license_key = ?",
      [licenseKey.trim()]
    );
    if (!existing) {
      return res.status(404).json({ message: "រកមិនឃើញ License Key នេះទេ" });
    }

    let newBalance, newExpiry;
    try {
      const result = await transaction(async (conn) => {
        const [rows] = await conn.execute(
          "SELECT balance FROM users WHERE id = ? FOR UPDATE",
          [req.user.id]
        );
        const currentBalance = parseFloat(rows[0].balance);

        if (currentBalance < price) {
          throw new Error(`INSUFFICIENT_BALANCE:${price}:${currentBalance}`);
        }

        const updatedBalance = parseFloat((currentBalance - price).toFixed(3));
        await conn.execute("UPDATE users SET balance = ? WHERE id = ?", [updatedBalance, req.user.id]);

        // Calculate new expiry
        const currentExpiry = new Date(existing.expiry_date);
        const now = new Date();
        const baseDate = currentExpiry > now ? currentExpiry : now;
        baseDate.setDate(baseDate.getDate() + pkg.days);
        const newExp = baseDate.toISOString().split("T")[0];

        // Update license
        await insertLicense(
          `UPDATE licenses SET expiry_date = ?, package_type = ?, user_name = ?, 
           is_active = 1 WHERE license_key = ?`,
          [newExp, packageId, req.user.username, licenseKey.trim()]
        );

        return { newBalance: updatedBalance, newExpiry: newExp };
      });

      newBalance = result.newBalance;
      newExpiry = result.newExpiry;
    } catch (err) {
      if (err.message.startsWith("INSUFFICIENT_BALANCE:")) {
        const [, needed, have] = err.message.split(":");
        return res.status(400).json({
          message: `Balance មិនគ្រប់គ្រាន់ — ត្រូវការ $${parseFloat(needed).toFixed(2)} មាន $${parseFloat(have).toFixed(3)}`,
        });
      }
      throw err;
    }

    res.json({
      message: "បន្តថ្ងៃ License Key ជោគជ័យ! ✅",
      license: {
        key: licenseKey,
        package: pkg.name,
        type: pkg.type,
        expiryDate: newExpiry,
        days: pkg.days,
      },
      newBalance,
    });
  } catch (err) {
    console.error("[License Renew]", err.message);
    res.status(500).json({ message: "Server error — សូមព្យorg់ម្ដងទៀត" });
  }
});

// GET /zapi/license/my-keys — get user's purchased licenses
router.get("/my-keys", auth, async (req, res) => {
  try {
    const licenses = await queryLicense(
      "SELECT * FROM licenses WHERE user_name = ? ORDER BY created_at DESC",
      [req.user.username]
    );
    // Map package_type to package_name
    const mapped = licenses.map(l => ({
      ...l,
      package_name: LICENSE_PACKAGES[l.package_type] ? LICENSE_PACKAGES[l.package_type].name : l.package_type
    }));
    res.json(mapped);
  } catch (err) {
    console.error("[License My Keys]", err.message);
    res.json([]);
  }
});

// POST /zapi/license/check — check a license key status
router.post("/check", async (req, res) => {
  try {
    const { licenseKey, hwid } = req.body;
    if (!licenseKey) return res.status(400).json({ message: "សូមបញ្ចូល License Key" });

    const license = await queryOneLicense(
      "SELECT license_key, package_type, hwid, expiry_date, is_active, created_at FROM licenses WHERE license_key = ?",
      [licenseKey.trim()]
    );

    if (!license) {
      return res.status(404).json({ message: "រកមិនឃើញ License Key នេះទេ" });
    }

    const isExpired = new Date(license.expiry_date) < new Date();
    let status = "active";
    
    if (!license.is_active) {
      status = "banned";
    } else if (isExpired) {
      status = "expired";
    } else if (hwid) {
      // HWID Anti-Piracy Check
      if (!license.hwid) {
        // First time use: Bind HWID
        await queryLicense("UPDATE licenses SET hwid = ? WHERE license_key = ?", [hwid.trim(), license.license_key]);
      } else if (license.hwid !== hwid.trim()) {
        // HWID mismatch
        return res.status(403).json({ 
          status: "hwid_mismatch", 
          message: "License Key នេះត្រូវបានប្រើប្រាស់នៅលើកុំព្យូទ័រផ្សេងហើយ។ សូមទាក់ទង Admin ដើម្បី Reset HWID។" 
        });
      }
    }

    const pkgName = LICENSE_PACKAGES[license.package_type] ? LICENSE_PACKAGES[license.package_type].name : license.package_type;

    res.json({
      key: license.license_key,
      package: pkgName,
      expiryDate: license.expiry_date,
      status,
      createdAt: license.created_at,
    });
  } catch (err) {
    console.error("[License Check]", err.message);
    res.status(500).json({ message: "Server error" });
  }
});

// POST /zapi/license/reset-hwid — reset HWID (Admin only)
router.post("/reset-hwid", auth, async (req, res) => {
  try {
    if (req.user.role !== "admin") return res.status(403).json({ message: "Admin only" });
    
    const { licenseKey } = req.body;
    if (!licenseKey) return res.status(400).json({ message: "Missing licenseKey" });

    const updateRes = await queryLicense("UPDATE licenses SET hwid = NULL WHERE license_key = ?", [licenseKey.trim()]);
    if (updateRes.affectedRows === 0) {
      return res.status(404).json({ message: "រកមិនឃើញ License Key នេះទេ" });
    }

    res.json({ message: "បាន Reset HWID រួចរាល់! អាចប្រើលើកុំព្យូទ័រថ្មីបានហើយ។" });
  } catch (err) {
    console.error("[Reset HWID]", err.message);
    res.status(500).json({ message: "Server error" });
  }
});

module.exports = router;
