import { useMutation } from '@tanstack/react-query';
import { useCallback, useRef } from 'react';

import { useStores } from '@/app/(root)/AppProviders';

/**
 * Hook to handle warming up audio features for clips in studio.
 * Tracks which clips have already been warmed up to avoid duplicate requests.
 * Each clip is only warmed up once per session.
 */
// Module-level tracking so multiple components/hooks share state across the app session
const warmedUpClips: Set<string> = (() => {
  try {
    if (typeof window !== 'undefined') {
      const saved = window.sessionStorage.getItem('studio_warmed_up_clips');
      if (saved) {
        const arr = JSON.parse(saved) as string[];
        return new Set(arr);
      }
    }
  } catch {}
  return new Set<string>();
})();

const inFlightWarmups = new Set<string>();

const persistWarmedUpClips = () => {
  try {
    if (typeof window !== 'undefined') {
      window.sessionStorage.setItem(
        'studio_warmed_up_clips',
        JSON.stringify(Array.from(warmedUpClips))
      );
    }
  } catch {}
};

export const useClipWarmup = () => {
  const { clips: clipsStore } = useStores();

  const warmupMutation = useMutation({
    mutationFn: async (clipId: string) => {
      // Call the warmup API endpoint
      const response = await clipsStore.apiClient.POST(
        '/api/gen/{clip_id}/warmup-audio-features',
        {
          params: { path: { clip_id: clipId } },
        }
      );

      if (response.error) {
        throw new Error(`Failed to warmup audio features for clip ${clipId}`);
      }

      return response;
    },
    onSuccess: (_, clipId) => {
      // Mark this clip as warmed up
      warmedUpClips.add(clipId);
      inFlightWarmups.delete(clipId);
      persistWarmedUpClips();
    },
    onError: (error, clipId) => {
      console.warn(
        `Failed to warmup audio features for clip ${clipId}:`,
        error
      );
      // Don't add to warmed up set on error, so it can be retried
      inFlightWarmups.delete(clipId);
    },
    // Don't retry on failure to avoid spam
    retry: false,
  });

  const warmupMutationRef = useRef(warmupMutation);
  warmupMutationRef.current = warmupMutation;

  const warmupClip = useCallback((clipId: string) => {
    // Only warm up if not already done and not currently in-flight
    if (warmedUpClips.has(clipId) || inFlightWarmups.has(clipId)) return;
    inFlightWarmups.add(clipId);
    warmupMutationRef.current.mutate(clipId);
  }, []);

  return {
    warmupClip,
    isWarming: warmupMutation.isPending,
  };
};
