var express = require("express");
var router = express.Router({ mergeParams: true });
var Category = require("../models/category");
var Product = require("../models/product");
var Sub_item = require("../models/sub_item");
var User = require("../models/user");
let file_manager = require("../tools/file_managment");
let { storageFun } = require("../tools/multer");
const sendEmail = require("../tools/sendEmail");

let upload = storageFun(__dirname + '/../public/images/products');


User.findOne({ email: "admin" }, function (err, admin) {
    if (!admin) {
        var newUser = new User({ username: "admin", email: "admin", role: "admin" });
        User.register(newUser, process.env.ADMIN_PASSWORD, function (err, user) {
            if (err) { console.log(err); return false; }
            else {
                return true;
            }
        });
    }
});

router.get("/admin", isAdminLoggedIn, function (req, res) {
    Category.find({}, function (err, cats) {
        if (err) { console.log(err); return res.json({ message: "fail" }) }
        Sub_item.find({}, function (err, subCats) {
            if (err) { console.log(err); return res.json({ message: "fail" }) }
            Product.find({}).populate('Sub_item').exec(function (err, products) {
                if (err) { console.log(err); return res.json({ message: "fail" }) }
                res.render("admin/admin", { cats, products, subCats });
            });
        })

    })
})



/******** category routes */
router.get("/new/category", isAdminLoggedIn, function (req, res) {
    res.render("admin/new_category");
});

router.put("/edit/category/:cat_id", isAdminLoggedIn, function (req, res) {
    Category.findOneAndUpdate({ _id: req.params.cat_id }, { name: req.body.name }, function (err, cat) {
        if (err) { console.log(err); return res.json({ message: "fail" }) }
        res.json({ message: "success", cat })
    });
});

//delete category
router.delete("/delete/category/:cat_id", isAdminLoggedIn, function (req, res) {
    return res.status(403).json({
        message: "deleting category has been removed for the moment, please delete sub category instead"
    });
    Category.findOneAndDelete({ _id: req.params.cat_id }, function (err, cat) {
        if (err) { console.log(err); return res.json({ message: "fail" }); }
        Sub_item.deleteMany({ _id: { $in: cat.Sub_items } }, function (err) {
            if (err) { console.log(err); return res.json({ message: "fail" }); }
            res.json({ message: "success" });
        })
    })
});


/******** sub_category routes */
router.get("/sub_categories/:cat_id", isAdminLoggedIn, function (req, res) {
    var cat_id = req.params.cat_id;
    Category.findOne({ _id: cat_id }).populate("Sub_items").exec(function (err, category) {
        if (err) { console.log(err); return res.json({ message: "fail" }) }
        res.render("admin/sub_categories", { category });
    });
});

//add new sub category
router.post("/new/sub_category", isAdminLoggedIn, function (req, res) {
    console.log(req.body, req.query);
    var cat_id = req.query.cat_id;
    Sub_item.findOne({ name: req.body.sub_name }, function (err, found) {
        if (err) { console.log(err); return res.redirect("/admin") }
        Category.findOne({ _id: cat_id, Sub_items: found }, function (err, cat_by_sub) {
            if (err || cat_by_sub) { console.log(err); return res.send("<h2 style='text-align:center;'>error or the category already exists somewhere else!</h2>") }
            Sub_item.create({ name: req.body.sub_name }, function (err, subItem) {
                if (err) { console.log(err); return res.json({ message: "fail" }) }
                Category.findOne({ _id: cat_id }, function (err, cat) {
                    if (err || !cat) { console.log(err); return res.json({ message: "fail", desc: "err or category not found" }) }
                    cat.Sub_items.push(subItem);
                    cat.save(function () {
                        console.log(subItem);
                        res.redirect("/sub_categories/" + cat._id);
                    });
                })
            })
        })
    });
});

//edit sub category
router.put("/edit/sub_category/:sub_id", isAdminLoggedIn, function (req, res) {
    Sub_item.findOneAndUpdate({ _id: req.params.sub_id }, { name: req.body.name }, function (err, sub) {
        if (err) { console.log(err); return res.json({ message: "fail" }) }
        res.json({ message: "success", sub })
    });
});

//delete sub cat
router.delete("/delete/sub_category/:sub_id", isAdminLoggedIn, function (req, res) {
    Sub_item.deleteOne({ _id: req.params.sub_id }, function (err) {
        if (err) { console.log(err); return res.json({ message: "fail" }); }
        //delete related products
        Product.find({ Sub_item: req.params.sub_id }, async function (err, products) {
            if (err) return res.status(500).json({ message: "err interne" });
            for (let index = 0; index < products.length; index++) {
                const product = products[index];
                await product.remove();
                for (var i = 0; i < product.images.length; i++) {
                    try {
                        const path = product.images[i]?.original_path;
                        await file_manager.deleteFile(product.images[i].public_id, path);
                    } catch (err) { console.error(err); }
                }
            }
        });
        return res.json({ message: "success" });
    });
});


