import { useQueries } from '@tanstack/react-query';
import { useMemo, useRef } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import { AlignedLyric } from '@/components/edit2025/types';
import { fetchClip } from '@/hooks/useClip';
import { Clip } from '@/state/clipStore';

import fetchRefinedAlignedLyrics from '../../edit2025/fetchers/fetchRefinedAlignedLyrics';

export const getAlignedLyricsQueryKey = (clipId: string) => [
  'alignedLyrics',
  clipId,
];

export const useAlignedLyrics = (clips: Record<string, Clip>) => {
  const { clips: clipsStore } = useStores();

  const clipsWithPrompt = useMemo(
    () => Object.values(clips).filter((clip) => clip?.metadata?.prompt),
    [clips]
  );

  const alignedLyricsQueries = useQueries({
    queries: clipsWithPrompt.map((clip) => ({
      queryKey: getAlignedLyricsQueryKey(clip.id),
      queryFn: async () => {
        const terminalClip = await fetchClip(clipsStore, clip.id, true);
        if (terminalClip.status !== 'complete') {
          return [];
        }
        return terminalClip.metadata.prompt
          ? fetchRefinedAlignedLyrics(
              clipsStore.apiClient,
              terminalClip.id,
              terminalClip.metadata.prompt
            )
          : [];
      },
      refetchOnWindowFocus: false,
      refetchOnMount: false,
      gcTime: Infinity,
      staleTime: Infinity,
    })),
  });

  const lastAlignedLyricsRef = useRef<Record<string, AlignedLyric[]>>({});

  const alignedLyrics = useMemo(() => {
    let result = lastAlignedLyricsRef.current;
    clipsWithPrompt
      .map((clip, i) => [clip.id, alignedLyricsQueries[i].data])
      .filter(([, data]) => data)
      .forEach(([id, data]) => {
        if (result[id as string] !== data) {
          result = {
            ...result,
            [id as string]: data as AlignedLyric[],
          };
        }
      });
    lastAlignedLyricsRef.current = result;
    return result;
  }, [clipsWithPrompt, alignedLyricsQueries]);

  return alignedLyrics;
};
