"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const z = require("zod");
const index$2 = require("./user-v6mfWQ2d.cjs");
const defaultHandler = require("./defaultHandler-MSjhitc-.cjs");
const defaultResponder = require("./defaultResponder-QWPOXt61.cjs");
const getInstalledAppPath = require("./getInstalledAppPath-3c7mqtrk.cjs");
const ewsJavascriptApi = require("ews-javascript-api");
const _metadata = require("./_metadata-bC6MV2HH.cjs");
class ExchangeCalendarService {
  constructor(credential) {
    this.url = "";
    this.integrationName = "";
    this.integrationName = "exchange2016_calendar";
    this.log = index$2.logger.getSubLogger({ prefix: [`[[lib] ${this.integrationName}`] });
    const decryptedCredential = JSON.parse(
      index$2.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 = ewsJavascriptApi.ExchangeVersion.Exchange2016;
  }
  async createEvent(event) {
    try {
      const appointment = new ewsJavascriptApi.Appointment(this.getExchangeService());
      appointment.Subject = event.title;
      appointment.Start = ewsJavascriptApi.DateTime.Parse(event.startTime);
      appointment.End = ewsJavascriptApi.DateTime.Parse(event.endTime);
      appointment.Location = event.location || "Location not defined!";
      appointment.Body = new ewsJavascriptApi.MessageBody(event.description || "");
      for (let i = 0; i < event.attendees.length; i++) {
        appointment.RequiredAttendees.Add(new ewsJavascriptApi.Attendee(event.attendees[i].email));
      }
      if (event.team?.members) {
        event.team.members.forEach((member) => {
          appointment.RequiredAttendees.Add(new ewsJavascriptApi.Attendee(member.email));
        });
      }
      await appointment.Save(ewsJavascriptApi.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 ewsJavascriptApi.Appointment.Bind(
        this.getExchangeService(),
        new ewsJavascriptApi.ItemId(uid),
        new ewsJavascriptApi.PropertySet()
      );
      appointment.Subject = event.title;
      appointment.Start = ewsJavascriptApi.DateTime.Parse(event.startTime);
      appointment.End = ewsJavascriptApi.DateTime.Parse(event.endTime);
      appointment.Location = event.location || "Location not defined!";
      appointment.Body = new ewsJavascriptApi.MessageBody(event.description || "");
      for (let i = 0; i < event.attendees.length; i++) {
        appointment.RequiredAttendees.Add(new ewsJavascriptApi.Attendee(event.attendees[i].email));
      }
      if (event.team?.members) {
        event.team.members.forEach((member) => {
          appointment.RequiredAttendees.Add(new ewsJavascriptApi.Attendee(member.email));
        });
      }
      appointment.Update(
        ewsJavascriptApi.ConflictResolutionMode.AlwaysOverwrite,
        ewsJavascriptApi.SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy
      );
    } catch (reason) {
      this.log.error(reason);
      throw reason;
    }
  }
  async deleteEvent(uid) {
    try {
      const appointment = await ewsJavascriptApi.Appointment.Bind(
        this.getExchangeService(),
        new ewsJavascriptApi.ItemId(uid),
        new ewsJavascriptApi.PropertySet()
      );
      appointment.Delete(ewsJavascriptApi.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 ewsJavascriptApi.FolderId(calendarsToGetAppointmentsFrom[i].externalId);
        const localReturn = await this.getExchangeService().FindAppointments(
          calendarFolderId,
          new ewsJavascriptApi.CalendarView(ewsJavascriptApi.DateTime.Parse(dateFrom), ewsJavascriptApi.DateTime.Parse(dateTo))
        ).then(function(params) {
          const ret = [];
          for (let k = 0; k < params.Items.length; k++) {
            if (params.Items[k].LegacyFreeBusyStatus != ewsJavascriptApi.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(ewsJavascriptApi.WellKnownFolderName.MsgFolderRoot, new ewsJavascriptApi.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 ewsJavascriptApi.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 ewsJavascriptApi.ExchangeService(this.exchangeVersion);
    exch1.Credentials = new ewsJavascriptApi.WebCredentials(this.credentials.username, this.credentials.password);
    exch1.Url = new ewsJavascriptApi.Uri(this.url);
    return exch1;
  }
}
const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  CalendarService: ExchangeCalendarService
}, Symbol.toStringTag, { value: "Module" }));
const bodySchema = z.z.object({
  username: z.z.string(),
  password: z.z.string(),
  url: z.z.string().url()
}).strict();
async function postHandler(req, res) {
  const body = bodySchema.parse(req.body);
  const user = await index$2.prisma.user.findFirstOrThrow({
    where: {
      id: req.session?.user?.id
    },
    select: {
      id: true,
      email: true
    }
  });
  const data = {
    type: "exchange2016_calendar",
    key: index$2.symmetricEncrypt(JSON.stringify(body), process.env.CALENDSO_ENCRYPTION_KEY || ""),
    userId: user.id,
    teamId: null,
    appId: "exchange2016-calendar",
    invalid: false,
    delegationCredentialId: null
  };
  try {
    const dav = new ExchangeCalendarService({
      id: 0,
      user: { email: user.email },
      ...data
    });
    await dav?.listCalendars();
    await index$2.prisma.credential.create({
      data
    });
  } catch (reason) {
    index$2.logger.error("Could not add this exchange account", reason);
    return res.status(500).json({ message: "Could not add this exchange account" });
  }
  return { url: getInstalledAppPath.getInstalledAppPath({ variant: "calendar", slug: "exchange2016-calendar" }) };
}
async function getHandler() {
  return { url: "/apps/exchange2016-calendar/setup" };
}
const add = defaultHandler.defaultHandler({
  GET: Promise.resolve({ default: defaultResponder.defaultResponder(getHandler) }),
  POST: Promise.resolve({ default: defaultResponder.defaultResponder(postHandler) })
});
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  add
}, Symbol.toStringTag, { value: "Module" }));
exports.metadata = _metadata.metadata;
exports.api = index;
exports.lib = index$1;
