import { deduplicateWarpMarkers } from '@suno/studiokit/projectState/warpMarkersRegistry';
import { useQuery } from '@tanstack/react-query';

import { useStores } from '@/app/(root)/AppProviders';
import useClip, { fetchClip } from '@/hooks/useClip';
import { ClipsStore } from '@/state/clipStore';

import { cachedFetchAndPollDownbeats } from '../edit2025/queryHooks/useEditTimingQuery';
import createKnownTimingStudioClipSync from './createKnownTimingStudioClipSync';
import createStudioClipSync from './createStudioClipSync';
import createUnknownTimingStudioClipSync from './createUnknownTimingStudioClipSync';
import { ClipArrangementPackage, StudioClip } from './types';
import { fetchClipAlignmentSpec } from './useAlignedClips';

export const fetchClipArrangementPackage = async (
  clipsStore: ClipsStore,
  clipId: string,
  includeContextWindow: boolean = false,
  expectedDurationSeconds: number = 8 * 60
): Promise<ClipArrangementPackage> => {
  const clip = await fetchClip(clipsStore, clipId, false);
  const downbeats =
    clip.metadata.duration == null
      ? null
      : await cachedFetchAndPollDownbeats(clipsStore.apiClient, clipId);

  let studioClip: StudioClip;
  if (includeContextWindow) {
    studioClip = createStudioClipSync(
      clip,
      downbeats,
      expectedDurationSeconds
    ).clip;
  } else if (downbeats) {
    studioClip = createKnownTimingStudioClipSync(
      clip,
      downbeats,
      expectedDurationSeconds
    );
  } else {
    studioClip = createUnknownTimingStudioClipSync(clip);
  }

  const alignmentSpec =
    includeContextWindow || clip.metadata.duration == null
      ? {}
      : await fetchClipAlignmentSpec(clipsStore.apiClient, clip);

  return {
    clip,
    studioClip,
    alignmentSpec,
  };
};

export const getClipArrangementPackageQueryKey = (
  clipId: string,
  includeContextWindow: boolean = false
) => {
  return [
    'sep-21-2025',
    'clip-arrangement-package',
    clipId,
    includeContextWindow,
  ];
};

export const useClipArrangementPackageQuery = (
  clipId: string | null,
  enabled: boolean = true,
  includeContextWindow: boolean = false
) => {
  const { clips: clipsStore } = useStores();
  const { clip } = useClip(clipId ?? undefined);
  return useQuery<ClipArrangementPackage, Error>({
    enabled: clip?.status === 'complete' && enabled,
    queryKey: getClipArrangementPackageQueryKey(
      clipId ?? 'MISSING_CLIP_ID',
      includeContextWindow
    ),
    queryFn: () =>
      fetchClipArrangementPackage(clipsStore, clipId!, includeContextWindow),
    staleTime: ({ state }) => {
      return state?.data?.clip.metadata.duration ? Infinity : 0;
    },
    select: (data) => {
      // Handle cached data that might have non-deduplicated markers
      const needsDeduplication = !Object.isFrozen(data.studioClip.warp.markers);
      if (needsDeduplication) {
        return {
          ...data,
          studioClip: {
            ...data.studioClip,
            warp: {
              ...data.studioClip.warp,
              markers: deduplicateWarpMarkers(data.studioClip.warp.markers),
            },
          },
        };
      }

      return data;
    },
  });
};
