import axios from "axios";
import qs from "qs";
import { d as getLocation } from "./CalEventParser-ZzmnrFso.js";
import { H as HttpError } from "./http-error-RJXCPZV2.js";
import { l as logger, p as prisma } from "./user--mpkKOwW.js";
import { g as getAppKeysFromSlug } from "./getAppKeysFromSlug-IDaQR-Xd.js";
import { r as refreshOAuthTokens } from "./refreshOAuthTokens-xR8Ic7eC.js";
const toISO8601String = (date) => {
  const tzo = -date.getTimezoneOffset(), dif = tzo >= 0 ? "+" : "-", pad = function(num) {
    return (num < 10 ? "0" : "") + num;
  };
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(
    date.getHours()
  )}:${pad(date.getMinutes())}:${pad(date.getSeconds())}${dif}${pad(Math.floor(Math.abs(tzo) / 60))}:${pad(
    Math.abs(tzo) % 60
  )}`;
};
class ZohoCrmCrmService {
  constructor(credential) {
    this.integrationName = "";
    this.client_id = "";
    this.client_secret = "";
    this.accessToken = "";
    this.getMeetingBody = (event) => {
      return `<b>${event.organizer.language.translate("invitee_timezone")}:</b> ${event.attendees[0].timeZone}<br><br><b>${event.organizer.language.translate("share_additional_notes")}</b><br>${event.additionalNotes || "-"}`;
    };
    this.createZohoEvent = async (event, contacts) => {
      const zohoEvent = {
        Event_Title: event.title,
        Start_DateTime: toISO8601String(new Date(event.startTime)),
        End_DateTime: toISO8601String(new Date(event.endTime)),
        Description: this.getMeetingBody(event),
        Venue: getLocation(event),
        Who_Id: contacts[0].id
        // Link the first attendee as the primary Who_Id
      };
      return axios({
        method: "post",
        url: `https://www.zohoapis.com/crm/v3/Events`,
        headers: {
          "content-type": "application/json",
          authorization: `Zoho-oauthtoken ${this.accessToken}`
        },
        data: JSON.stringify({ data: [zohoEvent] })
      }).then((data) => data.data).catch((e) => this.log.error(e, e.response?.data));
    };
    this.updateMeeting = async (uid, event) => {
      const zohoEvent = {
        id: uid,
        Event_Title: event.title,
        Start_DateTime: toISO8601String(new Date(event.startTime)),
        End_DateTime: toISO8601String(new Date(event.endTime)),
        Description: this.getMeetingBody(event),
        Venue: getLocation(event)
      };
      return axios({
        method: "put",
        url: `https://www.zohoapis.com/crm/v3/Events`,
        headers: {
          "content-type": "application/json",
          authorization: `Zoho-oauthtoken ${this.accessToken}`
        },
        data: JSON.stringify({ data: [zohoEvent] })
      }).then((data) => data.data).catch((e) => this.log.error(e, e.response?.data));
    };
    this.deleteMeeting = async (uid) => {
      return axios({
        method: "delete",
        url: `https://www.zohoapis.com/crm/v3/Events?ids=${uid}`,
        headers: {
          "content-type": "application/json",
          authorization: `Zoho-oauthtoken ${this.accessToken}`
        }
      }).then((data) => data.data).catch((e) => this.log.error(e, e.response?.data));
    };
    this.zohoCrmAuth = async (credential2) => {
      const appKeys = await getAppKeysFromSlug("zohocrm");
      if (typeof appKeys.client_id === "string")
        this.client_id = appKeys.client_id;
      if (typeof appKeys.client_secret === "string")
        this.client_secret = appKeys.client_secret;
      if (!this.client_id)
        throw new HttpError({ statusCode: 400, message: "Zoho CRM client_id missing." });
      if (!this.client_secret)
        throw new HttpError({ statusCode: 400, message: "Zoho CRM client_secret missing." });
      const credentialKey = credential2.key;
      const isTokenValid = (token) => {
        const isValid = token && token.access_token && token.expiryDate && token.expiryDate > Date.now();
        if (isValid) {
          this.accessToken = token.access_token;
        }
        return isValid;
      };
      const refreshAccessToken = async (credentialKey2) => {
        try {
          const url = `${credentialKey2.accountServer}/oauth/v2/token`;
          const formData = {
            grant_type: "refresh_token",
            client_id: this.client_id,
            client_secret: this.client_secret,
            refresh_token: credentialKey2.refresh_token
          };
          const zohoCrmTokenInfo = await refreshOAuthTokens(
            async () => await axios({
              method: "post",
              url,
              data: qs.stringify(formData),
              headers: {
                "Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
              }
            }),
            "zohocrm",
            credential2.userId
          );
          if (!zohoCrmTokenInfo.data.error) {
            zohoCrmTokenInfo.data.expiryDate = Math.round(Date.now() + 60 * 60);
            await prisma.credential.update({
              where: {
                id: credential2.id
              },
              data: {
                key: {
                  ...zohoCrmTokenInfo.data,
                  refresh_token: credentialKey2.refresh_token,
                  accountServer: credentialKey2.accountServer
                }
              }
            });
            this.accessToken = zohoCrmTokenInfo.data.access_token;
            this.log.debug("Fetched token", this.accessToken);
          } else {
            this.log.error(zohoCrmTokenInfo.data);
          }
        } catch (e) {
          this.log.error(e);
        }
      };
      return {
        getToken: () => isTokenValid(credentialKey) ? Promise.resolve() : refreshAccessToken(credentialKey)
      };
    };
    this.integrationName = "zohocrm_crm";
    this.auth = this.zohoCrmAuth(credential).then((r) => r);
    this.log = logger.getSubLogger({ prefix: [`[[lib] ${this.integrationName}`] });
  }
  async createContacts(contactsToCreate) {
    const auth = await this.auth;
    await auth.getToken();
    const contacts = contactsToCreate.map((contactToCreate) => {
      const [firstname, lastname] = !!contactToCreate.name ? contactToCreate.name.split(" ") : [contactToCreate.email, "-"];
      return {
        First_Name: firstname,
        Last_Name: lastname || "-",
        Email: contactToCreate.email
      };
    });
    const response = await axios({
      method: "post",
      url: `https://www.zohoapis.com/crm/v3/Contacts`,
      headers: {
        "content-type": "application/json",
        authorization: `Zoho-oauthtoken ${this.accessToken}`
      },
      data: JSON.stringify({ data: contacts })
    });
    const { data } = response;
    return data.data.map((contact) => {
      return {
        id: contact.id,
        email: contact.email
      };
    });
  }
  async getContacts({ emails }) {
    const auth = await this.auth;
    await auth.getToken();
    const emailsArray = Array.isArray(emails) ? emails : [emails];
    const searchCriteria = `(${emailsArray.map((email) => `(Email:equals:${encodeURI(email)})`).join("or")})`;
    const response = await axios({
      method: "get",
      url: `https://www.zohoapis.com/crm/v3/Contacts/search?criteria=${searchCriteria}`,
      headers: {
        authorization: `Zoho-oauthtoken ${this.accessToken}`
      }
    }).then((data) => data.data).catch((e) => {
      this.log.error(e, e.response?.data);
    });
    return response ? response.data.map((contact) => {
      return {
        id: contact.id,
        email: contact.email
      };
    }) : [];
  }
  async handleEventCreation(event, contacts) {
    const meetingEvent = await this.createZohoEvent(event, contacts);
    if (meetingEvent.data && meetingEvent.data.length && meetingEvent.data[0].status === "success") {
      this.log.debug("event:creation:ok", { meetingEvent });
      return Promise.resolve({
        uid: meetingEvent.data[0].details.id,
        id: meetingEvent.data[0].details.id,
        type: this.integrationName,
        password: "",
        url: "",
        additionalInfo: { contacts, meetingEvent }
      });
    }
    this.log.debug("meeting:creation:notOk", { meetingEvent, event, contacts });
    return Promise.reject("Something went wrong when creating a meeting in ZohoCRM");
  }
  async createEvent(event, contacts) {
    const auth = await this.auth;
    await auth.getToken();
    return await this.handleEventCreation(event, contacts);
  }
  async updateEvent(uid, event) {
    const auth = await this.auth;
    await auth.getToken();
    return await this.updateMeeting(uid, event);
  }
  async deleteEvent(uid) {
    const auth = await this.auth;
    await auth.getToken();
    return await this.deleteMeeting(uid);
  }
  getAppOptions() {
    console.log("No options implemented");
  }
  async handleAttendeeNoShow() {
    console.log("Not implemented");
  }
}
export {
  ZohoCrmCrmService as default
};
