"use strict";
const z = require("zod");
const getDailyAppKeys = require("./getDailyAppKeys-hu993QaD.cjs");
const dailyApiFetcher = require("./dailyApiFetcher-6ytV3FS6.cjs");
const index = require("./index-QSf6WJj0.cjs");
const indexBrowser = require("./index-browser-RtwB1hqI.cjs");
const dailyReturnTypeSchema = z.z.object({
  /** Long UID string ie: 987b5eb5-d116-4a4e-8e2c-14fcb5710966 */
  id: z.z.string(),
  /** Not a real name, just a random generated string ie: "ePR84NQ1bPigp79dDezz" */
  name: z.z.string(),
  api_created: z.z.boolean(),
  privacy: z.z.union([z.z.literal("private"), z.z.literal("public")]),
  /** https://api-demo.daily.co/ePR84NQ1bPigp79dDezz */
  url: z.z.string(),
  created_at: z.z.string(),
  config: z.z.object({
    /** Timestamps expressed in seconds, not in milliseconds */
    nbf: z.z.number().optional(),
    /** Timestamps expressed in seconds, not in milliseconds */
    exp: z.z.number(),
    enable_chat: z.z.boolean(),
    enable_knocking: z.z.boolean(),
    enable_prejoin_ui: z.z.boolean(),
    enable_transcription_storage: z.z.boolean().default(false),
    enable_pip_ui: z.z.boolean()
  })
});
const getTranscripts = z.z.object({
  total_count: z.z.number(),
  data: z.z.array(
    z.z.object({
      transcriptId: z.z.string(),
      domainId: z.z.string(),
      roomId: z.z.string(),
      mtgSessionId: z.z.string(),
      duration: z.z.number(),
      status: z.z.string()
    })
  )
});
const getBatchProcessJobs = z.z.object({
  total_count: z.z.number(),
  data: z.z.array(
    z.z.object({
      id: z.z.string(),
      preset: z.z.string(),
      status: z.z.string()
    })
  )
});
const getRooms = z.z.object({
  id: z.z.string()
}).passthrough();
const meetingTokenSchema = z.z.object({
  token: z.z.string()
}).passthrough();
z.z.object({
  room_name: z.z.string(),
  exp: z.z.number(),
  enable_recording_ui: z.z.boolean().optional(),
  user_id: z.z.number().nullable().optional()
}).passthrough();
const meetingParticipantSchema = z.z.object({
  user_id: z.z.string().nullable(),
  participant_id: z.z.string(),
  user_name: z.z.string().nullable(),
  join_time: z.z.number(),
  duration: z.z.number()
});
const meetingSessionSchema = z.z.object({
  id: z.z.string(),
  room: z.z.string(),
  start_time: z.z.number(),
  duration: z.z.number(),
  ongoing: z.z.boolean(),
  max_participants: z.z.number(),
  participants: z.z.array(meetingParticipantSchema)
});
const getMeetingInformationResponseSchema = z.z.object({
  data: z.z.array(meetingSessionSchema)
});
const REGION_CODES = [
  "af-south-1",
  "ap-northeast-2",
  "ap-southeast-1",
  "ap-southeast-2",
  "ap-south-1",
  "eu-central-1",
  "eu-west-2",
  "sa-east-1",
  "us-east-1",
  "us-west-2"
];
function getDailyVideoRegionFromEnv() {
  if (!process?.env?.DAILY_VIDEO_REGION)
    return;
  const isRoomGeo = (value) => REGION_CODES.includes(value);
  function assertIsDailyVideoRegion(value) {
    if (!isRoomGeo(value)) {
      throw new Error(`Invalid region code: ${value}. Must be one of: ${REGION_CODES.join(", ")}`);
    }
  }
  const region = process.env.DAILY_VIDEO_REGION;
  assertIsDailyVideoRegion(region);
  return region;
}
const isS3StorageEnabled = process.env.CAL_VIDEO_BUCKET_NAME && process.env.CAL_VIDEO_BUCKET_REGION && process.env.CAL_VIDEO_ASSUME_ROLE_ARN;
const FAKE_DAILY_CREDENTIAL = {
  id: 0,
  type: "daily_video",
  key: { apikey: process.env.DAILY_API_KEY },
  userId: 0,
  user: { email: "" },
  appId: "daily-video",
  invalid: false,
  teamId: null,
  delegatedToId: null,
  delegatedTo: null,
  delegationCredentialId: null
};
function postToDailyAPI(endpoint, body) {
  return dailyApiFetcher.fetcher(endpoint, {
    method: "POST",
    body: JSON.stringify(body)
  });
}
const getBatchProcessorJobAccessLink = (id) => {
  return dailyApiFetcher.fetcher(`/batch-processor/${id}/access-link`).then(indexBrowser.ZGetTranscriptAccessLink.parse);
};
const getRoomNameFromRecordingId = (recordingId) => {
  return dailyApiFetcher.fetcher(`/recordings/${recordingId}`).then(indexBrowser.recordingItemSchema.parse).then((res) => res.room_name);
};
async function processTranscriptsInBatches(transcriptIds) {
  const batchSize = 5;
  const batches = [];
  for (let i = 0; i < transcriptIds.length; i += batchSize) {
    batches.push(transcriptIds.slice(i, i + batchSize));
  }
  const allTranscriptsAccessLinks = [];
  for (const batch of batches) {
    const batchPromises = batch.map(
      (id) => dailyApiFetcher.fetcher(`/transcript/${id}/access-link`).then(z.z.object({ link: z.z.string() }).parse).then((res) => res.link)
    );
    const accessLinks = await Promise.all(batchPromises);
    allTranscriptsAccessLinks.push(...accessLinks);
  }
  return allTranscriptsAccessLinks;
}
const DailyVideoApiAdapter = () => {
  async function createOrUpdateMeeting(endpoint, event, region2) {
    if (!event.uid) {
      throw new Error("We need need the booking uid to create the Daily reference in DB");
    }
    const body = await translateEvent(event, region2);
    const dailyEvent = await postToDailyAPI(endpoint, body).then(dailyReturnTypeSchema.parse);
    const meetingToken = await postToDailyAPI("/meeting-tokens", {
      properties: {
        room_name: dailyEvent.name,
        exp: dailyEvent.config.exp,
        is_owner: true,
        enable_recording_ui: false
      }
    }).then(meetingTokenSchema.parse);
    return Promise.resolve({
      type: "daily_video",
      id: dailyEvent.name,
      password: meetingToken.token,
      url: dailyEvent.url
    });
  }
  const translateEvent = async (event, region2) => {
    const exp = Math.round(new Date(event.endTime).getTime() / 1e3) + 60 * 60 * 24 * 14;
    const { scale_plan: scalePlan } = await getDailyAppKeys.getDailyAppKeys();
    const hasTeamPlan = await index.prisma.membership.findFirst({
      where: {
        userId: event.organizer.id,
        team: {
          slug: {
            not: null
          }
        }
      }
    });
    const enableRecording = scalePlan === "true" && !!hasTeamPlan === true ? "cloud" : void 0;
    const isTranscriptionEnabled = !!hasTeamPlan;
    return {
      privacy: "public",
      properties: {
        ...region2 ? { geo: region2 } : {},
        enable_prejoin_ui: true,
        enable_knocking: true,
        enable_screenshare: true,
        enable_chat: true,
        enable_pip_ui: true,
        exp,
        enable_recording: enableRecording,
        ...!!enableRecording && isS3StorageEnabled && {
          recordings_bucket: {
            bucket_name: process.env.CAL_VIDEO_BUCKET_NAME,
            bucket_region: process.env.CAL_VIDEO_BUCKET_REGION,
            assume_role_arn: process.env.CAL_VIDEO_ASSUME_ROLE_ARN,
            allow_api_access: true,
            allow_streaming_from_bucket: true
          }
        },
        enable_transcription_storage: isTranscriptionEnabled,
        ...isTranscriptionEnabled && {
          permissions: {
            canAdmin: ["transcription"]
          }
        },
        ...isTranscriptionEnabled && isS3StorageEnabled && {
          transcription_bucket: {
            bucket_name: process.env.CAL_VIDEO_BUCKET_NAME,
            bucket_region: process.env.CAL_VIDEO_BUCKET_REGION,
            assume_role_arn: process.env.CAL_VIDEO_ASSUME_ROLE_ARN,
            allow_api_access: true
          }
        }
      }
    };
  };
  async function createInstantMeeting(endTime, region2) {
    const exp = Math.round(new Date(endTime).getTime() / 1e3) + 60 * 60;
    const { scale_plan: scalePlan } = await getDailyAppKeys.getDailyAppKeys();
    const isScalePlanTrue = scalePlan === "true";
    const enableRecording = isScalePlanTrue ? "cloud" : void 0;
    const body = {
      privacy: "public",
      properties: {
        ...region2 ? { geo: region2 } : {},
        enable_prejoin_ui: true,
        enable_knocking: true,
        enable_screenshare: true,
        enable_chat: true,
        enable_pip_ui: true,
        exp,
        enable_recording: enableRecording,
        ...!!enableRecording && isS3StorageEnabled && {
          recordings_bucket: {
            bucket_name: process.env.CAL_VIDEO_BUCKET_NAME,
            bucket_region: process.env.CAL_VIDEO_BUCKET_REGION,
            assume_role_arn: process.env.CAL_VIDEO_ASSUME_ROLE_ARN,
            allow_api_access: true,
            allow_streaming_from_bucket: true
          }
        },
        start_video_off: true,
        enable_transcription_storage: isScalePlanTrue,
        ...isScalePlanTrue && isS3StorageEnabled && {
          permissions: {
            canAdmin: ["transcription"]
          },
          transcription_bucket: {
            bucket_name: process.env.CAL_VIDEO_BUCKET_NAME,
            bucket_region: process.env.CAL_VIDEO_BUCKET_REGION,
            assume_role_arn: process.env.CAL_VIDEO_ASSUME_ROLE_ARN,
            allow_api_access: true
          }
        }
      }
    };
    const dailyEvent = await postToDailyAPI("/rooms", body).then(dailyReturnTypeSchema.parse);
    const meetingToken = await postToDailyAPI("/meeting-tokens", {
      properties: {
        room_name: dailyEvent.name,
        exp: dailyEvent.config.exp,
        is_owner: true,
        enable_recording_ui: false
      }
    }).then(meetingTokenSchema.parse);
    return Promise.resolve({
      type: "daily_video",
      id: dailyEvent.name,
      password: meetingToken.token,
      url: dailyEvent.url
    });
  }
  const region = getDailyVideoRegionFromEnv();
  return {
    /** Daily doesn't need to return busy times, so we return empty */
    getAvailability: () => {
      return Promise.resolve([]);
    },
    createMeeting: async (event) => createOrUpdateMeeting("/rooms", event, region),
    deleteMeeting: async (uid) => {
      await dailyApiFetcher.fetcher(`/rooms/${uid}`, { method: "DELETE" });
      return Promise.resolve();
    },
    updateMeeting: (bookingRef, event) => createOrUpdateMeeting(`/rooms/${bookingRef.uid}`, event, region),
    getRecordings: async (roomName) => {
      try {
        const res = await dailyApiFetcher.fetcher(`/recordings?room_name=${roomName}`).then(
          indexBrowser.getRecordingsResponseSchema.parse
        );
        return Promise.resolve(res);
      } catch (err) {
        throw new Error("Something went wrong! Unable to get recording");
      }
    },
    createInstantCalVideoRoom: (endTime) => createInstantMeeting(endTime, region),
    getRecordingDownloadLink: async (recordingId) => {
      try {
        const res = await dailyApiFetcher.fetcher(`/recordings/${recordingId}/access-link?valid_for_secs=43200`).then(
          indexBrowser.getAccessLinkResponseSchema.parse
        );
        return Promise.resolve(res);
      } catch (err) {
        console.log("err", err);
        throw new Error("Something went wrong! Unable to get recording access link");
      }
    },
    getAllTranscriptsAccessLinkFromRoomName: async (roomName) => {
      try {
        const res = await dailyApiFetcher.fetcher(`/rooms/${roomName}`).then(getRooms.parse);
        const roomId = res.id;
        const allTranscripts = await dailyApiFetcher.fetcher(`/transcript?roomId=${roomId}`).then(getTranscripts.parse);
        if (!allTranscripts.data.length)
          return [];
        const allTranscriptsIds = allTranscripts.data.map((transcript) => transcript.transcriptId);
        const allTranscriptsAccessLink = await processTranscriptsInBatches(allTranscriptsIds);
        const accessLinks = await Promise.all(allTranscriptsAccessLink);
        return Promise.resolve(accessLinks);
      } catch (err) {
        console.log("err", err);
        throw new Error("Something went wrong! Unable to get transcription access link");
      }
    },
    getAllTranscriptsAccessLinkFromMeetingId: async (meetingId) => {
      try {
        const allTranscripts = await dailyApiFetcher.fetcher(`/transcript?mtgSessionId=${meetingId}`).then(
          getTranscripts.parse
        );
        if (!allTranscripts.data.length)
          return [];
        const allTranscriptsIds = allTranscripts.data.map((transcript) => transcript.transcriptId);
        const allTranscriptsAccessLink = await processTranscriptsInBatches(allTranscriptsIds);
        const accessLinks = await Promise.all(allTranscriptsAccessLink);
        return Promise.resolve(accessLinks);
      } catch (err) {
        console.log("err", err);
        throw new Error("Something went wrong! Unable to get transcription access link");
      }
    },
    submitBatchProcessorJob: async (body) => {
      try {
        const batchProcessorJob = await postToDailyAPI("/batch-processor", body).then(
          indexBrowser.ZSubmitBatchProcessorJobRes.parse
        );
        return batchProcessorJob;
      } catch (err) {
        console.log("err", err);
        throw new Error("Something went wrong! Unable to submit batch processor job");
      }
    },
    getTranscriptsAccessLinkFromRecordingId: async (recordingId) => {
      try {
        const batchProcessorJobs = await dailyApiFetcher.fetcher(`/batch-processor?recordingId=${recordingId}`).then(
          getBatchProcessJobs.parse
        );
        if (!batchProcessorJobs.data.length) {
          return { message: `No Batch processor jobs found for recording id ${recordingId}` };
        }
        const transcriptJobId = batchProcessorJobs.data.filter(
          (job) => job.preset === "transcript" && job.status === "finished"
        )?.[0]?.id;
        if (!transcriptJobId)
          return [];
        const accessLinkRes = await getBatchProcessorJobAccessLink(transcriptJobId);
        return accessLinkRes.transcription;
      } catch (err) {
        console.log("err", err);
        throw new Error("Something went wrong! can't get transcripts");
      }
    },
    checkIfRoomNameMatchesInRecording: async (roomName, recordingId) => {
      try {
        const recording = await dailyApiFetcher.fetcher(`/recordings/${recordingId}`).then(indexBrowser.recordingItemSchema.parse);
        return recording.room_name === roomName;
      } catch (err) {
        console.error("err", err);
        throw new Error(`Something went wrong! Unable to checkIfRoomNameMatchesInRecording. ${err}`);
      }
    },
    getMeetingInformation: async (roomName) => {
      try {
        const res = await dailyApiFetcher.fetcher(`/meetings?room=${encodeURIComponent(roomName)}`).then(
          getMeetingInformationResponseSchema.parse
        );
        return res;
      } catch (err) {
        console.error("err", err);
        throw new Error("Something went wrong! Unable to get meeting information");
      }
    }
  };
};
exports.DailyVideoApiAdapter = DailyVideoApiAdapter;
exports.FAKE_DAILY_CREDENTIAL = FAKE_DAILY_CREDENTIAL;
exports.getBatchProcessorJobAccessLink = getBatchProcessorJobAccessLink;
exports.getRoomNameFromRecordingId = getRoomNameFromRecordingId;
