import type { FrameAdapter } from "./types";

export interface GSAPTimelineLike {
  // Base timeline span excluding repeats.
  duration: () => number;
  // Full span including repeats/yoyo when available.
  totalDuration?: () => number;
  seek: (timeInSeconds: number, suppressEvents?: boolean) => unknown;
  pause?: () => unknown;
}

export interface CreateGSAPFrameAdapterOptions {
  id?: string;
  fps: number;
  timeline: GSAPTimelineLike;
}

export function createGSAPFrameAdapter(options: CreateGSAPFrameAdapterOptions): FrameAdapter {
  const { fps, timeline } = options;
  const adapterId = options.id ?? "gsap";

  const getDurationSeconds = (): number => {
    const totalDuration =
      typeof timeline.totalDuration === "function" ? timeline.totalDuration() : timeline.duration();
    return Number.isFinite(totalDuration) && totalDuration > 0 ? totalDuration : 0;
  };

  return {
    id: adapterId,
    init: () => {
      timeline.pause?.();
    },
    getDurationFrames: () => {
      const durationSeconds = getDurationSeconds();
      return Math.max(0, Math.ceil(durationSeconds * fps));
    },
    seekFrame: (frame: number) => {
      const clampedFrame = Number.isFinite(frame) ? Math.max(0, frame) : 0;
      const targetSeconds = clampedFrame / fps;
      timeline.pause?.();
      timeline.seek(targetSeconds, false);
    },
  };
}
