import { Task } from "@lit/task";
import { EFMedia } from "../../EFMedia";
import { BufferedSeekingInput } from "../BufferedSeekingInput";
import type { InputTask } from "../shared/MediaTaskUtils";

export const makeAudioInputTask = (host: EFMedia): InputTask => {
  return new Task<
    readonly [ArrayBuffer | undefined, ArrayBuffer | undefined],
    BufferedSeekingInput
  >(host, {
    args: () =>
      [
        host.audioInitSegmentFetchTask.value,
        host.audioSegmentFetchTask.value,
      ] as const,
    onError: (error) => {
      console.error("audioInputTask error", error);
    },
    onComplete: (_value) => {},
    task: async (_, { signal }) => {
      const initSegment = await host.audioInitSegmentFetchTask.taskComplete;
      signal.throwIfAborted(); // Abort if a new seek started
      const segment = await host.audioSegmentFetchTask.taskComplete;
      signal.throwIfAborted(); // Abort if a new seek started
      if (!initSegment || !segment) {
        throw new Error("Init segment or segment is not available");
      }

      // Get startTimeOffsetMs from the audio rendition if available
      const mediaEngine = await host.mediaEngineTask.taskComplete;
      const audioRendition = mediaEngine?.audioRendition;
      const startTimeOffsetMs = audioRendition?.startTimeOffsetMs;

      const arrayBuffer = await new Blob([initSegment, segment]).arrayBuffer();
      signal.throwIfAborted(); // Abort if a new seek started
      return new BufferedSeekingInput(arrayBuffer, {
        videoBufferSize: EFMedia.VIDEO_SAMPLE_BUFFER_SIZE,
        audioBufferSize: EFMedia.AUDIO_SAMPLE_BUFFER_SIZE,
        startTimeOffsetMs,
      });
    },
  });
};
