const express = require("express");
const router = express.Router();
const Token = require("../models/token.model.js");
const TradingToken = require("../models/leaderboard.model.js");
const { authenticate } = require("../middleware/login.middleware.js");

// GET tokens with image, address, price, and balance
router.get("/user/:userId/tokens", authenticate, async (req, res) => {
  try {
    const { userId } = req.params;

    const tokens = await Token.find({ userId });
    const trades = await TradingToken.find({ userId });

    const tokenSummary = {};

    trades.forEach((trade) => {
      const address = trade.tokenAddress;
      const buy = parseFloat(trade.tokenBuy) || 0;
      const sell = parseFloat(trade.tokenSell) || 0;

      if (!tokenSummary[address]) {
        tokenSummary[address] = {
          buy: 0,
          sell: 0,
          price: trade.tokenprice || "0",
        };
      }

      tokenSummary[address].buy += buy;
      tokenSummary[address].sell += sell;
      tokenSummary[address].price =
        trade.tokenprice || tokenSummary[address].price;
    });

    const result = tokens.map((token) => {
      const address = token.tokenAddress;
      const summary = tokenSummary[address] || { buy: 0, sell: 0, price: "0" };
      const totalToken = summary.buy - summary.sell;

      return {
        name: token.name,
        symbol: token.symbol,
        image_url: token.image_url,
        tokenAddress: token.tokenAddress,
        tokenprice: summary.price,
        totalToken,
        description: token.description,
        web: token.web,
        telegram: token.telegram,
        x: token.x,
      };
    });

    res.json(result);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: "Server error" });
  }
});

router.get("/leaderboard/:userId", async (req, res) => {
  try {
    const { userId } = req.params;

    // 1. Get all trades by user
    const userTrades = await TradingToken.find({ userId }).sort({
      createdAt: -1,
    });

    const tokenMap = {};

    for (const trade of userTrades) {
      const address = trade.tokenAddress;
      const buy = parseFloat(trade.tokenBuy) || 0;
      const sell = parseFloat(trade.tokenSell) || 0;

      if (!tokenMap[address]) {
        tokenMap[address] = {
          tokenAddress: address,
          tokenName: trade.tokenName || "",
          totalBuy: 0,
          totalSell: 0,
          latestTradeTime: trade.createdAt,
          latestPrice: trade.tokenprice || "0",
        };
      }

      tokenMap[address].totalBuy += buy;
      tokenMap[address].totalSell += sell;

      // Update latest price only if this trade is more recent
      if (trade.createdAt > tokenMap[address].latestTradeTime) {
        tokenMap[address].latestTradeTime = trade.createdAt;
        tokenMap[address].latestPrice =
          trade.tokenprice || tokenMap[address].latestPrice;
      }
    }

    const leaderboard = [];

    for (const tokenAddress in tokenMap) {
      const entry = tokenMap[tokenAddress];
      const tokenMeta = await Token.findOne({ tokenAddress });

      leaderboard.push({
        tokenAddress,
        tokenName: entry.tokenName || tokenMeta?.name || "",
        totalToken: entry.totalBuy - entry.totalSell,
        latestPrice: entry.latestPrice,
        symbol: tokenMeta?.symbol || "",
        image_url: tokenMeta?.image_url || "",
        description: tokenMeta?.description || "",
      });
    }

    res.json(leaderboard);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Server error" });
  }
});

router.get("/top-tokens", async (req, res) => {
  try {
    const result = await TradingToken.aggregate([
      // Sort all trades so the latest is on top per tokenAddress
      { $sort: { createdAt: -1 } },

      // Group by tokenAddress
      {
        $group: {
          _id: "$tokenAddress",
          tokenName: { $first: "$tokenName" },
          totalBuy: {
            $sum: {
              $toDouble: { $ifNull: ["$tokenBuy", "0"] },
            },
          },
          totalSell: {
            $sum: {
              $toDouble: { $ifNull: ["$tokenSell", "0"] },
            },
          },
          latestPrice: { $first: "$tokenprice" },
          latestHolder: { $first: "$tokenholder" },
        },
      },

      // Calculate totalToken = totalBuy - totalSell
      {
        $addFields: {
          totalToken: { $add: ["$totalBuy", "$totalSell"] },
        },
      },

      // Sort descending by totalToken
      { $sort: { totalToken: -1 } },

      // Join with Token model to get image and symbol
      {
        $lookup: {
          from: "tokens", // must match actual collection name
          localField: "_id",
          foreignField: "tokenAddress",
          as: "tokenDetails",
        },
      },
      { $unwind: "$tokenDetails" },

      // Select fields to return
      {
        $project: {
          _id: 0,
          tokenAddress: "$_id",
          tokenName: 1,
          totalBuy: 1,
          totalSell: 1,
          totalToken: 1,
          latestPrice: 1,
          latestHolder: 1,
          image_url: "$tokenDetails.image_url",
          symbol: "$tokenDetails.symbol",
        },
      },
    ]);

    res.json(result);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: "Internal server error" });
  }
});

router.get("/token-holders/:tokenAddress", async (req, res) => {
  const { tokenAddress } = req.params;

  try {
    const result = await TradingToken.aggregate([
      {
        $match: {
          tokenAddress: tokenAddress,
        },
      },
      {
        $addFields: {
          buyAmount: { $toDouble: "$tokenBuy" },
          sellAmount: { $toDouble: "$tokenSell" },
        },
      },
      {
        $group: {
          _id: "$userId",
          totalBuy: { $sum: "$buyAmount" },
          totalSell: { $sum: "$sellAmount" },
        },
      },
      {
        $addFields: {
          holding: { $subtract: ["$totalBuy", "$totalSell"] },
        },
      },
      {
        $match: {
          holding: { $gte: 10 },
        },
      },
      {
        $count: "holderCount",
      },
    ]);

    const holderCount = result.length > 0 ? result[0].holderCount : 0;

    res.json({ tokenAddress, holderCount });
  } catch (error) {
    console.error("Error fetching token holders:", error);
    res.status(500).json({ error: "Server error" });
  }
});

module.exports = router;
