import { v } from "convex/values";
import { api, internal } from "./_generated/api";
import { internalAction } from "./_generated/server";

export const checkRadio = internalAction({
  args: {
    roomId: v.id("rooms"),
  },
  handler: async (ctx, args) => {
    const room = await ctx.runQuery(api.rooms.getById, {
      roomId: args.roomId,
    });

    const radioState = room?.radioState;
    if (!radioState) {
      return;
    }

    if (radioState.queue.length === 0) {
      // No clips are enqueued.
      return;
    }

    // Load recent status of all queue clips.
    const clips = await ctx
      .runQuery(internal.clips.getByIds, {
        clipIds: radioState.queue.map((q: any) => q.clipId),
      })
      .then((clips) => clips.filter((clip) => clip !== null));

    const clip = clips[0];

    const newClipsById = Object.fromEntries(
      clips.map((clip) => [clip!._id, clip])
    );

    let newQueue = [];

    let nextPlayTs: number | null = new Date().getTime() + 10;

    for (const queueEntry of radioState.queue) {
      const newClip = newClipsById[queueEntry.clipId];
      if (!newClip) {
        return;
      }

      // If we know the duration, we can use that to schedule the next clip.

      if (
        !queueEntry.playTs &&
        (newClip.status === "streaming" || newClip.status === "complete")
      ) {
        newQueue.push({
          clipId: queueEntry.clipId,
          audio_url: queueEntry.audio_url || newClip.audio_url,

          status: "ready",
          playTs: nextPlayTs,
          expireTs:
            newClip.metadata?.duration && nextPlayTs
              ? nextPlayTs + newClip.metadata.duration * 1000
              : null,
          queueTs: queueEntry.queueTs,
        });
      } else {
        newQueue.push(queueEntry);
      }

      if (newClip.metadata?.duration && nextPlayTs) {
        nextPlayTs += newClip.metadata.duration * 1000 - 200;
      } else {
        nextPlayTs = null;
      }
    }

    console.log("here", clips);

    await ctx.runMutation(internal.rooms.updateRoomRadioState, {
      roomId: args.roomId,
      radioState: {
        ...radioState,
        queue: newQueue,
      },
    });

    const currentClipIndex =
      newQueue
        .map((clip, index) => ({ clip, index }))
        .reverse()
        .find(({ clip }) => clip.playTs && clip.playTs < new Date().getTime())
        ?.index ?? -1;
  },
});
