const { fakePassword } = require("../helpers/appHelper");
const User = require("../model/User");
const { loginByid } = require("../service/authService");
const Controller = require("./Controller");
const bcrypt = require("bcrypt");
module.exports = new class UserController extends Controller {

    usertoclub = async (req, res, next) => {
        try {
            const { id, commition, name } = req.body;
            if (!name || !id || !commition) return next("input data not found");
            await User.find(id);
            const check = await User.where("club_name", name.trim()).first();
            if (check) return next("Invalid name!");
            const payload = { club_name: name, role: User.role.club, club_comminion: commition, sp_comminion: '0' }
            await User.update(id, v => payload);
            return res.success("User to club convet successfull");
        } catch (error) {
            return next(error);
        }
    }
    getUser = async (req, res, next) => {
        try {
            const data = await User.where("role", User.role.user).orderBy("id", "desc");
            return res.success("success", data);
        } catch (error) {
            return next(error);
        }
    }
    getClubholder = async (req, res, next) => {
        try {
            const data = await User.where("role", User.role.club).orderBy("id", "desc");
            return res.success("success", data);
        } catch (error) {
            return next(error);
        }
    }
    block = async (req, res, next) => {
        try {
            const { id } = req.params;
            const checkUser = await User.find(id);
            // if (checkUser.is_block == "yes") return next("User already in trash");
            await User.update(id, v => ({ is_block: v.is_block == "yes" ? "no" : 'yes' }));
            return res.success("successfull");
        } catch (error) {
            return next(error.toString());
        }
    }
    trash = async (req, res, next) => {
        try {
            const { id } = req.params;
            const checkUser = await User.find(id);
            if (checkUser.is_block == "yes") return next("User already in trash");
            await User.update(id, v => ({ is_block: "yes" }));
            return res.success("trash successfull");
        } catch (error) {
            return next(error.toString());
        }
    }
    parmition = async (req, res, next) => {
        try {
            const allow = ['wd_permition', 'dp_permition', 'blt_permition']
            const { name } = req.body;
            const id = req.params.id;
            if (!allow.includes(name)) return next("Enter valid name");
            const setting = await this.setting();
            if (name == "wd_permition" && setting['wd_permition'] == "deactive") return next("parmition deactive");
            if (name == "dp_permition" && setting['dp_permition'] == "deactive") return next("parmition deactive");
            if (name == "blt_permition" && setting['transfar_permition'] == "0") return next("parmition deactive");
            await User.find(id);
            await User.update(id, v => ({ [name]: v[name] == "1" ? "0" : "1" }))
            return res.success("Parmition  successfull");
        } catch (error) {
            return next(error);
        }
    }
    commition = async (req, res, next) => {
        try {
            const allow = ['club_comminion', 'sp_comminion']
            const { commition, name } = req.body;
            const id = req.params.id;
            if (!Number(commition)) return next("Enter valid amount");
            if (!allow.includes(name)) return next("Enter valid name");
            await User.find(id);
            await User.update(id, v => {
                return { [name]: commition }
            })
            return res.success("commition add successfull");
        } catch (error) {
            return next(error);
        }
    }
    cuttaka = async (req, res, next) => {
        try {
            const id = req.params.id;
            await User.find(id);
            const { type, message, taka } = req.body;
            if (!id || !taka || !type || !message) return next("Input invalid");
            if (type == "cut") {
                await this.cutTakaFromUser(id, this.getTaka(taka), this.transectionType.admin_update.cut, message);
                return res.success("balance cut successfull");
            } else if (type == "add") {
                await this.addTakaToUser(id, this.getTaka(taka), this.transectionType.admin_update.add, message);
                return res.success("balance add successfull");
            }
        } catch (error) {
            return next(error.toString());
        }
    }
    transfer = async (req, res, next) => {
        try {
            const { taka, pass, mobail } = req.body;
            const user = req.user;
            const role = user.role;
            const chekpas = await bcrypt.compare(pass, user.pass);
            if (!chekpas) return next("invalid password");
            if (user.blt_permition != "1") return next("your parmiton off")
            if (role == User.role.user) {
                // user only her clubholder 
                const clubholder = await User.find(user.club_by_id);
                await this.cutTakaFromUser(user.id, taka, this.transectionType.transfer, `Transfer to ${clubholder.club_name}`);
                await this.addTakaToUser(clubholder.id, taka, this.transectionType.transfer, `by ${user.name}`);
                await this.bltransfer(user.id, clubholder.id, taka, this.getTaka(parseFloat(clubholder.taka + taka)))
                return res.success("Reciver your clubholder.thanks you");
            }
            if (role == User.role.club) {
                // club to her any user
                const reciver = await User.where("name", mobail).orWhere("mobail", mobail).first();
                if (!reciver || mobail == user.name) return next("Invalid name or mobail");

                await this.cutTakaFromUser(user.id, taka, this.transectionType.transfer, `Transfer to ${reciver.name}`);
                await this.addTakaToUser(reciver.id, taka, this.transectionType.transfer, `by ${user.club_name}`);
                await this.bltransfer(user.id, reciver.id, taka, this.getTaka(parseFloat(reciver.taka + taka)))
                return res.success("Recive your taka thanks you");
            }

        } catch (error) {
            return next(error.toString())
        }
    }
    add = async (req, res, next) => {

        try {
            let { name, mobile, club, sponser = null, password } = req.body;

            const clubRecord = await User.where("id", "=", club).andWhere("role", "=", User.role.club).first();
            if (!clubRecord) return next("Invalid clubholder");
            if (name === sponser) return next("invalid sponser name");
            // sponsor check (optional)
            const sp = await User.where("name", "=", sponser).first();
            const sid = sp?.id || 0;
            const checkname = await User.where("name", name).first();
            if (checkname) return next("username is allready exest!");
            const echkmobail = await User.where("mobail", mobile).first();
            if (echkmobail) return next("mobail is allready exest!");
            // create pass hash
            const hashedPassword = await bcrypt.hash(password, 10);
            // // insert user into database
            const payload = {
                name,
                mobail: mobile,
                club_by_id: clubRecord.id,
                sponcer_by_id: sid,
                pass: hashedPassword,
                role: User.role.user
            }
            await User.add(payload);
            return res.success("successfull");
        } catch (error) {
            return next(error.toString());
        }
    }
    clubs = async (req, res, next) => {
        try {
            const clubs = await User.club();
            const data = clubs.map((item) => ({ id: item.id, name: item.club_name }))
            return res.success("club data", data);
        } catch (error) {
            return next(error.toString());
        }
    }
    loginid = async (req, res, next) => {
        try {
            const id = req.params.id;
            const setting = await this.setting();
            const token = await loginByid(id);
            const payload = { url: setting.fontendURL, token };
            res.success("successfull login", payload);
        } catch (error) {
            return next(error.toString());
        }
    }
    // unbcomplate this code install history dayli sponser income XXXXXXX
    mysponser = async (req, res, next) => {
        try {
            const user = req.user;
            const sponserList = await User.where("sponcer_by_id", "=", user.id).orderBy("id", "desc");
            const list = sponserList.map((user) => ({
                id: user.id,
                income: "100",
                name: user.name
            }))
            return res.success("data", list);
        } catch (error) {
            return next(error.toString());
        }
    }
    passupdate = async (req, res, next) => {
        try {
            if (req.user.role === "admin") {
                const id = req.body.id;
                const newpass = fakePassword();
                const user = await User.find(id);
                const newpasshash = await bcrypt.hash(newpass, 10);
                await User.update(id, () => ({ pass: newpasshash }));
                return res.success("success", { name: user.name, pass: newpass });
            }
            if (req.user.role == "user") {
                const { oldp, newp } = req.body;
                const id = req.user.id;
                if (!id) return next("User id missing");
                if (!oldp || !newp) return next("Input value empty");
                if (oldp === newp) return next("Old and new password same");
                if (newp.length < 6) return next("New password minimum 6 character");
                const user = await User.find(id);
                const checkpassstatus = await bcrypt.compare(oldp, user.pass);
                if (!checkpassstatus) return next("invalid old password");
                const newpasshash = await bcrypt.hash(newp, 10);
                await User.update(id, () => ({ pass: newpasshash }));
                return res.success("Update success");
            }
        } catch (error) {
            return next(error.toString())
        }
    }
    clubchenge = async (req, res, next) => {
        try {
            const { id, pass } = req.body;
            if (!id || !pass) return next("data empty!");
            const user = req.user;
            const passstatus = await bcrypt.compare(pass, user.pass);
            if (!passstatus) return next("Invalid password");
            const haveclub = await User.where("id", "=", id).andWhere("role", "=", User.role.club);
            if (!haveclub) return next("Invalid club id");
            const newdata = await User.update(user.id, (old) => ({ club_by_id: id }));
            return res.success("Update success", newdata);
        } catch (error) {
            return next(error.toString())
        }
    }
    profile = async (req, res, next) => {
        try {
            const user = req.user;
            const sponser = await User.sponser(user);
            const clubholder = await User.clubholder(user);
            const setting = await this.setting();
            const send = {
                ...user,
                notice: setting?.notice,
                time: setting?.bettime,
                pass: "",
                taka: this.getTaka(user.taka),
                sponcer_by_id: sponser?.name,
                club_by_id: clubholder?.club_name,
            }
            return res.success("success", send);
        } catch (error) {
            return next(error.toString());
        }
    }
};