
import { Request, Response } from "express";
import { User } from "../../database/user/user";
import { messages } from "../../utills/common";
import { sendErrorResponse, sendSuccessResponse } from "../../utills/response";
import { UserPortfolio } from "../../database/transaction/usersPortfolio";
import { Transaction } from "../../database/transaction/transaction";

// get all user
export const getAllUsers = async (req: Request, res: Response) => {
    try {
        const { page = '1', limit = '10', search } = req.query;
        const pageNum = Math.max(1, parseInt(page as string, 10));
        const limitNum = Math.max(1, Math.min(100, parseInt(limit as string, 10)));
        const skip = (pageNum - 1) * limitNum;

        let userQuery = User.createQueryBuilder("user")
            .where({ isAdmin: false })
            .orderBy("user.created_at", "DESC");

        if (search) {
            userQuery = userQuery.andWhere("(user.name LIKE :search OR user.email LIKE :search OR user.phone LIKE :search)", { search: `%${search}%` });
        }

        const [users, totalCount] = await userQuery
            .skip(skip)
            .take(limitNum)
            .getManyAndCount();

        const totalPages = Math.ceil(totalCount / limitNum);

        return sendSuccessResponse(res, 200, messages.UserMsg, {
            users,
            pagination: {
                currentPage: pageNum,
                totalPages,
                totalCount,
                limit: limitNum
            }
        });
    } catch (error) {
        return sendErrorResponse(res, 500, messages.errorMsg);
    }
};

// create api for the user graph
export const getUsersByYear = async (req: Request, res: Response) => {
    try {
        const currentYear = new Date().getFullYear();
        const lastFiveYears = currentYear - 5;

        const result = await User
            .createQueryBuilder("user")
            .select("YEAR(user.created_at) as year")
            .addSelect("COUNT(*) as count")
            .where("user.isAdmin = :isAdmin", { isAdmin: false })
            .andWhere("YEAR(user.created_at) BETWEEN :lastFiveYears AND :currentYear", { lastFiveYears, currentYear })
            .groupBy("year")
            .orderBy("year")
            .getRawMany();

        const yearlyCounts = result.reduce((acc, { year, count }) => {
            acc[year] = parseInt(count);

            return acc;
        }, {});
        const yearlyData = [];
        for (let year = lastFiveYears; year <= currentYear; year++) {
            yearlyData.push({ year: year.toString(), count: yearlyCounts[year.toString()] || 0 });
        }

        return sendSuccessResponse(res, 200, messages.UserMsg, yearlyData);
    } catch (error) {
        return sendErrorResponse(res, 500, messages.errorMsg);
    }
};

// get user profit
export const getUserProfit = async (req: Request, res: Response) => {
    try {
        const userId = req.params.id;

        // Fetch transactions for the user
        const transactions = await Transaction.createQueryBuilder("transaction")
            .orderBy("transaction.created_at", "DESC")
            .where({ userId })
            .andWhere({})
            .getMany();

        // Calculate pending deposit amount for the user
        let pendingDepositAmount = 0;
        transactions.forEach(tr => {
            if (!tr.iswithdrawAmount) {
                pendingDepositAmount += tr.withdrawAmount;
            }
        });

        // Fetch user portfolio
        const userPortfolio = await UserPortfolio.createQueryBuilder("userPortfolio")
            .orderBy("userPortfolio.created_at", "DESC")
            .getMany();

        // Total invested amount by the user
  
        const investedAmount = transactions[0]?.totalInvestedAmount;

        // Total invested amount across all users
        // const totalInvestedAmount = userPortfolio?.investedAmount ?? 0;

        // Total profit for all users
        // const totalProfit = userPortfolio?.dayEndPortfolio ?? 0;

        // // Total invested amount across all users
        const totalInvestedAmount = userPortfolio.reduce((sum, portfolio) => sum + portfolio.investedAmount, 0);
        // // Total profit for all users
        const totalProfit = userPortfolio.reduce((sum, portfolio) => sum + portfolio.dayEndPortfolio, 0);
        const dailyProfitPercentage = userPortfolio[0]?.dailyProfitPercentage;

        // Calculate profit for the specific user's invested amount
        let userProfit = 0;
        if (totalProfit !== undefined && totalInvestedAmount !== undefined) {
            // userProfit = (totalProfit / totalInvestedAmount) * investedAmount;
            userProfit = (investedAmount * dailyProfitPercentage) / 100;
        }

        // const userProfitOnInvestAmount = userProfit - investedAmount;
        // const quantCapitalProfit = userProfit * 20 / 100;
        const actualProfit = userProfit / 0.8;
     
        const quantCapitalProfit = actualProfit * 0.2;

        return sendSuccessResponse(res, 200, messages.viewData, {
            investedAmount,
            totalProfitAmount: userProfit,
            pendingDepositAmount,
            quantCapitalProfit
        });
    } catch (error) {
        console.log("error",error);
        
        return sendErrorResponse(res, 500, messages.errorMsg);
    }
};
