const router = require("express").Router();
const { query } = require("../database/dbpromise.js");
const randomstring = require("randomstring");
const bcrypt = require("bcrypt");
const {
  isValidEmail,
  getFileExtension,
  makeRequest,
  readJsonFromFile,
} = require("../functions/function.js");
const { sign } = require("jsonwebtoken");
const validateUser = require("../middlewares/user.js");
const { checkPlan } = require("../middlewares/plan.js");

function hasPropertyWithValue(arr, property, value) {
  return arr.some((item) => item[property] === value);
}

router.post("/add_chatbot", validateUser, checkPlan, async (req, res) => {
  try {
    const { title, chats, flow, for_all, origin: originRaw = {} } = req.body;

    const origin = {
      title: "Meta",
      code: "META",
      data: {},
      ...originRaw,
    };

    if (req.plan?.allow_chatbot < 1) {
      return res.json({
        success: false,
        msg: "Your plan does not allow you to set a chatbot",
      });
    }

    if (!origin?.code) {
      return res.json({ msg: "Please select a chatbot Origin" });
    }

    if (!title || chats.length < 1 || !flow) {
      return res.json({
        success: false,
        msg: "Please provide the all fields! title, chats, flow are required",
      });
    }

    // checking for qr chatbot if they used a flow which contain interactive buttons
    if (origin?.code !== "META") {
      const flowPath = `${__dirname}/../flow-json/nodes/${req.decode.uid}/${flow?.flow_id}.json`;
      const nodeData = readJsonFromFile(flowPath);
      const checkBtn = hasPropertyWithValue(nodeData, "type", "BUTTON");
      const checkList = hasPropertyWithValue(nodeData, "type", "LIST");
      if (checkBtn || checkList) {
        return res.json({
          msg: "Please select another flow which does not contain interactive buttons",
        });
      }
    }

    await query(
      `INSERT INTO chatbot (uid, title, for_all, chats, flow, flow_id, active, origin) VALUES (?,?,?,?,?,?,?,?)`,
      [
        req.decode.uid,
        title,
        for_all ? 1 : 0,
        JSON.stringify(chats),
        JSON.stringify(flow),
        flow?.id,
        1,
        JSON.stringify(origin),
      ],
    );

    res.json({ success: true, msg: "Chatbot was added" });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went wrong", err });
  }
});

// update chatbot
router.post("/update_chatbot", validateUser, checkPlan, async (req, res) => {
  try {
    const {
      title,
      chats,
      flow,
      for_all,
      id,
      origin: originRaw = {},
    } = req.body;

    const origin = {
      title: "Meta",
      code: "META",
      data: {},
      ...originRaw,
    };

    if (req.plan?.allow_chatbot < 1) {
      return res.json({
        success: false,
        msg: "Your plan does not allow you to set a chatbot",
      });
    }

    if (!title || chats.length < 1 || !flow) {
      return res.json({
        success: false,
        msg: "Please provide the all fields! title, chats, flow are required",
      });
    }

    if (!origin?.code) {
      return res.json({ msg: "Please select a chatbot Origin" });
    }

    // checking for qr chatbot if they used a flow which contain interactive buttons
    if (origin?.code !== "META") {
      const flowPath = `${__dirname}/../flow-json/nodes/${req.decode.uid}/${flow?.flow_id}.json`;
      const nodeData = readJsonFromFile(flowPath);
      const checkBtn = hasPropertyWithValue(nodeData, "type", "BUTTON");
      const checkList = hasPropertyWithValue(nodeData, "type", "LIST");
      if (checkBtn || checkList) {
        return res.json({
          msg: "Please select another flow which does not contain interactive buttons",
        });
      }
    }

    await query(
      `UPDATE chatbot SET title = ?, for_all = ?, chats = ?, flow = ?, flow_id = ?, origin = ? WHERE id = ?`,
      [
        title,
        for_all ? 1 : 0,
        JSON.stringify(chats),
        JSON.stringify(flow),
        flow?.id,
        JSON.stringify(origin),
        id,
      ],
    );

    res.json({ success: true, msg: "Chatbot was updated" });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went wrong", err });
  }
});

// get my chatbots
router.get("/get_chatbot", validateUser, async (req, res) => {
  try {
    const data = await query(`SELECT * FROM chatbot WHERE uid = ?`, [
      req.decode.uid,
    ]);
    res.json({ data, success: true });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went wrong", err });
  }
});

// change bot status
router.post("/change_bot_status", validateUser, checkPlan, async (req, res) => {
  try {
    const { id, status } = req.body;

    if (req.plan?.allow_chatbot < 1) {
      return res.json({
        success: false,
        msg: "Your plan does not allow you to set a chatbot",
      });
    }

    await query(`UPDATE chatbot SET active = ? WHERE uid = ? AND id = ?`, [
      status ? 1 : 0,
      req.decode.uid,
      id,
    ]);

    res.json({ success: true, msg: "Chatbot was updated" });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went wrong", err });
  }
});

// del chatbot
router.post("/del_chatbot", validateUser, async (req, res) => {
  try {
    const { id } = req.body;
    await query(`DELETE FROM chatbot WHERE id = ? AND uid = ?`, [
      id,
      req.decode.uid,
    ]);
    res.json({ success: true, msg: "Chatbot was deleted" });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went wrong", err });
  }
});

// try to make a request
router.post("/make_request_api", validateUser, checkPlan, async (req, res) => {
  try {
    const { url, body, headers, type } = req.body;

    if (!url || !type) {
      return res.json({ msg: "Url is required" });
    }

    const resp = await makeRequest({
      method: type,
      url,
      body,
      headers,
    });

    res.json(resp);
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went wrong", err });
  }
});

