import { deduplicateWarpMarkers } from '@suno/studiokit/projectState/warpMarkersRegistry';
import { getWarpBeatsFromSeconds } from '@suno/studiokit/warpUtils';
import { v4 as uuidv4 } from 'uuid';

import { Clip } from '@/state/clipStore';
import { getClipTitle } from '@/utils/clip';

import { pickRandomColor } from '../edit2025/getSections';
import getTimingFromDownbeats from '../edit2025/getTimingFromDownbeats';
import describeClip from './describeClipTiming';
import { StudioClip } from './types';

// note: consumer should set endBeats
export default function createPartiallyKnownTimingStudioClipSync(
  clip: Clip,
  knownDownbeats: [number, number][],
  includeContextWindow: boolean = false
): StudioClip {
  const { contentStartSeconds, contentDurationSeconds } = describeClip(clip);
  const finalContentStartSeconds = includeContextWindow
    ? 0
    : contentStartSeconds;

  const finalContentDurationSeconds = includeContextWindow
    ? (clip.metadata.duration ?? null)
    : (contentDurationSeconds ?? clip.metadata.duration);

  let expectedDurationBeats = 8 * 60 * 2; // 8 minutes at 120bpm (2bps);

  const bps = clip.metadata.avg_bpm
    ? clip.metadata.avg_bpm / 60
    : getTimingFromDownbeats(knownDownbeats).bps;

  if (finalContentDurationSeconds && bps) {
    expectedDurationBeats = finalContentDurationSeconds * bps;
  }

  const firstDownbeatIndex = knownDownbeats
    ? Math.max(
        knownDownbeats.findIndex((b) => b[1] === 1),
        0
      )
    : 0;

  const markers: Record<number, number> = {};
  if (knownDownbeats) {
    knownDownbeats.forEach(([second], index) => {
      markers[second] = index - firstDownbeatIndex;
    });
  } else {
    markers[0] = 0;
  }

  const warp = {
    enabled: true,
    markers: deduplicateWarpMarkers(markers),
    awaitingAnalysis: true,
    speed: 1,
  };

  const contentStartBeats = getWarpBeatsFromSeconds(
    warp,
    finalContentStartSeconds
  );

  return {
    streaming: clip.status !== 'complete',
    id: uuidv4(),
    clipId: clip.id,
    uploadId: null,
    mute: false,
    name: getClipTitle(clip as Clip) || 'New Clip',
    color: pickRandomColor(clip.id),
    startBeats: 0,
    endBeats: expectedDurationBeats,
    readStartBeats: contentStartBeats,
    fadeInBeats: 0,
    fadeOutBeats: 0,
    transposition: 0,
    amplitude: 1,
    loop: {
      enabled: false,
      startBeats: contentStartBeats,
      endBeats: 999,
    },
    warp,
  };
}
