const Model = require("../model/adminModel");
const axios = require("axios");
const { body, validationResult } = require("express-validator");
const bcrypt = require("bcrypt");
const adminModel = new Model();
const FormData = require("form-data");
const fs = require("fs/promises");

// View start
function makeid(length) {
  var result = '';
  var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  var charactersLength = characters.length;
  for (var i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}

exports.validateInput = (method) => {
  switch (method) {
    case "login":
      return [
        body('email', 'Email is Required').not().isEmpty().isEmail(),
        body('password', 'Password should be minimum 8 characters').isLength({ min: 8 }),
      ]

    case "add":
      return [
        body('website', 'Website is Required').not().isEmpty(),
        body('username', 'Username is Required').not().isEmpty(),
        body('password', 'Password is Required').not().isEmpty(),
      ]

    case "edit":
      return [
        body('website', 'Website is Required').not().isEmpty(),
        body('username', 'Username is Required').not().isEmpty(),
        body('password', 'Password is Required').not().isEmpty(),
      ]

  }
}

exports.validateAdmin = (req, res) => {
  if (!req.session.admin_logged_in || req.session.admin_id == 0)
    return res.redirect("/admin/login");
}

exports.login = (req, res) => {
  let data = {
    title: "Admin Login page",
    session: req.session,
    page_name: "Login",
  };

  // return console.log(req.session)
  if (req.session.admin_logged_in && req.session.admin_id != 0)
    return res.redirect("/admin/dashboard");
  else
    return res.render("admin/auth/login", data);
};

exports.dashboard = async (req, res) => {
  var [userDetails] = await adminModel.getUserDetails();
  var [orderDetails] = await adminModel.getOrderDetails();
  var [currentOrders] = await adminModel.getCurrentOrderDetails();

  let data = {
    userDetails,
    orderDetails,
    currentOrders,
    title: "Admin dashboard page",
    session: req.session,
    page_name: "Dashboard",
    url: "dashboard",
  };


  console.log(data)

  return res.render("admin/index", data);
};

exports.forgotpassword = (req, res) => {
  let data = {
    title: "Admin Forgot Password page",
    session: req.session,
    page_name: "Login",
  };
  return res.render("admin/auth/forgot-password", data);
};

exports.logout = (req, res) => {
  req.session.destroy();
  return res.redirect("login");
}

exports.addProduct = async (req, res) => {
  let table = "all_products"
  let [categories] = await adminModel.getCategories(table);
  let data = {
    title: "Admin Add Product page",
    session: req.session,
    page_name: "add Product",
    categories
  };
  return res.render("admin/product/add_product", data);
};

exports.allProducts = async (req, res) => {
  var table = "all_products";
  var product_per_page = 10; // Product per page
  var requested_page = parseInt(req.query.page) || 1; //req.query.page;
  var starting_page = (requested_page - 1) * product_per_page; //Starting Page
  var [products] = await adminModel.getData(
    table,
    starting_page,
    product_per_page
  );
  var [countProducts] = await adminModel.getAllRowCount(table);

  let data = {
    products,
    title: "Admin All Product page",
    session: req.session,
    page_name: "All Products",
    total_page_count: Math.round(countProducts.length / product_per_page) || 1,
    current_page: requested_page,
    previous_page: requested_page == 1 ? 1 : requested_page - 1,
    next_page: requested_page + 1,
  };
  // console.log(data);
  return res.render("admin/product/products", data);
};

exports.allOrders = async (req, res) => {
  var where = '';

  if (Object.keys(req.query).length !== 0) {
    for (const index in Object.entries(req.query)) {
      if (index == 0) {
        where += `WHERE `;
      }
      if (Object.entries(req.query)[index][0] == 'date') {
        let date = Object.entries(req.query)[index][1].split('/')
        if (date.length == 1) {
          where += `date(created_at) = '${date[0]}' `;
        } else if (date.length == 2) {
          where += `(date(created_at) BETWEEN '${date[0]}' AND '${date[1]}') `;
        }
      } else
        where += `${Object.entries(req.query)[index][0]} = '${Object.entries(req.query)[index][1]}' `;
      if (index != Object.keys(req.query).length - 1) {
        where += `AND `
      }
    }
  }
  var table = "orders";
  var orders_per_page = 10; // Product per page
  var requested_page = parseInt(req.query.page) || 1; //req.query.page;
  var starting_page = (requested_page - 1) * orders_per_page; //Starting Page
  var [orders] = await adminModel.getData(
    table,
    starting_page,
    orders_per_page,
    where
  );
  var countOrders = await adminModel.getAllRowCount(table);

  let data = {
    orders,
    title: "Admin All Orders page",
    session: req.session,
    page_name: "All Orders",
    total_page_count: Math.round(countOrders / orders_per_page) || 1,
    current_page: requested_page,
    previous_page: requested_page == 1 ? 1 : requested_page - 1,
    next_page: requested_page + 1,
    where: req.query.user_id,
  };
  return res.render("admin/orders/orders", data);
};

exports.allUsers = async (req, res) => {
  var table = "users";
  var users_per_page = 10; // Product per page
  var requested_page = parseInt(req.query.page) || 1; //req.query.page;
  var starting_page = (requested_page - 1) * users_per_page; //Starting Page
  var [users] = await adminModel.getData(table, starting_page, users_per_page);
  var countUsers = await adminModel.getAllRowCount(table);

  let data = {
    users,
    title: "Admin All Users page",
    session: req.session,
    page_name: "All Users",
    total_page_count: Math.round(countUsers / users_per_page) || 1,
    current_page: requested_page,
    previous_page: requested_page == 1 ? 1 : requested_page - 1,
    next_page: requested_page + 1,
  };
  console.log(data);
  return res.render("admin/users/users", data);
};

exports.allCategory = async (req, res) => {
  var table = "category";
  var orders_per_page = 10; // Product per page
  var requested_page = parseInt(req.query.page) || 1; //req.query.page;
  var starting_page = (requested_page - 1) * orders_per_page; //Starting Page
  var [orders] = await adminModel.getData(
    table,
    starting_page,
    orders_per_page,
    where
  );
  var countOrders = await adminModel.getAllRowCount(table);

  let data = {
    orders,
    title: "Admin All Orders page",
    session: req.session,
    page_name: "All Orders",
    total_page_count: Math.round(countOrders / orders_per_page) || 1,
    current_page: requested_page,
    previous_page: requested_page == 1 ? 1 : requested_page - 1,
    next_page: requested_page + 1,
    where: req.query.user_id,
  };
  // console.log(data);
  return res.render("admin/orders/orders", data);
};

// View Ends

// POST CONTROLLERS

exports.insertProduct = async (req, res, next) => {

  // return console.log([req.files["thumbnail"],req.files["multi_img[]"]]);

  if (req.files["thumbnail"] == undefined || req.files["multi_img[]"] == undefined) {
    return res.status(403).json({ message: "Fields are empty!!" });
  }

  var img = req.files["thumbnail"][0];
  var thumbnailUrl = "";

  const data = await fs.readFile(img.path)

  const formdata = new FormData();
  formdata.append("file", data, img.originalname);

  const imageUpload = await axios
    .post("https://dcloud.co.in/upload", formdata, {
      headers: {
        "X-Key": "Tv7fioEG2Z5lwWf0IUq9VLcj2",
        "X-Secret": "6o2ZfCsdN105wFlnqAcwmpafN",
      }
    })

  if (!imageUpload.data.status) {

  }

  thumbnailUrl = imageUpload.data.result.file_url

  var multiUrl = [];
  var img2 = req.files["multi_img[]"];

  await Promise.all(img2.map(async (element) => {

    let data = await fs.readFile(element.path)

    const formdata = new FormData();
    formdata.append("file", data, element.originalname);

    let image = await axios
      .post("https://dcloud.co.in/upload", formdata, {
        headers: {
          "X-Key": "Tv7fioEG2Z5lwWf0IUq9VLcj2",
          "X-Secret": "6o2ZfCsdN105wFlnqAcwmpafN",
        },
      })

    if (!image.data.status) {

    }
    multiUrl.push(image.data.result.file_url);
  }));

  var insertData = {
    title: req.body.title,
    p_code: makeid(6),
    description: req.body.description,
    is_featured: req.body.is_featured == "on" ? 1 : 0,
    on_sale: req.body.on_sale == "on" ? 1 : 0,
    display_price: req.body.display_price,
    selling_price: req.body.selling_price,
    gst: req.body.gst,
    discount: req.body.discount,
    shipping_charges: req.body.shipping_charges,
    total_qty: req.body.total_qty,
    category: req.body.category,
    thumbnail: thumbnailUrl,
    multi_img: multiUrl,
  }

  try {
    const [response] = await adminModel.insertProduct(insertData);
    if (response.affectedRows === 1) {
      return res.status(200).json({ message: "Product Added Successfully" });
    }

  } catch (error) {
    return res.status(403)
      .json({ message: "Something went wrong, Try again later!!" });
  }
};

exports.updateProductStatus = (req, res) => {
  try {
    var id = req.body.id;
    var status = req.body.status;
    var column = req.body.column;

    const response = adminModel.updateProductStatus(id, column, status);
    if (response != 0)
      return res.status(200).json({
        type: "success",
        status: "success",
        message: "Product Updated Successfully",
      });
    else
      return res.status(403).json({
        type: "success",
        status: "error",
        message: "Something went Wrong!!",
      });
  } catch (error) {
    return res
      .status(403)
      .json({ message: "Something went wrong, Try again later!!" });
  }
};

exports.updateStatus = (req, res) => {
  try {
    var id = req.body.id;
    var status = req.body.status;
    var column = req.body.column;
    var table = req.body.table;

    const response = adminModel.updateStatus(id, column, status, table);
    if (response != 0)
      return res.status(200).json({
        type: "success",
        status: "success",
        message: "Status Updated Successfully",
      });
    else
      return res.status(403).json({
        type: "success",
        status: "error",
        message: "Something went Wrong!!",
      });
  } catch (error) {
    return res
      .status(403)
      .json({ message: "Something went wrong, Try again later!!" });
  }
};

exports.validate_login = (req, res) => {
  const errors = validationResult(req);

  if (!errors.isEmpty()) return res.json({ error: errors.errors });

  const { email, password } = req.body;
  adminModel
    .validateLogin(email)
    .then(async ([row]) => {

      if (row.length == 0) {
        return res.json({ 'type': 'error', 'message': "Admin not found" });
      }

      const validPassword = await bcrypt.compare(password, row[0].password);
      if (!validPassword) {
        return res.json({ 'type': 'error', 'message': "Incorrect Password" });
      }

      req.session.admin_logged_in = true;
      req.session.admin_id = row[0].id;
      req.session.save();
      return res.json({ 'type': 'success', 'message': "Successfully Logged in..." });
    })
    .catch((err) => {
      console.log(err);
    });
};
