import { Appointment, DateTime, MessageBody, Attendee, SendInvitationsMode, ItemId, ConflictResolutionMode, SendInvitationsOrCancellationsMode, DeleteMode, FolderId, CalendarView, LegacyFreeBusyStatus, FolderView, PropertySet, BasePropertySet, FolderSchema, FolderTraversal, Folder, WellKnownFolderName, SearchFilter, LogicalOperator, ExchangeService, WebCredentials, Uri } from "ews-javascript-api";
import { l as logger, n as symmetricDecrypt } from "./i18n-tiaWqB1b.js";
var ExchangeAuthentication = /* @__PURE__ */ ((ExchangeAuthentication2) => {
  ExchangeAuthentication2[ExchangeAuthentication2["STANDARD"] = 0] = "STANDARD";
  ExchangeAuthentication2[ExchangeAuthentication2["NTLM"] = 1] = "NTLM";
  return ExchangeAuthentication2;
})(ExchangeAuthentication || {});
class ExchangeCalendarService {
  constructor(credential) {
    this.integrationName = "";
    this.integrationName = "exchange_calendar";
    this.log = logger.getSubLogger({ prefix: [`[[lib] ${this.integrationName}`] });
    this.payload = JSON.parse(
      symmetricDecrypt(credential.key?.toString() || "", process.env.CALENDSO_ENCRYPTION_KEY || "")
    );
  }
  async createEvent(event) {
    const appointment = new Appointment(await this.getExchangeService());
    appointment.Subject = event.title;
    appointment.Start = DateTime.Parse(event.startTime);
    appointment.End = DateTime.Parse(event.endTime);
    appointment.Location = event.location || "";
    appointment.Body = new MessageBody(event.description || "");
    event.attendees.forEach((attendee) => {
      appointment.RequiredAttendees.Add(new Attendee(attendee.email));
    });
    if (event.team?.members) {
      event.team.members.forEach((member) => {
        appointment.RequiredAttendees.Add(new Attendee(member.email));
      });
    }
    return appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy).then(() => {
      return {
        uid: appointment.Id.UniqueId,
        id: appointment.Id.UniqueId,
        password: "",
        type: "",
        url: "",
        additionalInfo: {}
      };
    }).catch((reason) => {
      this.log.error(reason);
      throw reason;
    });
  }
  async updateEvent(uid, event) {
    const appointment = await Appointment.Bind(await this.getExchangeService(), new ItemId(uid));
    appointment.Subject = event.title;
    appointment.Start = DateTime.Parse(event.startTime);
    appointment.End = DateTime.Parse(event.endTime);
    appointment.Location = event.location || "";
    appointment.Body = new MessageBody(event.description || "");
    event.attendees.forEach((attendee) => {
      appointment.RequiredAttendees.Add(new Attendee(attendee.email));
    });
    if (event.team?.members) {
      event.team.members.forEach((member) => {
        appointment.RequiredAttendees.Add(new Attendee(member.email));
      });
    }
    return appointment.Update(
      ConflictResolutionMode.AlwaysOverwrite,
      SendInvitationsOrCancellationsMode.SendToChangedAndSaveCopy
    ).then(() => {
      return {
        uid: appointment.Id.UniqueId,
        id: appointment.Id.UniqueId,
        password: "",
        type: "",
        url: "",
        additionalInfo: {}
      };
    }).catch((reason) => {
      this.log.error(reason);
      throw reason;
    });
  }
  async deleteEvent(uid) {
    const appointment = await Appointment.Bind(await this.getExchangeService(), new ItemId(uid));
    return appointment.Delete(DeleteMode.MoveToDeletedItems).catch((reason) => {
      this.log.error(reason);
      throw reason;
    });
  }
  async getAvailability(dateFrom, dateTo, selectedCalendars) {
    const calendars = await this.listCalendars();
    const promises = calendars.filter((lcal) => selectedCalendars.some((rcal) => lcal.externalId == rcal.externalId)).map(async (calendar) => {
      return (await this.getExchangeService()).FindAppointments(
        new FolderId(calendar.externalId),
        new CalendarView(DateTime.Parse(dateFrom), DateTime.Parse(dateTo))
      ).then((results) => {
        return results.Items.filter((appointment) => {
          return appointment.LegacyFreeBusyStatus != LegacyFreeBusyStatus.Free;
        }).map((appointment) => {
          return {
            start: new Date(appointment.Start.ToISOString()),
            end: new Date(appointment.End.ToISOString())
          };
        });
      }).catch((reason) => {
        this.log.error(reason);
        throw reason;
      });
    });
    return Promise.all(promises).then((x) => x.flat());
  }
  async listCalendars() {
    const service = await this.getExchangeService();
    const view = new FolderView(1e3);
    view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
    view.PropertySet.Add(FolderSchema.ParentFolderId);
    view.PropertySet.Add(FolderSchema.DisplayName);
    view.PropertySet.Add(FolderSchema.ChildFolderCount);
    view.Traversal = FolderTraversal.Deep;
    const deletedItemsFolder = await Folder.Bind(service, WellKnownFolderName.DeletedItems);
    const searchFilterCollection = new SearchFilter.SearchFilterCollection(LogicalOperator.And);
    searchFilterCollection.Add(new SearchFilter.IsEqualTo(FolderSchema.FolderClass, "IPF.Appointment"));
    return service.FindFolders(WellKnownFolderName.MsgFolderRoot, searchFilterCollection, view).then((res) => {
      return res.Folders.filter((folder) => {
        return folder.ParentFolderId.UniqueId != deletedItemsFolder.Id.UniqueId;
      }).map((folder) => {
        return {
          externalId: folder.Id.UniqueId,
          name: folder.DisplayName ?? "",
          primary: folder.ChildFolderCount > 0,
          integration: this.integrationName
        };
      });
    }).catch((reason) => {
      this.log.error(reason);
      throw reason;
    });
  }
  async getExchangeService() {
    const service = new ExchangeService(this.payload.exchangeVersion);
    service.Credentials = new WebCredentials(this.payload.username, this.payload.password);
    service.Url = new Uri(this.payload.url);
    if (this.payload.authenticationMethod === ExchangeAuthentication.NTLM) {
      const { XhrApi } = await import("@ewsjs/xhr");
      const xhr = new XhrApi({
        rejectUnauthorized: false
      }).useNtlmAuthentication(this.payload.username, this.payload.password);
      service.XHRApi = xhr;
    }
    return service;
  }
}
export {
  ExchangeCalendarService as default
};
