import { Request, Response } from "express";
import { getIO } from "../libs/socket";
import CreateQueueService from "../services/QueueService/CreateQueueService";
import DeleteQueueService from "../services/QueueService/DeleteQueueService";
import ListQueuesService from "../services/QueueService/ListQueuesService";
import ShowQueueService from "../services/QueueService/ShowQueueService";
import UpdateQueueService from "../services/QueueService/UpdateQueueService";
import Queue from "../models/Queue";
import AppError from "../errors/AppError";
import { del, get, set } from "../helpers/RedisClient";
import { Op } from "sequelize";
import ListWhatsAppsService from "../services/WhatsappService/ListWhatsAppsService";
import Whatsapp from "../models/Whatsapp";
import QuickAnswerQueue from "../models/QuickAnswerQueue";
import ContactQueue from "../models/ContactQueues";

export const index = async (req: Request, res: Response): Promise<Response> => {
  const queues = await ListQueuesService();

  return res.status(200).json(queues);
};

export const listQueues = async (
  req: Request,
  res: Response
): Promise<Response> => {
  const whatsapps = await Whatsapp.findAll({
    where: {
      name: { [Op.ne]: "botqueue" },
      number: { [Op.ne]: "" },
      phoneNumberId: false
    },
    attributes: ["number"],
    include: [
      {
        model: Queue,
        as: "queues",
        attributes: ["id", "name"]
      }
    ]
  });

  const whats = whatsapps
    ?.filter((w: any) => w?.queues?.length > 0)
    ?.map((w: any) => {
      const { number, queues } = w;
      return {
        number,
        queues: queues?.map((q: any) => {
          const { id, name } = q;
          return { id, name };
        })
      };
    });

  let _queues: any = [];

  for (const w of whats) {
    const { queues } = w;

    for (const q of queues) {
      const { id: queueId, name } = q;

      const auxQueue = _queues.findIndex((q: any) => q.queueId == queueId);

      if (auxQueue == -1) {
        _queues.push({ queueId, name });
      }
    }
  }

  return res.status(200).json(_queues);
};

export const store = async (req: Request, res: Response): Promise<Response> => {
  const { name, color, greetingMessage, farewellMessage, cc } = req.body;

  const queue = await CreateQueueService({
    name,
    color,
    greetingMessage,
    cc,
    farewellMessage
  });

  const io = getIO();
  io.emit("queue", {
    action: "update",
    queue
  });

  return res.status(200).json(queue);
};

export const customization = async (
  req: Request,
  res: Response
): Promise<Response> => {
  const { ura } = req.body;

  if (!ura) throw new AppError("BAD REQUEST", 400);

  let new_queues: any;

  if (ura.length > 0) {
    new_queues = ura
      .filter(
        (u: any) =>
          u.idmaster === ura[1].id &&
          u?.queueName &&
          u?.color &&
          u?.greetingMessage
      )
      .map((u: any) => {
        const { queueName, color, greetingMessage } = u;
        return {
          queueName: queueName?.trim()?.replace(/\s+/g, " "),
          color,
          greetingMessage
        };
      });

    if (new_queues && new_queues.length > 0) {
      const db_queues: any = await Queue.findAll();

      // for (const i in new_queues) {
      //   let { queueName: name, color, greetingMessage } = new_queues[i];

      //   name = name?.trim()?.replace(/\s+/g, " ");

      //   const update = db_queues.find(
      //     (q: any) => q.name?.trim()?.replace(/\s+/g, " ") == name
      //   );

      //   if (update) {
      //     const { id } = update;
      //     // UPDATE
      //     // const queue = await UpdateQueueService(id, {
      //     //   name,
      //     //   color,
      //     //   greetingMessage
      //     // });

      //     // const io = getIO();
      //     // io.emit("queue", {
      //     //   action: "update",
      //     //   queue
      //     // });
      //   } else {
      //     // CREATE
      //     // const queue = await CreateQueueService({
      //     //   name,
      //     //   color,
      //     //   greetingMessage
      //     // });
      //     // const io = getIO();
      //     // io.emit("queue", {
      //     //   action: "update",
      //     //   queue
      //     // });
      //   }
      // }

      let remove_queues = db_queues.filter(
        (q: any) =>
          !new_queues
            .map((nq: any) => nq.queueName)
            .includes(q.name?.trim()?.replace(/\s+/g, " "))
      );

      for (const i in remove_queues) {
        const { id, name } = remove_queues[i];

        // await DeleteQueueService(id);

        // const io = getIO();
        // io.emit("queue", {
        //   action: "delete",
        //   queueId: +id
        // });
      }

      // await set("ura", ura);
    }
  }

  await set("ura", ura);

  const _ura = await get({ key: "ura", parse: true });
  console.log("_URA: ", _ura);

  return res.status(200).json({ new_queues });
};

export const show = async (req: Request, res: Response): Promise<Response> => {
  const { queueId } = req.params;

  const queue = await ShowQueueService(queueId);

  return res.status(200).json(queue);
};

export const update = async (
  req: Request,
  res: Response
): Promise<Response> => {
  const { queueId } = req.params;

  const queue = await UpdateQueueService(queueId, req.body);

  const io = getIO();
  io.emit("queue", {
    action: "update",
    queue
  });

  return res.status(201).json(queue);
};

export const remove = async (
  req: Request,
  res: Response
): Promise<Response> => {
  const { queueId } = req.params;

  await DeleteQueueService(queueId);

  await QuickAnswerQueue.destroy({ where: { queueId } });
  await ContactQueue.destroy({ where: { queueId } });

  await del(`queue:${queueId}`);

  const io = getIO();
  io.emit("queue", {
    action: "delete",
    queueId: +queueId
  });

  return res.status(200).send();
};
