import { ExchangeVersion, Appointment, DateTime, MessageBody, Attendee, SendInvitationsMode, ItemId, PropertySet, ConflictResolutionMode, SendInvitationsOrCancellationsMode, DeleteMode, FolderId, LegacyFreeBusyStatus, CalendarView, FolderView, WellKnownFolderName, ExchangeService, WebCredentials, Uri } from "ews-javascript-api";
import { l as logger, o as symmetricDecrypt } from "./i18n-VAwx2uzJ.js";
class ExchangeCalendarService {
  constructor(credential) {
    this.url = "";
    this.integrationName = "";
    this.integrationName = "exchange2016_calendar";
    this.log = logger.getSubLogger({ prefix: [`[[lib] ${this.integrationName}`] });
    const decryptedCredential = JSON.parse(
      symmetricDecrypt(credential.key?.toString() || "", process.env.CALENDSO_ENCRYPTION_KEY || "")
    );
    const username = decryptedCredential.username;
    const url = decryptedCredential.url;
    const password = decryptedCredential.password;
    this.url = url;
    this.credentials = {
      username,
      password
    };
    this.exchangeVersion = ExchangeVersion.Exchange2016;
  }
  async createEvent(event) {
    try {
      const appointment = new Appointment(this.getExchangeService());
      appointment.Subject = event.title;
      appointment.Start = DateTime.Parse(event.startTime);
      appointment.End = DateTime.Parse(event.endTime);
      appointment.Location = event.location || "Location not defined!";
      appointment.Body = new MessageBody(event.description || "");
      for (let i = 0; i < event.attendees.length; i++) {
        appointment.RequiredAttendees.Add(new Attendee(event.attendees[i].email));
      }
      if (event.team?.members) {
        event.team.members.forEach((member) => {
          appointment.RequiredAttendees.Add(new Attendee(member.email));
        });
      }
      await appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy);
      return {
        uid: appointment.Id.UniqueId,
        id: appointment.Id.UniqueId,
        password: "",
        type: "",
        url: "",
        additionalInfo: {}
      };
    } catch (reason) {
      this.log.error(reason);
      throw reason;
    }
  }
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  async updateEvent(uid, event) {
    try {
      const appointment = await Appointment.Bind(
        this.getExchangeService(),
        new ItemId(uid),
        new PropertySet()
      );
      appointment.Subject = event.title;
      appointment.Start = DateTime.Parse(event.startTime);
      appointment.End = DateTime.Parse(event.endTime);
      appointment.Location = event.location || "Location not defined!";
      appointment.Body = new MessageBody(event.description || "");
      for (let i = 0; i < event.attendees.length; i++) {
        appointment.RequiredAttendees.Add(new Attendee(event.attendees[i].email));
      }
      if (event.team?.members) {
        event.team.members.forEach((member) => {
          appointment.RequiredAttendees.Add(new Attendee(member.email));
        });
      }
      appointment.Update(
        ConflictResolutionMode.AlwaysOverwrite,
        SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy
      );
    } catch (reason) {
      this.log.error(reason);
      throw reason;
    }
  }
  async deleteEvent(uid) {
    try {
      const appointment = await Appointment.Bind(
        this.getExchangeService(),
        new ItemId(uid),
        new PropertySet()
      );
      appointment.Delete(DeleteMode.MoveToDeletedItems);
    } catch (reason) {
      this.log.error(reason);
      throw reason;
    }
  }
  async getAvailability(dateFrom, dateTo, selectedCalendars) {
    try {
      const externalCalendars = await this.listCalendars();
      const calendarsToGetAppointmentsFrom = [];
      for (let i = 0; i < selectedCalendars.length; i++) {
        for (let k = 0; k < externalCalendars.length; k++) {
          if (selectedCalendars[i].externalId == externalCalendars[k].externalId) {
            calendarsToGetAppointmentsFrom.push(selectedCalendars[i]);
          }
        }
      }
      const finaleRet = [];
      for (let i = 0; i < calendarsToGetAppointmentsFrom.length; i++) {
        const calendarFolderId = new FolderId(calendarsToGetAppointmentsFrom[i].externalId);
        const localReturn = await this.getExchangeService().FindAppointments(
          calendarFolderId,
          new CalendarView(DateTime.Parse(dateFrom), DateTime.Parse(dateTo))
        ).then(function(params) {
          const ret = [];
          for (let k = 0; k < params.Items.length; k++) {
            if (params.Items[k].LegacyFreeBusyStatus != LegacyFreeBusyStatus.Free) {
              ret.push({
                start: new Date(params.Items[k].Start.ToISOString()),
                end: new Date(params.Items[k].End.ToISOString())
              });
            }
          }
          return ret;
        });
        finaleRet.push(...localReturn);
      }
      return finaleRet;
    } catch (reason) {
      this.log.error(reason);
      throw reason;
    }
  }
  async listCalendars() {
    try {
      const allFolders = [];
      return this.getExchangeService().FindFolders(WellKnownFolderName.MsgFolderRoot, new FolderView(1e3)).then(async (res) => {
        for (const k in res.Folders) {
          const f = res.Folders[k];
          if (f.FolderClass == "IPF.Appointment") {
            allFolders.push({
              externalId: f.Id.UniqueId,
              name: f.DisplayName ?? "",
              primary: true,
              //The first one is prime
              integration: this.integrationName
            });
            return await this.getExchangeService().FindFolders(f.Id, new FolderView(1e3)).then((res2) => {
              res2.Folders.forEach((fs) => {
                allFolders.push({
                  externalId: fs.Id.UniqueId,
                  name: fs.DisplayName ?? "",
                  primary: false,
                  integration: this.integrationName
                });
              });
              return allFolders;
            });
          }
        }
        return allFolders;
      });
    } catch (reason) {
      this.log.error(reason);
      throw reason;
    }
  }
  getExchangeService() {
    const exch1 = new ExchangeService(this.exchangeVersion);
    exch1.Credentials = new WebCredentials(this.credentials.username, this.credentials.password);
    exch1.Url = new Uri(this.url);
    return exch1;
  }
}
export {
  ExchangeCalendarService as default
};
