"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const querystring = require("querystring");
const index$2 = require("./user-v6mfWQ2d.cjs");
const defaultHandler = require("./defaultHandler-MSjhitc-.cjs");
const defaultResponder = require("./defaultResponder-QWPOXt61.cjs");
const getAppKeysFromSlug = require("./getAppKeysFromSlug-W8EkKxxV.cjs");
const encodeOAuthState = require("./encodeOAuthState-VBfelnxQ.cjs");
const getSafeRedirectUrl = require("./getSafeRedirectUrl-ErDpjTNV.cjs");
const getInstalledAppPath = require("./getInstalledAppPath-3c7mqtrk.cjs");
const createOAuthAppCredential = require("./createOAuthAppCredential-ccvXpWYY.cjs");
const decodeOAuthState = require("./decodeOAuthState--7fljpCf.cjs");
const uuid = require("uuid");
const z = require("zod");
const getParsedAppKeysFromSlug = require("./getParsedAppKeysFromSlug-IAcyRjQk.cjs");
const markTokenAsExpired = require("./markTokenAsExpired-yzGdqjc-.cjs");
const oAuthManagerHelper = require("./oAuthManagerHelper-oCcY9kRG.cjs");
const CalEventParser = require("./CalEventParser-60bHdlQO.cjs");
async function handler$1(req) {
  const user = req?.session?.user;
  if (!user) {
    return { status: 401, body: { error: "Unauthorized" } };
  }
  const appKeys = await getAppKeysFromSlug.getAppKeysFromSlug("nextcloudtalk");
  const hostUrl = appKeys.nextcloudTalkHost;
  const client_id = appKeys.nextcloudTalkClientId;
  const client_secret = appKeys.nextcloudTalkClientSecret;
  const state = encodeOAuthState.encodeOAuthState(req);
  const params = {
    response_type: "code",
    client_id,
    client_secret,
    redirect_uri: `${index$2.WEBAPP_URL}/api/integrations/nextcloudtalk/callback`,
    state
  };
  const query = querystring.stringify(params);
  const url = `${hostUrl}/index.php/apps/oauth2/authorize?${query}`;
  return { url };
}
const add = defaultHandler.defaultHandler({
  GET: Promise.resolve({ default: defaultResponder.defaultResponder(handler$1) })
});
async function handler(req, res) {
  const state = decodeOAuthState.decodeOAuthState(req);
  const userId = req.session?.user.id;
  if (!userId) {
    return res.status(404).json({ message: "No user found" });
  }
  const { code } = req.query;
  const appKeys = await getAppKeysFromSlug.getAppKeysFromSlug("nextcloudtalk");
  const hostUrl = appKeys.nextcloudTalkHost;
  const client_id = appKeys.nextcloudTalkClientId;
  const client_secret = appKeys.nextcloudTalkClientSecret;
  const result = await fetch(`${hostUrl}/index.php/apps/oauth2/api/v1/token`, {
    method: "POST",
    body: JSON.stringify({
      grant_type: "authorization_code",
      code,
      client_id,
      client_secret,
      redirect_uri: `${index$2.WEBAPP_URL}/api/integrations/nextcloudtalk/callback`
    }),
    headers: {
      "Content-Type": "application/json"
    }
  });
  if (result.status !== 200) {
    let errorMessage = "Something is wrong with the Nextcloud API";
    try {
      const responseBody2 = await result.json();
      errorMessage = responseBody2.error;
    } catch (e) {
    }
    res.status(400).json({ message: errorMessage });
    return;
  }
  const responseBody = await result.json();
  if (responseBody.error) {
    res.status(400).json({ message: responseBody.error });
    return;
  }
  await index$2.prisma.credential.deleteMany({
    where: {
      type: "nextcloudtalk_video",
      userId,
      appId: "nextcloudtalk"
    }
  });
  await createOAuthAppCredential.createOAuthAppCredential({ appId: "nextcloudtalk", type: "nextcloudtalk_video" }, responseBody, req);
  res.redirect(
    getSafeRedirectUrl.getSafeRedirectUrl(state?.returnTo) ?? getInstalledAppPath.getInstalledAppPath({ variant: "conferencing", slug: "nextcloudtalk" })
  );
}
const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  add,
  callback: handler
}, Symbol.toStringTag, { value: "Module" }));
const nextcloudEventResultSchema = z.z.object({
  ocs: z.z.object({
    meta: z.z.object({
      status: z.z.string(),
      statuscode: z.z.number(),
      message: z.z.string()
    }),
    data: z.z.object({
      token: z.z.string()
    })
  })
});
const NextcloudTalkVideoApiAdapter = (credential) => {
  const tokenResponse = oAuthManagerHelper.oAuthManagerHelper.getTokenObjectFromCredential(credential);
  const clientCredentials = getParsedAppKeysFromSlug.getParsedAppKeysFromSlug(CalEventParser.config$1.slug, index$2.appKeysSchema$2);
  const fetchNextcloudApi = async (endpoint, options) => {
    const auth = new markTokenAsExpired.OAuthManager({
      credentialSyncVariables: oAuthManagerHelper.oAuthManagerHelper.credentialSyncVariables,
      resourceOwner: {
        type: "user",
        id: credential.userId
      },
      appSlug: CalEventParser.config$1.slug,
      currentTokenObject: tokenResponse,
      fetchNewTokenObject: async ({ refreshToken }) => {
        const { nextcloudTalkClientId, nextcloudTalkClientSecret, nextcloudTalkHost: nextcloudTalkHost2 } = await clientCredentials;
        if (!refreshToken) {
          return null;
        }
        const params = {
          client_id: nextcloudTalkClientId,
          client_secret: nextcloudTalkClientSecret,
          refresh_token: refreshToken,
          grant_type: "refresh_token"
        };
        const query = querystring.stringify(params);
        return fetch(`${nextcloudTalkHost2}/index.php/apps/oauth2/api/v1/token?${query}`, {
          method: "POST",
          headers: {
            Accept: "application/json",
            "Content-Type": "application/json"
          },
          body: new URLSearchParams({})
        });
      },
      isTokenObjectUnusable: async function(response) {
        const myLog = index$2.logger.getSubLogger({ prefix: ["nextcloudtalkvideo:isTokenObjectUnusable"] });
        myLog.debug(index$2.safeStringify({ status: response.status, ok: response.ok }));
        if (!response.ok || response.status < 200 && response.status >= 300) {
          const responseBody = await response.json();
          myLog.debug(index$2.safeStringify({ responseBody }));
          if (responseBody.error === "invalid_grant") {
            return { reason: responseBody.error };
          }
        }
        return null;
      },
      isAccessTokenUnusable: async function(response) {
        const myLog = index$2.logger.getSubLogger({ prefix: ["nextcloudtalkvideo:isAccessTokenUnusable"] });
        myLog.debug(index$2.safeStringify({ status: response.status, ok: response.ok }));
        if (!response.ok || response.status < 200 && response.status >= 300) {
          const responseBody = await response.json();
          myLog.debug(index$2.safeStringify({ responseBody }));
          if (responseBody.code === 124) {
            return { reason: responseBody.message ?? "" };
          }
        }
        return null;
      },
      invalidateTokenObject: () => markTokenAsExpired.invalidateCredential(credential.id),
      expireAccessToken: () => markTokenAsExpired.markTokenAsExpired(credential),
      updateTokenObject: async (newTokenObject) => {
        await index$2.prisma.credential.update({
          where: {
            id: credential.id
          },
          data: {
            key: newTokenObject
          }
        });
      }
    });
    const { nextcloudTalkHost } = await clientCredentials;
    const { json } = await auth.request({
      url: `${nextcloudTalkHost}/${endpoint}`,
      options: {
        method: "GET",
        ...options,
        headers: {
          ...options?.headers
        }
      }
    });
    return json;
  };
  return {
    getAvailability: () => {
      return Promise.resolve([]);
    },
    createMeeting: async (eventData) => {
      const appKeys = await getAppKeysFromSlug.getAppKeysFromSlug(CalEventParser.config$1.slug);
      const meetingPattern = appKeys.nextcloudTalkPattern || "{uuid}";
      const hostUrl = appKeys.nextcloudTalkHost;
      const meetingID = meetingPattern.replaceAll("{uuid}", uuid.v4()).replaceAll("{Title}", eventData.title).replaceAll("{Event Type Title}", eventData.type).replaceAll("{Scheduler}", eventData.attendees.map((a) => a.name).join("-")).replaceAll("{Organizer}", eventData.organizer.name).replaceAll("{Location}", eventData.location || "").replaceAll("{Team}", eventData.team?.name || "").replaceAll(" ", "-");
      try {
        const response = await fetchNextcloudApi(`ocs/v2.php/apps/spreed/api/v4/room`, {
          method: "POST",
          headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
            "OCS-APIRequest": "true"
          },
          body: JSON.stringify({
            roomType: 3,
            roomName: `${meetingID}`
          })
        });
        const result = nextcloudEventResultSchema.parse(response);
        if (result.ocs && result.ocs.data) {
          return {
            type: CalEventParser.config$1.type,
            id: result.ocs.data.token,
            password: "",
            url: `${hostUrl}/call/${result.ocs.data.token}`
          };
        }
        throw new Error(`Failed to create meeting. Response is ${JSON.stringify(result)}`);
      } catch (err) {
        console.error(err);
        throw new Error("Unexpected error");
      }
    },
    deleteMeeting: async (uid) => {
      try {
        const response = await fetchNextcloudApi(`ocs/v2.php/apps/spreed/api/v4/room/${uid}`, {
          method: "DELETE",
          headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
            "OCS-APIRequest": "true"
          }
        });
        const result = nextcloudEventResultSchema.parse(response);
        if (result.ocs && result.ocs.meta && result.ocs.meta.status === "ok") {
          return Promise.resolve();
        }
        throw new Error(`Failed to delete meeting. Response is ${JSON.stringify(result)}`);
      } catch (err) {
        return Promise.reject(new Error("Failed to delete meeting"));
      }
    },
    updateMeeting: (bookingRef) => {
      return Promise.resolve({
        type: CalEventParser.config$1.type,
        id: bookingRef.meetingId,
        password: bookingRef.meetingPassword,
        url: bookingRef.meetingUrl
      });
    }
  };
};
const NextcloudTalkVideoApiAdapter$1 = NextcloudTalkVideoApiAdapter;
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  VideoApiAdapter: NextcloudTalkVideoApiAdapter$1
}, Symbol.toStringTag, { value: "Module" }));
exports.api = index$1;
exports.lib = index;
