/** Read the duration (seconds) of a video file. */
export async function videoDuration(file: File): Promise<number | null> {
  const url = URL.createObjectURL(file);
  const video = document.createElement("video");
  video.src = url;
  video.preload = "metadata";
  try {
    return await new Promise<number | null>((resolve) => {
      video.onloadedmetadata = () => resolve(Number.isFinite(video.duration) ? video.duration : null);
      video.onerror = () => resolve(null);
    });
  } finally {
    URL.revokeObjectURL(url);
  }
}

/** Extract evenly spaced key frames from a video file, as JPEG data URLs. */
export async function extractKeyFrames(file: File, count = 5, maxWidth = 720): Promise<string[]> {
  const url = URL.createObjectURL(file);
  const video = document.createElement("video");
  video.src = url;
  video.muted = true;
  video.playsInline = true;
  video.preload = "auto";

  try {
    await new Promise<void>((resolve, reject) => {
      video.onloadedmetadata = () => resolve();
      video.onerror = () => reject(new Error("Could not read that video."));
    });

    const duration = Number.isFinite(video.duration) && video.duration > 0 ? video.duration : 1;
    const scale = Math.min(1, maxWidth / (video.videoWidth || maxWidth));
    const canvas = document.createElement("canvas");
    canvas.width = Math.round((video.videoWidth || maxWidth) * scale);
    canvas.height = Math.round((video.videoHeight || maxWidth) * scale);
    const ctx = canvas.getContext("2d");
    if (!ctx) throw new Error("Could not process that video.");

    const frames: string[] = [];
    for (let i = 0; i < count; i += 1) {
      const time = (duration * (i + 0.5)) / count;
      await new Promise<void>((resolve, reject) => {
        const onSeeked = () => {
          video.removeEventListener("seeked", onSeeked);
          resolve();
        };
        video.addEventListener("seeked", onSeeked);
        video.onerror = () => reject(new Error("Could not read that video."));
        video.currentTime = Math.min(time, Math.max(0, duration - 0.05));
      });
      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
      frames.push(canvas.toDataURL("image/jpeg", 0.72));
    }
    return frames;
  } finally {
    URL.revokeObjectURL(url);
  }
}