router.post("/add_beta_chatbot", validateUser, checkPlan, async (req, res) => {
  try {
    const { title, origin, flow } = req.body;
    if (!title || !origin || !flow?.id) {
      return res.json({ msg: "Please fill all required fields" });
    }

    if (req.plan?.allow_chatbot < 1) {
      return res.json({
        success: false,
        msg: "Your plan does not allow you to set a chatbot",
      });
    }

    const { flow_id } = flow;
    const [getFlow] = await query(
      `SELECT * FROM beta_flows WHERE flow_id = ? AND uid = ?`,
      [flow_id, req.decode.uid],
    );
    if (!getFlow) {
      return res.json({ msg: "This flow is not existed" });
    }

    const flowNodesEdges = getFlow?.data ? JSON.parse(getFlow.data) : null;

    if (!flowNodesEdges || flowNodesEdges?.nodes?.length < 2) {
      return res.json({
        msg: "This flow does not have enough nodes to start, Please complete the flow",
      });
    }

    const { nodes, edges } = flowNodesEdges;

    // Check for buttons and lists only for non-META origins
    if (origin?.code !== "META") {
      const hasButtons = nodes.some(
        (node) =>
          node.data?.type?.type === "button" ||
          (node.data?.content?.type === "interactive" &&
            node.data?.content?.interactive?.type === "button"),
      );

      const hasLists = nodes.some(
        (node) =>
          node.data?.type?.type === "list" ||
          (node.data?.content?.type === "interactive" &&
            node.data?.content?.interactive?.type === "list"),
      );

      if (hasButtons || hasLists) {
        return res.json({
          success: false,
          msg: `Interactive buttons and lists are not supported for ${
            origin.code === "TELEGRAM" ? "Telegram" : "QR"
          } origin. Please select a flow without buttons or lists, or use META origin.`,
        });
      }
    }

    const origins = ["QR", "META", "WEBHOOK_AUTOMATION", "TELEGRAM"];
    if (!origins.includes(origin.code)) {
      return res.json({
        msg: `Selected Origin not found`,
      });
    }

    const getAllChatbots = await query(
      `SELECT * FROM beta_chatbot WHERE uid = ?`,
      [req.decode.uid],
    );

    // Assuming the chatbot data is stored as JSON in the database
    const chatbots = getAllChatbots?.map((x) => JSON.parse(x.origin)) || [];

    // Check if META chatbot already exists
    if (origin?.code === "META" && chatbots.find((x) => x.code === "META")) {
      return res.json({
        msg: `A ${
          origin?.code === "WEBHOOK_AUTOMATION"
            ? "webhook automation"
            : "chatbot"
        } is already running for META, Please delete that to add new`,
      });
    }

    // Check if chatbot with same origin title already exists
    if (
      chatbots.find((x) => x.title === origin?.title && x.code === origin?.code)
    ) {
      return res.json({
        msg: `A ${
          origin?.code === "WEBHOOK_AUTOMATION"
            ? "webhook automation"
            : "chatbot"
        } with this origin already exists for this device`,
      });
    }

    if (origin.code === "QR" && !origin.data?.uniqueId) {
      return res.json({ msg: "No active account found using this origin" });
    }

    if (origin.code === "TELEGRAM" && !origin.data?.id) {
      return res.json({
        msg: "No active Telegram session found using this origin",
      });
    }

    // Determine origin_id based on origin code
    let origin_id;
    if (origin.code === "META") {
      origin_id = "META";
    } else if (origin.code === "TELEGRAM") {
      origin_id = origin.data?.session_id || origin.data?.id;
    } else if (origin.code === "QR") {
      origin_id = origin.data?.uniqueId;
    } else {
      origin_id = null;
    }

    await query(
      `INSERT INTO beta_chatbot (uid, source, title, flow_id, origin, origin_id) VALUES (?,?,?,?,?,?)`,
      [
        req.decode.uid,
        origin?.code === "WEBHOOK_AUTOMATION"
          ? "webhook_automation"
          : "wa_chatbot",
        title,
        flow_id,
        JSON.stringify(origin),
        origin_id,
      ],
    );

    res.json({ success: true, msg: "Chatbot was added successfully" });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went wrong", err });
  }
});

// get all chatbots beta
router.get("/get_beta_chatbots", validateUser, async (req, res) => {
  try {
    const { type } = req.query;
    const data = await query(
      `SELECT * FROM beta_chatbot WHERE uid = ? AND source = ?`,
      [req.decode.uid, type],
    );
    res.json({ data, success: true });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went wrong", err });
  }
});

// change bot status
router.post("/change_beta_bot_status", validateUser, async (req, res) => {
  try {
    const { id, status } = req.body;
    await query(`UPDATE beta_chatbot SET active = ? WHERE uid = ? AND id = ?`, [
      status ? 1 : 0,
      req.decode.uid,
      id,
    ]);
    res.json({ msg: "Satus changed", success: true });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went wrong", err });
  }
});

// del beta chatbot
router.post("/del_beta_chatbot", validateUser, async (req, res) => {
  try {
    const { id } = req.body;
    await query(`DELETE FROM beta_chatbot WHERE id = ? AND uid = ?`, [
      id,
      req.decode.uid,
    ]);
    res.json({ msg: "Chatbot was deleted", success: true });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: "Something went wrong", err });
  }
});

module.exports = router;
