import * as hubspot from "@hubspot/api-client";
import { d as getLabelValueMapFromResponses, b as getLocation } from "./CalEventParser-yX6oM9Dn.js";
import { l as logger, v as WEBAPP_URL, p as prisma } from "./i18n-VAwx2uzJ.js";
import { H as HttpError } from "./http-error-RJXCPZV2.js";
import { g as getAppKeysFromSlug } from "./getAppKeysFromSlug-UZbl5tW2.js";
import { r as refreshOAuthTokens } from "./refreshOAuthTokens-pVzgg2nd.js";
class HubspotCalendarService {
  constructor(credential) {
    this.url = "";
    this.integrationName = "";
    this.client_id = "";
    this.client_secret = "";
    this.getHubspotMeetingBody = (event) => {
      const userFields = getLabelValueMapFromResponses(event);
      const plainText = event?.description?.replace(/<\/?[^>]+(>|$)/g, "").replace(/_/g, " ");
      const location = getLocation(event);
      const userFieldsHtml = Object.entries(userFields).map(([key, value]) => {
        const formattedValue = typeof value === "boolean" ? value ? "Yes" : "No" : value || "-";
        return `<b>${event.organizer.language.translate(key)}:</b> ${formattedValue}`;
      }).join("<br><br>");
      return `<b>${event.organizer.language.translate("invitee_timezone")}:</b> ${event.attendees[0].timeZone}<br><br>${event.additionalNotes ? `<b>${event.organizer.language.translate("share_additional_notes")}</b><br>${event.additionalNotes}<br><br>` : ""}
    ${userFieldsHtml}<br><br>
    <b>${event.organizer.language.translate("where")}:</b> ${location}<br><br>
    ${plainText ? `<b>${event.organizer.language.translate("description")}</b><br>${plainText}` : ""}
  `;
    };
    this.hubspotCreateMeeting = async (event) => {
      const simplePublicObjectInput = {
        properties: {
          hs_timestamp: Date.now().toString(),
          hs_meeting_title: event.title,
          hs_meeting_body: this.getHubspotMeetingBody(event),
          hs_meeting_location: getLocation(event),
          hs_meeting_start_time: new Date(event.startTime).toISOString(),
          hs_meeting_end_time: new Date(event.endTime).toISOString(),
          hs_meeting_outcome: "SCHEDULED"
        }
      };
      return this.hubspotClient.crm.objects.meetings.basicApi.create(simplePublicObjectInput);
    };
    this.hubspotAssociate = async (meeting, contacts) => {
      const batchInputPublicAssociation = {
        inputs: contacts.map((contact) => ({
          _from: { id: meeting.id },
          to: { id: contact.id },
          type: "meeting_event_to_contact"
        }))
      };
      return this.hubspotClient.crm.associations.batchApi.create(
        "meetings",
        "contacts",
        batchInputPublicAssociation
      );
    };
    this.hubspotUpdateMeeting = async (uid, event) => {
      const simplePublicObjectInput = {
        properties: {
          hs_timestamp: Date.now().toString(),
          hs_meeting_title: event.title,
          hs_meeting_body: this.getHubspotMeetingBody(event),
          hs_meeting_location: getLocation(event),
          hs_meeting_start_time: new Date(event.startTime).toISOString(),
          hs_meeting_end_time: new Date(event.endTime).toISOString(),
          hs_meeting_outcome: "RESCHEDULED"
        }
      };
      return this.hubspotClient.crm.objects.meetings.basicApi.update(uid, simplePublicObjectInput);
    };
    this.hubspotDeleteMeeting = async (uid) => {
      return this.hubspotClient.crm.objects.meetings.basicApi.archive(uid);
    };
    this.hubspotAuth = async (credential2) => {
      const appKeys = await getAppKeysFromSlug("hubspot");
      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: "Hubspot client_id missing." });
      if (!this.client_secret)
        throw new HttpError({ statusCode: 400, message: "Hubspot client_secret missing." });
      const credentialKey = credential2.key;
      const isTokenValid = (token) => token && token.tokenType && token.accessToken && token.expiryDate && (token.expiresIn || token.expiryDate) < Date.now();
      const refreshAccessToken = async (refreshToken) => {
        try {
          const hubspotRefreshToken = await refreshOAuthTokens(
            async () => await this.hubspotClient.oauth.tokensApi.createToken(
              "refresh_token",
              void 0,
              `${WEBAPP_URL}/api/integrations/hubspot/callback`,
              this.client_id,
              this.client_secret,
              refreshToken
            ),
            "hubspot",
            credential2.userId
          );
          hubspotRefreshToken.expiryDate = Math.round(Date.now() + hubspotRefreshToken.expiresIn * 1e3);
          await prisma.credential.update({
            where: {
              id: credential2.id
            },
            data: {
              key: hubspotRefreshToken
            }
          });
          this.hubspotClient.setAccessToken(hubspotRefreshToken.accessToken);
        } catch (e) {
          this.log.error(e);
        }
      };
      return {
        getToken: () => !isTokenValid(credentialKey) ? Promise.resolve([]) : refreshAccessToken(credentialKey.refreshToken)
      };
    };
    this.hubspotClient = new hubspot.Client();
    this.integrationName = "hubspot_other_calendar";
    this.auth = this.hubspotAuth(credential).then((r) => r);
    this.log = logger.getSubLogger({ prefix: [`[[lib] ${this.integrationName}`] });
  }
  async handleMeetingCreation(event, contacts) {
    const contactIds = contacts.map((contact) => ({ id: contact.id }));
    const meetingEvent = await this.hubspotCreateMeeting(event);
    if (meetingEvent) {
      this.log.debug("meeting:creation:ok", { meetingEvent });
      const associatedMeeting = await this.hubspotAssociate(meetingEvent, contactIds);
      if (associatedMeeting) {
        this.log.debug("association:creation:ok", { associatedMeeting });
        return Promise.resolve({
          uid: meetingEvent.id,
          id: meetingEvent.id,
          type: "hubspot_other_calendar",
          password: "",
          url: "",
          additionalInfo: { contacts, associatedMeeting }
        });
      }
      return Promise.reject("Something went wrong when associating the meeting and attendees in HubSpot");
    }
    this.log.debug("meeting:creation:notOk", { meetingEvent, event, contacts });
    return Promise.reject("Something went wrong when creating a meeting in HubSpot");
  }
  async createEvent(event, contacts) {
    const auth = await this.auth;
    await auth.getToken();
    return await this.handleMeetingCreation(event, contacts);
  }
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  async updateEvent(uid, event) {
    const auth = await this.auth;
    await auth.getToken();
    return await this.hubspotUpdateMeeting(uid, event);
  }
  async deleteEvent(uid) {
    const auth = await this.auth;
    await auth.getToken();
    return await this.hubspotDeleteMeeting(uid);
  }
  async getContacts({ emails }) {
    const auth = await this.auth;
    await auth.getToken();
    const emailArray = Array.isArray(emails) ? emails : [emails];
    const publicObjectSearchRequest = {
      filterGroups: emailArray.map((attendeeEmail) => ({
        filters: [
          {
            value: attendeeEmail,
            propertyName: "email",
            operator: "EQ"
          }
        ]
      })),
      sorts: ["hs_object_id"],
      properties: ["hs_object_id", "email"],
      limit: 10,
      after: 0
    };
    const contacts = await this.hubspotClient.crm.contacts.searchApi.doSearch(publicObjectSearchRequest).then((apiResponse) => apiResponse.results);
    return contacts.map((contact) => {
      return {
        id: contact.id,
        email: contact.properties.email
      };
    });
  }
  async createContacts(contactsToCreate) {
    const auth = await this.auth;
    await auth.getToken();
    const simplePublicObjectInputs = contactsToCreate.map((attendee) => {
      const [firstname, lastname] = attendee.name ? attendee.name.split(" ") : [attendee.email, ""];
      return {
        properties: {
          firstname,
          lastname,
          email: attendee.email
        }
      };
    });
    const createdContacts = await Promise.all(
      simplePublicObjectInputs.map(
        (contact) => this.hubspotClient.crm.contacts.basicApi.create(contact).catch((error) => {
          if (error.body.message.includes("Contact already exists. Existing ID:")) {
            const split = error.body.message.split("Contact already exists. Existing ID: ");
            return { id: split[1], properties: contact.properties };
          } else {
            throw error;
          }
        })
      )
    );
    return createdContacts.map((contact) => {
      return {
        id: contact.id,
        email: contact.properties.email
      };
    });
  }
  getAppOptions() {
    console.log("No options implemented");
  }
  async handleAttendeeNoShow() {
    console.log("Not implemented");
  }
}
export {
  HubspotCalendarService as default
};
