"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const querystring = require("querystring");
const index$2 = require("./user-v6mfWQ2d.cjs");
const getAppKeysFromSlug = require("./getAppKeysFromSlug-W8EkKxxV.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 CalEventParser = require("./CalEventParser-60bHdlQO.cjs");
const httpError = require("./http-error-mkY8Ke7V.cjs");
async function handler$1(req, res) {
  if (req.method === "GET") {
    await index$2.prisma.user.findFirstOrThrow({
      where: {
        id: req.session?.user?.id
      },
      select: {
        id: true
      }
    });
    let clientId = "";
    let baseUrl = "";
    const appKeys = await getAppKeysFromSlug.getAppKeysFromSlug("tandem");
    if (typeof appKeys.client_id === "string")
      clientId = appKeys.client_id;
    if (typeof appKeys.base_url === "string")
      baseUrl = appKeys.base_url;
    if (!clientId)
      return res.status(400).json({ message: "Tandem client_id missing." });
    if (!baseUrl)
      return res.status(400).json({ message: "Tandem base_url missing." });
    const redirect_uri = encodeURI(`${index$2.WEBAPP_URL}/api/integrations/tandemvideo/callback`);
    const params = {
      client_id: clientId,
      redirect_uri
    };
    const query = querystring.stringify(params);
    const url = `${baseUrl}/oauth/approval?${query}`;
    res.status(200).json({ url });
  }
}
async function handler(req, res) {
  if (!req.query.code) {
    res.status(401).json({ message: "Missing code" });
    return;
  }
  const code = req.query.code;
  const state = decodeOAuthState.decodeOAuthState(req);
  let clientId = "";
  let clientSecret = "";
  let baseUrl = "https://tandem.chat";
  const appKeys = await getAppKeysFromSlug.getAppKeysFromSlug("tandem");
  if (typeof appKeys.client_id === "string")
    clientId = appKeys.client_id;
  if (typeof appKeys.client_secret === "string")
    clientSecret = appKeys.client_secret;
  if (typeof appKeys.base_url === "string")
    baseUrl = appKeys.base_url;
  if (!clientId)
    return res.status(400).json({ message: "Tandem client_id missing." });
  if (!clientSecret)
    return res.status(400).json({ message: "Tandem client_secret missing." });
  if (!baseUrl)
    return res.status(400).json({ message: "Tandem base_url missing." });
  const result = await fetch(`${baseUrl}/api/v1/oauth/v2/token`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ code, client_id: clientId, client_secret: clientSecret })
  });
  const responseBody = await result.json();
  const userId = req.session?.user.id;
  if (!userId) {
    return res.status(404).json({ message: "No user found" });
  }
  const existingCredentialTandemVideo = await index$2.prisma.credential.findMany({
    select: {
      id: true
    },
    where: {
      type: "tandem_video",
      userId: req.session?.user.id,
      appId: "tandem"
    }
  });
  const credentialIdsToDelete = existingCredentialTandemVideo.map((item) => item.id);
  if (credentialIdsToDelete.length > 0) {
    await index$2.prisma.credential.deleteMany({ where: { id: { in: credentialIdsToDelete }, userId } });
  }
  if (result.ok) {
    responseBody.expiry_date = Math.round(Date.now() + responseBody.expires_in * 1e3);
    delete responseBody.expires_in;
    await createOAuthAppCredential.createOAuthAppCredential({ appId: "tandem", type: "tandem_video" }, responseBody, req);
    res.redirect(
      getSafeRedirectUrl.getSafeRedirectUrl(state?.returnTo) ?? getInstalledAppPath.getInstalledAppPath({ variant: "conferencing", slug: "tandem" })
    );
  }
}
const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  add: handler$1,
  callback: handler
}, Symbol.toStringTag, { value: "Module" }));
const loadConfiguration = async () => {
  const appKeys = await getAppKeysFromSlug.getAppKeysFromSlug("tandem");
  let clientId = "";
  let clientSecret = "";
  let baseUrl = "";
  if (typeof appKeys.client_id === "string")
    clientId = appKeys.client_id;
  if (typeof appKeys.client_secret === "string")
    clientSecret = appKeys.client_secret;
  if (typeof appKeys.base_url === "string")
    baseUrl = appKeys.base_url;
  if (!clientId)
    throw new httpError.HttpError({ statusCode: 400, message: "Tandem client_id missing." });
  if (!clientSecret)
    throw new httpError.HttpError({ statusCode: 400, message: "Tandem client_secret missing." });
  if (!baseUrl)
    throw new httpError.HttpError({ statusCode: 400, message: "Tandem base_url missing." });
  return {
    clientId,
    clientSecret,
    baseUrl
  };
};
const tandemAuth = async (credential) => {
  const configuration = await loadConfiguration();
  const credentialKey = credential.key;
  const isTokenValid = (token) => token && token.access_token && token.expiry_date < Date.now();
  const refreshAccessToken = async (refreshToken) => {
    const result = await fetch(`${configuration.baseUrl}/api/v1/oauth/v2/token`, {
      method: "POST",
      body: new URLSearchParams({
        client_id: configuration.clientId,
        client_secret: configuration.clientSecret,
        code: refreshToken
      })
    });
    const responseBody = await CalEventParser.handleErrorsJson(result);
    responseBody.expiry_date = Math.round(Date.now() + (responseBody.expires_in || 0) * 1e3);
    delete responseBody.expires_in;
    await index$2.prisma.credential.update({
      where: {
        id: credential.id
      },
      data: {
        key: responseBody
      }
    });
    credentialKey.expiry_date = responseBody.expiry_date;
    credentialKey.access_token = responseBody.access_token;
    credentialKey.refresh_token = responseBody.refresh_token;
    return credentialKey.access_token;
  };
  return {
    getToken: () => !isTokenValid(credentialKey) ? Promise.resolve(credentialKey.access_token) : refreshAccessToken(credentialKey.refresh_token)
  };
};
const TandemVideoApiAdapter = (credential) => {
  const auth = tandemAuth(credential);
  const _parseDate = (date) => {
    return Date.parse(date) / 1e3;
  };
  const _translateEvent = (event, param) => {
    return JSON.stringify({
      [param]: {
        title: event.title,
        starts_at: _parseDate(event.startTime),
        ends_at: _parseDate(event.endTime),
        description: event.description || "",
        conference_solution: "tandem",
        type: 3
      }
    });
  };
  const _translateResult = (result) => {
    return {
      type: "tandem_video",
      id: result.data.id,
      password: "",
      url: result.data.event_link
    };
  };
  return {
    /** Tandem doesn't need to return busy times, so we return empty */
    getAvailability: () => {
      return Promise.resolve([]);
    },
    createMeeting: async (event) => {
      const accessToken = await (await auth).getToken();
      const configuration = await loadConfiguration();
      const result = await fetch(`${configuration.baseUrl}/api/v1/meetings`, {
        method: "POST",
        headers: {
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": "application/json"
        },
        body: _translateEvent(event, "meeting")
      });
      const responseBody = await CalEventParser.handleErrorsJson(result);
      return Promise.resolve(_translateResult(responseBody));
    },
    deleteMeeting: async (uid) => {
      const accessToken = await (await auth).getToken();
      const configuration = await loadConfiguration();
      await fetch(`${configuration.baseUrl}/api/v1/meetings/${uid}`, {
        method: "DELETE",
        headers: {
          Authorization: `Bearer ${accessToken}`
        }
      }).then(CalEventParser.handleErrorsRaw);
      return Promise.resolve();
    },
    updateMeeting: async (bookingRef, event) => {
      const accessToken = await (await auth).getToken();
      const configuration = await loadConfiguration();
      const result = await fetch(`${configuration.baseUrl}/api/v1/meetings/${bookingRef.meetingId}`, {
        method: "PUT",
        headers: {
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": "application/json"
        },
        body: _translateEvent(event, "updates")
      });
      const responseBody = await CalEventParser.handleErrorsJson(result);
      return Promise.resolve(_translateResult(responseBody));
    }
  };
};
const TandemVideoApiAdapter$1 = TandemVideoApiAdapter;
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  VideoApiAdapter: TandemVideoApiAdapter$1
}, Symbol.toStringTag, { value: "Module" }));
exports.metadata = CalEventParser.metadata$3;
exports.api = index$1;
exports.lib = index;
