import { Message as WbotMessage } from "whatsapp-web.js";
import AppError from "../../errors/AppError";
import GetTicketWbot from "../../helpers/GetTicketWbot";
import GetWbotMessage from "../../helpers/GetWbotMessage";
import SerializeWbotMsgId from "../../helpers/SerializeWbotMsgId";
import Message from "../../models/Message";
import Ticket from "../../models/Ticket";
import Whatsapp from "../../models/Whatsapp";

import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService";
import wbotByUserQueue from "../../helpers/GetWbotByUserQueue";

import { WhatsIndex } from "../../helpers/LoadBalanceWhatsSameQueue";

import {
  deleteTicketsByContactsCache,
  updateTicketCacheByTicketId
} from "../../helpers/TicketCache";

import ListWhatsAppsNumber from "../WhatsappService/ListWhatsAppsNumber";
import { getWbot } from "../../libs/wbot";
import { json } from "sequelize/types";

import { restartWhatsSession } from "../../helpers/RestartWhatsSession";
// import { insertOrUpeateWhatsCache, searchWhatsappCache } from "../../helpers/WhatsCache";
import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp";
import autoRestore from "../../helpers/AutoRestore";
import { _restore } from "../../helpers/RestoreControll";
import { getIO } from "../../libs/socket";
import sendWhatsAppMessageSocket from "../../helpers/SendWhatsappMessageSocket";
import sendWhatsAppMessageOfficialAPI from "../../helpers/sendWhatsAppMessageOfficialAPI";

interface Request {
  body: string;
  ticket: Ticket;
  quotedMsg?: Message;
  number?: string;
}

const SendWhatsAppMessage = async ({
  body,
  ticket,
  quotedMsg,
  number
}: Request): Promise<WbotMessage | any> => {
  try {
    const { phoneNumberId } = ticket;

    if (phoneNumberId) {
      sendWhatsAppMessageOfficialAPI(ticket, body, quotedMsg);
      return;
    }

    let timestamp = Date.now() + String(Math.floor(Math.random() * 1000));
    var timetaken = `########################################${timestamp}| TicketId: ${ticket.id} => Time taken to send the message`;

    console.time(timetaken);

    let quotedMsgSerializedId: string | undefined;

    if (quotedMsg) {
      await GetWbotMessage(ticket, quotedMsg.id);

      quotedMsgSerializedId = SerializeWbotMsgId(ticket, quotedMsg);
    }

    console.log("quotedMsgSerializedId: ", quotedMsgSerializedId);

    let whatsapps: any;

    let listWhatsapp = null;

    // listWhatsapp = await searchWhatsappCache(`${ticket.whatsappId}`, 'CONNECTED')

    if (!ticket.whatsappId) {
      const defaultWhatsapp: any = await GetDefaultWhatsApp({
        userId: ticket.userId
      });

      await ticket.update({ whatsappId: +defaultWhatsapp.id });
    }

    if (!listWhatsapp) {
      listWhatsapp = await ListWhatsAppsNumber(ticket.whatsappId, "CONNECTED");
    }

    if (
      listWhatsapp.whatsapp &&
      listWhatsapp.whatsapp.status != "CONNECTED" &&
      listWhatsapp.whatsapps.length > 0
    ) {
      await ticket.update({ whatsappId: +listWhatsapp.whatsapps[0].id });
    }

    if (listWhatsapp.whatsapps.length > 1) {
      const _whatsapp =
        listWhatsapp.whatsapps[
          Math.floor(Math.random() * listWhatsapp.whatsapps.length)
        ];

      await ticket.update({ whatsappId: +_whatsapp.id });
    }

    if (
      listWhatsapp.whatsapps.length == 0 &&
      listWhatsapp.whatsapp.status != "CONNECTED"
    ) {
      whatsapps = await wbotByUserQueue({ userId: ticket.userId });

      if (whatsapps.length > 0) {
        whatsapps = whatsapps.filter((w: any) => !w?.isOfficial);

        if (whatsapps.length > 1) {
          await ticket.update({
            whatsappId: whatsapps[+WhatsIndex(whatsapps)].id
          });
        } else if (whatsapps && whatsapps.length == 1) {
          await ticket.update({ whatsappId: whatsapps[0].id });
        } else {
          throw new Error(
            "Sessão de Whatsapp desconectada! Entre em contato com o suporte."
          );
        }
      }
    }

    console.log(
      "1 --------> send from whatsapp ticket.whatsappId: ",
      ticket.whatsappId
    );

    try {
      sendWhatsAppMessageSocket(ticket, body, quotedMsgSerializedId, number);

      await ticket.update({ lastMessage: body });

      await updateTicketCacheByTicketId(ticket.id, {
        lastMessage: body,
        updatedAt: new Date(ticket.updatedAt).toISOString()
      });

      console.timeEnd(timetaken);
    } catch (err: any) {
      console.error("0 ===> Error on SendWhatsAppMessage.ts file: \n", err);
      throw new AppError("ERR_SENDING_WAPP_MSG");
    }
  } catch (error: any) {
    console.error("===> Error on SendWhatsAppMessage.ts file: \n", error);
    throw new AppError(error.message);
  }
};

export default SendWhatsAppMessage;