/**** Products routes */
//get new
router.get("/new/:sub_cat/product", isAdminLoggedIn, function (req, res) {
    Sub_item.findOne({ _id: req.params.sub_cat }, function (err, subItem) {
        Sub_item.find({}, function (err, allSubs) {
            if (err) { console.log(err); return res.json({ message: "fail" }) }
            res.render("admin/new_product", { subItem, allSubs });
        })
    });
});


//delete product
router.delete("/delete/product/:product_id", isAdminLoggedIn, function (req, res) {
    Product.findOneAndDelete({ _id: req.params.product_id }, async function (err, product) {
        if (err) { console.log(err); return res.json({ message: "fail" }); }
        try {
            for (var i = 0; i < product.images.length; i++) {
                path = __dirname + '/../public' + product.images[i];
                await file_manager.deleteFile(product.images[i].public_id, path);
            }
        } catch (err) {
            console.error(err)
        }
        res.json({ message: "success" });
    });
});


//get product to Edit by id
//!add is adminLoggedIn
router.get("/admin/product/details/:id", function (req, res) {
    Product.findOne({ _id: req.params.id }, function (err, product) {
        if (err) { console.log(err); return res.json({ message: "fail" }); }
        Sub_item.find({}, function (err, allSubs) {
            if (err) { console.log(err); return res.json({ message: "fail" }) }
            if (req.query.json == "true") return res.status(200).json({ product });
            res.render("admin/edit_product", { product, allSubs })
        })
    });
})


//edit product
router.post("/edit_product", upload.array('productImages', 10), function (req, res) {
    var productName = req.body.productName;
    var subItem_id = req.body.subItem_id;
    var productDesc = req.body.productDesc;
    var description_blocks = req.body.description_blocks;
    var price = req.body.price;
    var in_stock = req.body.inStock == "on" ? true : false;
    var TTC = price * 1.2;

    var images_to_remove = [];
    if (req.body.remove_imgs?.length > 0)
        images_to_remove = JSON.parse(req.body.remove_imgs);

    Sub_item.findOne({ _id: subItem_id }, function (err, sub_item) {
        if (err || !sub_item) {
            console.log(err);
            return res.json({ message: "fail" });
        }
        //if category field is added in product find it by subitem and add it here
        Product.findOneAndUpdate({ _id: req.query.p_id }, { name: productName, Sub_item: sub_item, description: productDesc, price, in_stock, TTC, description_blocks }, async function (err, product) {
            if (err) { console.log(err); return res.json({ message: "fail" }); }
            if (req.files.length) {
                var start = 0
                var result = images_to_remove.find(img_to_rm => {
                    return img_to_rm.original_filename == product.images[0]?.original_filename
                });
                if (result) {
                    const response = await file_manager.createFile(req.files[0].path, 'products');
                    response.original_path = req.files[0].path;
                    product.images.unshift(response);
                    start = 1;
                }
                var rIdex;
                for (var i = 0; i < images_to_remove.length; i++) {
                    const rIdex = product.images.findIndex(productImage => {
                        return productImage.public_id === images_to_remove[i].public_id;
                    });
                    product.images.splice(rIdex, 1);
                }
                //uploading secondary images
                for (var i = start; i < req.files.length; i++) {
                    const response = await file_manager.createFile(req.files[i].path, 'products');
                    response.original_path = req.files[i].path;
                    product.images.push(response);
                }
            }
            else {
                var rIdex;
                for (var i = 0; i < images_to_remove.length; i++) {
                    const rIdex = product.images.findIndex(productImage => {
                        return productImage.public_id === images_to_remove[i].public_id;
                    });
                    product.images.splice(rIdex, 1);
                }
            }
            //removing deleted images
            try {
                for (var i = 0; i < images_to_remove.length; i++) {
                    let path = images_to_remove[i].original_path;
                    await file_manager.deleteFile(images_to_remove[i].public_id, path);
                }
            } catch (err) { console.error(err); }


            //emailing promissed customers
            if (!product.in_stock && in_stock && product.emails_availability.length) {
                var emails = product.emails_availability;
                var mailOptions = {
                    from: 'FutureTech',
                    subject: 'A product you followed is back in stock',
                    html: "Dear Customer," + "<br> Feel free to check the product you were intersted in, as it is available now, Product: <a href='http://" + req.headers.host + "/product/details/" + product._id + "'>" + product.name + "</a>."
                };
                //sending emails
                //TODO: search if possible to send emails to all addresses at once
                for (var i = 0; i < emails.length; i++) {
                    mailOptions.to = emails[i];
                    sendEmail(mailOptions);
                }
                product.emails_availability = [];
                product.save(function () {
                    return res.redirect("/category/" + subItem_id + "/products?admin=true");
                });
            }
            else {
                product.save(function () {
                    return res.redirect("/category/" + subItem_id + "/products?admin=true");
                })
            }

        });

    });
})


function isAdminLoggedIn(req, res, next) {
    if (req.isAuthenticated()) {
        if (req.user.role == "admin")
            return next();
        else {
            res.redirect("/admin/login");
        }
    }
    else {
        res.redirect("/admin/login");
    }
}
module.exports = router;
