import { subHours, subMinutes, subSeconds } from "date-fns";
import { Op } from "sequelize";
import BotIsOnQueue from "../../helpers/BotIsOnQueue";
import Contact from "../../models/Contact";
import Ticket from "../../models/Ticket";
import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService";
import ShowTicketService from "./ShowTicketService";
import AppError from "../../errors/AppError";
import ListWhatsAppsNumber from "../WhatsappService/ListWhatsAppsNumber";
import { getSettingValue } from "../../helpers/WhaticketSettings";

const FindOrCreateTicketService = async (
  contact: Contact,
  whatsappId: number,
  unreadMessages: number,
  groupContact?: Contact,
  queueId?: number | string,
  isRemote?: boolean
): Promise<Ticket> => {
  try {
    let ticket;

    if (getSettingValue("oneContactChatWithManyWhats")?.value == "enabled") {
      let whats = await ListWhatsAppsNumber(whatsappId);

      ticket = await Ticket.findOne({
        where: {
          status: {
            [Op.or]: ["open", "pending", "queueChoice"]
          },
          contactId: groupContact ? groupContact.id : contact.id,
          whatsappId: { [Op.in]: whats.whatsapps.map((w: any) => w.id) }
        }
      });
    } else {
      ticket = await Ticket.findOne({
        where: {
          status: {
            [Op.or]: ["open", "pending", "queueChoice"]
          },
          contactId: groupContact ? groupContact.id : contact.id
        }
      });
    }

    const { queues, greetingMessage, phoneNumberId } =
      await ShowWhatsAppService(whatsappId);

    const botInfo = { isOnQueue: false };

    if (ticket) {
      await ticket.update({ unreadMessages });
    }

    if (!ticket && groupContact) {
      ticket = await Ticket.findOne({
        where: {
          contactId: groupContact.id
        },
        order: [["updatedAt", "DESC"]]
      });

      if (ticket) {
        await ticket.update({
          status: "pending",
          userId: null,
          unreadMessages
        });
      }
    }

    if (!ticket && !groupContact) {
      ticket = await Ticket.findOne({
        where: {
          updatedAt: {
            // Tempo osioso para a ura responder  thuanny
            //[Op.between]: [+subMinutes(new Date(), 30), +new Date()]

            // Sub seconds
            [Op.between]: [+subSeconds(new Date(), 0), +new Date()]
          },
          contactId: contact.id
        },
        order: [["updatedAt", "DESC"]]
      });

      if (ticket) {
        await ticket.update({
          status: "pending",
          userId: null,
          unreadMessages
        });
      }
    }

    if (!ticket) {
      let status = "pending";

      if (queues.length > 1 && !botInfo.isOnQueue && !queueId) {
        status = "queueChoice";
      }

      ticket = await Ticket.create({
        contactId: groupContact ? groupContact.id : contact.id,
        status: status,
        isGroup: !!groupContact,
        queueId,
        unreadMessages,
        whatsappId,
        phoneNumberId,
        isRemote
      });
    }

    ticket = await ShowTicketService(ticket.id);

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

export default FindOrCreateTicketService;
