import CheckContactOpenTickets from "../../helpers/CheckContactOpenTickets";
import SetTicketMessagesAsRead from "../../helpers/SetTicketMessagesAsRead";
import { getIO } from "../../libs/socket";
import Ticket from "../../models/Ticket";
import SendWhatsAppMessage from "../WbotServices/SendWhatsAppMessage";
import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService";
import ShowTicketService from "./ShowTicketService";

import { createOrUpdateTicketCache } from "../../helpers/TicketCache";
import AppError from "../../errors/AppError";
import sendWhatsAppMessageSocket from "../../helpers/SendWhatsappMessageSocket";
import BotIsOnQueue from "../../helpers/BotIsOnQueue";
import { del, deleteObject, get, set } from "../../helpers/RedisClient";
var flatten = require("flat");

interface TicketData {
  status?: string;
  userId?: number | null;
  queueId?: number;
  statusChatEnd?: string;
  statusChatEndId?: number;
  unreadMessages?: number;
  whatsappId?: string | number;
  isRemote?: boolean;
}

interface Request {
  ticketData: TicketData;
  ticketId: string | number;
  msg?: string;
}

interface Response {
  ticket: Ticket;
  oldStatus: string;
  oldUserId: number | undefined;
}

const UpdateTicketService = async ({
  ticketData,
  ticketId,
  msg = ""
}: Request): Promise<Response> => {
  try {
    const {
      status,
      userId,
      queueId,
      statusChatEnd,
      unreadMessages,
      statusChatEndId,
      whatsappId,
      isRemote
    } = ticketData;

    const ticket = await ShowTicketService(ticketId);

    const botInfo = await BotIsOnQueue("botqueue");

    if (
      status == "closed" ||
      (status == "open" && ticket && `${userId}` != `${botInfo.userIdBot}`)
    ) {
      deleteObject(`${ticket.whatsappId}`, `${ticket.contactId}`, "ura");
    }

    const oldStatus = ticket.status;
    const oldUserId = ticket.user?.id;

    if (oldStatus === "closed") {
      await CheckContactOpenTickets(ticket.contact.id, ticket.whatsappId);
    }

    if (status == "closed") {
      del(`remote:ticketId:${ticket.id}`);

      let ticketsIds = await get({ key: `remote:controll`, parse: true });

      if (ticketsIds) {
        const index = ticketsIds.findIndex((t: any) => t == ticket.id);

        console.log("ticketsIds 1: ", ticketsIds);

        if (index != -1) {
          ticketsIds.splice(index, 1);

          console.log("ticketsIds 2: ", ticketsIds);

          set(`remote:controll`, JSON.stringify(ticketsIds));
        }
      }
    }

    await ticket.update({
      status,
      queueId,
      userId,
      unreadMessages,
      statusChatEnd,
      statusChatEndId,
      whatsappId,
      isRemote
    });

    await ticket.reload();

    if (msg?.trim().length > 0) {
      setTimeout(async () => {
        sendWhatsAppMessageSocket(ticket, `\u200e${msg}`);
      }, 2000);
    }

    // TEST DEL
    try {
      // const { name, number } = await ShowContactService(ticket.contactId)

      let jsonString = JSON.stringify(ticket); //convert to string to remove the sequelize specific meta data
      let ticket_obj = JSON.parse(jsonString); //to make plain json
      delete ticket_obj["contact"]["extraInfo"];
      delete ticket_obj["user"];

      ticket_obj = flatten(ticket_obj);

      await createOrUpdateTicketCache(`ticket:${ticket.id}`, ticket_obj);
    } catch (error) {
      console.log(
        "There was an error on UpdateTicketService.ts on createTicketCache: ",
        error
      );
    }
    //

    let io = getIO();

    if (ticket.status !== oldStatus || ticket.user?.id !== oldUserId) {
      io.to(oldStatus).emit("ticket", {
        action: "delete",
        ticketId: ticket.id
      });
    }

    io.to(ticket.status)
      .to("notification")
      .to(ticketId.toString())
      .emit("ticket", {
        action: "update",
        ticket
      });

    io.emit("ticketStatus", {
      action: "update",
      ticketStatus: { ticketId: ticket.id, status: ticket.status }
    });

    return { ticket, oldStatus, oldUserId };
  } catch (error: any) {
    console.error("===> Error on UpdateTicketService.ts file: \n", error);
    throw new AppError(error.message);
  }
};

export default UpdateTicketService;
