
const datetime = require("../../config/datetime");
const Betting = require("../model/Betting");
const Deposit = require("../model/Deposit");
const Transection = require("../model/Transection");
const Transfer = require("../model/Transfer");
const User = require("../model/User");
const Widthdrow = require("../model/Widthdrow");
const Controller = require("./Controller");
module.exports = new class DepositController extends Controller {
    dahboard = async (req, res, next) => {
        try {
            const today = datetime.today();
            const sum = (array = [], feild) => array.filter((Boolean)).reduce((total, data) => total += parseFloat(data[feild]), 0);
            // dp wid (user club)
            const dpData = await Deposit.where("status", "=", Deposit.status.success);
            const wdData = await Widthdrow.where("status", "=", Widthdrow.status.success);
            const usersAndclub = await User.where("is_block", "no");
            const users = usersAndclub.filter(u => u.role === "user");
            const clubs = usersAndclub.filter(u => u.role === "club");
            const addorcut = await Transection.where("type", "admin_add").orWhere("type", "admin_cut");

            // total dp wd clubtk usertk
            const totalAddtk = sum(addorcut.filter(t => t.type == "admin_add"), "credit");
            const totalCuttk = sum(addorcut.filter(t => t.type == "admin_cut"), "debit");



            // -------------
            const send = {};
            // total balence section
            const totalDp = sum(dpData, "taka") + totalAddtk;
            const totalWd = sum(wdData, "taka") + totalCuttk;
            const totalCbtk = sum(clubs, "taka");
            const totalUstk = sum(users, "taka");
            const profit = (parseFloat(totalDp)) - (parseFloat(totalWd) + parseFloat(totalUstk) + parseFloat(totalCbtk)) //(dp+addtk)-(wd+user+club+cutk) ==profite;
            send.totalDeposit = this.getTaka(totalDp);
            send.totalWidthdraw = this.getTaka(totalWd);
            send.profit = this.getTaka(profit).replace("-", "loss ")
            // user
            const todayaddcut = addorcut.filter(d => d.date == (today));
            const totalAddtktoday = sum(todayaddcut.filter(t => t.type == "admin_add"), "credit");
            const totalCuttktoday = sum(todayaddcut.filter(t => t.type == "admin_cut"), "debit");
            const todaydp = sum(await Deposit.where("status", "=", Deposit.status.success).where("accespt_date", "like", `%${today}%`), "taka");
            const todaywd = sum(await Widthdrow.where("status", "=", Widthdrow.status.success).where("accespt_date", "like", `%${today}%`), "taka");
            send.totalClub = clubs.length;
            send.totalUser = users.length;
            send.todayDiposit = this.getTaka(totalAddtktoday + todaydp);
            send.todayWidthdraw = this.getTaka(totalCuttktoday + todaywd);
            send.totalUserbalance = this.getTaka(sum(users, "taka"));
            send.totalClubbalance = this.getTaka(sum(clubs, "taka"));
            // betting
            const todaybet = await Betting.where("betting_time", "like", `%${today}%`);
            const pendingdata = await Betting.where("status", "pending");
            const toWin = sum(todaybet.filter(it => it.status == "win"), "return_taka");
            const toloss = sum(todaybet.filter(it => it.status == "loss"), "taka");
            send.betPending = this.getTaka(sum(pendingdata, 'taka'));
            send.betRetrun = this.getTaka(sum(pendingdata, 'return_taka'));
            send.toloss = this.getTaka(toloss);
            send.toWin = this.getTaka(toWin);


            return res.success("success", send);
        } catch (error) {
            return next(error.toString());
        }
    }
    transections = async (req, res, next) => {
        try {
            const transectionList = await Transection.my(req.user);
            const send = transectionList.map((item) => {
                return {
                    Date: item.date + " " + item.time, Type: item.message, Debits: item.debit, Credits: item.credit, Taka: item.total
                }
            })
            return res.success("transection data", send);
        } catch (error) {
            return next(error.toString());
        }
    }

    deposit = (req, res, next) => {
        try {
        } catch (error) {
            return next(error.toString());
        }
    }
    bet = async (req, res, next) => {
        try {
            const user = req.user;
            let query = this.database.table("bets");
            if (user.role == "user") {
                query = query.where("bets.user_id", user.id);
            }
            query.join("users", "bets.user_id", "users.id")
                .leftJoin("admins", "bets.resulder_id", "admins.id")
                .limit(300)
                .orderBy("bets.id", "desc")
                .select([
                    "bets.*",
                    "users.name as user_name",
                    "admins.name as resulder_name"
                ])
            return res.success("betting", await query);
        } catch (error) {
            return next(error.toString());
        }
    }
    daily = async (req, res, next) => {
        try {
            const { text } = req.query;
            const head = ["DATE", "DEPOSITE", "BONUS", "BET", "WIN", "LOSS", "PROFIT", "USER WIDTHDRAW", "CLUB WIDTHDRAW", "SPONSER COMMITON", "CLUB COMMITION", "TOTAL BONUS", "FINALY PROFITE"];
            const datas = await Transection.get().groupBy("date");
            const model = [];
            const sum = (array = [], feild) => array.filter((Boolean)).reduce((total, data) => total += parseFloat(data[feild]), 0)
            for (const item of datas) {

                const dailydata = await Transection.where("date", "=", item.date);

                // deposit
                const dailyDeposit = await Deposit.where("accespt_date", "LIKE", `%${item.date}%`)
                    .andWhere("status", Deposit.status.success);

                const totalDeposit = sum(dailyDeposit, 'taka');
                const totalBonus = sum(dailyDeposit, 'bonus');
                // widthraw
                const dailyWidthdaw = await Widthdrow.where("accespt_date", "LIKE", `%${item.date}%`).andWhere("status", Deposit.status.success);
                const totalUserWidthdaw = sum(dailyWidthdaw.filter(d => d.type = User.role.user), 'taka');
                const totalClubWidthdaw = sum(dailyWidthdaw.filter(d => d.type = User.role.club), 'taka');
                // commiton
                const sp_commiton = sum(dailydata.filter(it => it.type = this.transectionType.responsercomming), 'credit');
                const club_commiton = sum(dailydata.filter(it => it.type = this.transectionType.club_commintion), 'credit');


                const betHistroy = await Betting.where("betting_time", "like", `%${item.date}%`);

                const totalBet = sum(betHistroy, 'taka')
                const totalWin = sum(betHistroy.filter(item => item.status == "win"), 'taka');
                const totalLoss = sum(betHistroy.filter(item => item.status == "loss"), 'taka');

                const totalProfite = totalLoss - totalWin;
                const AlltotalBonus = totalBonus + sp_commiton + club_commiton;
                const finalyProfite = totalProfite - AlltotalBonus;
                model.push([
                    item.date,
                    this.getTaka(totalDeposit),
                    this.getTaka(totalBonus),
                    this.getTaka(totalBet),
                    this.getTaka(totalWin),
                    this.getTaka(totalLoss),
                    this.getTaka(totalProfite).replace("-", "loss "),
                    this.getTaka(totalUserWidthdaw),
                    this.getTaka(totalClubWidthdaw),
                    this.getTaka(sp_commiton),
                    this.getTaka(club_commiton),
                    this.getTaka(AlltotalBonus),
                    this.getTaka(finalyProfite).replace("-", "loss ")
                ])
            }
            const data = model.filter(itme => itme[0].includes(text || ""));
            return res.success("success", { head, data });
        } catch (error) {
            return next(error);
        }
    }
    transfer = async (req, res, next) => {
        try {
            const transectionList = req.user.role == User.role.user ?
                await Transfer.my(req.user) :
                await Transfer.get().orderBy("id", "desc");

            const send = [];
            for (const item of transectionList) {
                const reciver = await User.where("id", item.reciver).first();
                const sender = await User.where("id", item.sender).first();
                if (reciver && reciver) {
                    send.push({
                        Date: item.datetime,
                        Sender: sender.name,
                        Receiver: reciver.name,
                        Amount: this.getTaka(item.taka),
                        Status: "Completed"
                    })
                }
            }
            return res.success("Transfer data", send);
        } catch (error) {
            return next(error.toString());
        }
    }
    addcut = async (req, res, next) => {
        try {
            const datas = await Transection
                .where("type", "admin_add")
                .orWhere("type", "admin_cut")
                .orderBy("id","desc")
                .join("users", "transection.user_id", "users.id")
                .select(
                    "transection.*",
                    "users.name",
                );
            const sendata = datas.map(data => {
                return {
                    name: data.name,
                    date: data.date +" "+data.time,
                    taka: data.type === "admin_add" ? data.credit : data.debit,
                    type: data.type === "admin_add" ? "Add" : "Cut"
                }
            })

            return res.success("Transfer data", sendata);
        } catch (error) {
            return next(error.toString());
        }
    }
    clubmembar = async (req, res, next) => {
        try {
            const holder = req.user;
            const membar = await User
                .where("club_by_id", holder.id)
                .andWhere("role", "user");
            const data = await Promise.all(
                membar.map(async user => {
                    const dp = (await Deposit.where("user_id", user.id).andWhere("status", "success")).reduce((total, data) => total += parseFloat(data.taka), 0)
                    const wd = (await Widthdrow.where("user_id", user.id).andWhere("status", "success")).reduce((total, data) => total += parseFloat(data.taka), 0)
                    return {
                        ...user,
                        taka: this.getTaka(user.taka),
                        deposit: this.getTaka(dp),
                        widthdrow: this.getTaka(wd),
                    }
                })
            )
            return res.success("Transfer data", data);
        } catch (error) {
            return next(error.toString());
        }
    }
};

