import AppError from "../../errors/AppError";
import Contact from "../../models/Contact";
import ContactCustomField from "../../models/ContactCustomField";

import { updateTicketsByContactsCache } from "../../helpers/TicketCache";
import { updateContactCacheById } from "../../helpers/ContactsCache";
import { tr } from "date-fns/locale";
import AssociateContatctQueue from "./AssociateContatctQueue";

interface ExtraInfo {
  id?: number;
  name: string;
  value: string;
}
interface ContactData {
  email?: string;
  number?: string;
  name?: string;
  extraInfo?: ExtraInfo[];
  queueIds?: number[];
}

interface Request {
  contactData: ContactData;
  contactId: string;
}

const UpdateContactService = async ({
  contactData,
  contactId
}: Request): Promise<Contact> => {
  try {
    const { email, name, number, extraInfo, queueIds } = contactData;

    // console.log('email, name, number, extraInfo: ', email, name, number, extraInfo)

    const contact = await Contact.findOne({
      where: { id: contactId },
      attributes: ["id", "name", "number", "email", "profilePicUrl"],
      include: ["extraInfo"]
    });

    if (!contact) {
      throw new AppError("ERR_NO_CONTACT_FOUND", 404);
    }

    if (extraInfo) {
      await Promise.all(
        extraInfo.map(async info => {
          await ContactCustomField.upsert({ ...info, contactId: contact.id });
        })
      );

      await Promise.all(
        contact.extraInfo.map(async oldInfo => {
          const stillExists = extraInfo.findIndex(
            info => info.id === oldInfo.id
          );

          if (stillExists === -1) {
            await ContactCustomField.destroy({ where: { id: oldInfo.id } });
          }
        })
      );
    }

    const oldNumber = contact.number;

    //Solução para o erro tcp_wrap.cc
    console.log("----------> oldNumber: ", oldNumber);
    if (number) {
      const numberExists = await Contact.findOne({
        where: { number }
      });

      if (numberExists && numberExists.id != +contactId) {
        throw new AppError("ERR_DUPLICATED_CONTACT");
      }
    }

    await contact.update({
      name,
      number,
      email
    });

    
    if (queueIds) await AssociateContatctQueue(contact, queueIds);

    //TEST DEL
    await updateTicketsByContactsCache(oldNumber, contact.name, contact.number);
    //

    await contact.reload({
      attributes: ["id", "name", "number", "email", "profilePicUrl"],
      include: ["extraInfo"]
    });

    // console.log('contactcontactcontactcontact: ',flatten(JSON.parse(JSON.stringify(contact))))
    await updateContactCacheById(
      contact.id,
      JSON.parse(JSON.stringify(contact))
    );

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

export default UpdateContactService;
