import { useInfiniteQuery } from '@tanstack/react-query';

import { useApiClient } from '@/lib/apiClient';
import { Clip } from '@/state/clipStore';

export interface UseRemastersForClipOptions {
  parentClipId: string;
  pageLimit?: number;
  workspaceId?: string | null;
  enabled?: boolean;
}

export interface UseAllRemastersOptions {
  pageLimit?: number;
  workspaceId?: string | null;
  enabled?: boolean;
}

/**
 * Validates that a clip object has the required properties
 */
function isValidClip(clip: any): clip is Clip {
  return (
    clip &&
    typeof clip === 'object' &&
    typeof clip.id === 'string' &&
    clip.id.length > 0
  );
}

/**
 * Validates and filters clips array
 */
function validateClips(clips: any[]): Clip[] {
  if (!Array.isArray(clips)) {
    console.warn('useRemasters: data.clips is not an array', clips);
    return [];
  }

  return clips.filter((clip) => {
    if (!isValidClip(clip)) {
      console.warn('useRemasters: Invalid clip object found', clip);
      return false;
    }
    return true;
  });
}

/**
 * Hook for fetching remasters for a specific clip using TanStack Query
 * Uses feed v3 API
 */
export function useRemastersForClip({
  parentClipId,
  pageLimit = 20,
  workspaceId,
  enabled = true,
}: UseRemastersForClipOptions) {
  const apiClient = useApiClient();

  const isEnabled = enabled && !!parentClipId && parentClipId.length > 0;

  const query = useInfiniteQuery({
    queryKey: ['remasters-for-clip', parentClipId, pageLimit, workspaceId],
    queryFn: async ({ pageParam }: { pageParam: string | null }) => {
      // Create filters for remasters of a specific clip
      const filters: any = {
        remaster: {
          presence: 'True' as const,
          clipId: parentClipId,
        },
      };

      // Only add workspace filter if workspaceId is provided
      if (workspaceId) {
        filters.workspace = {
          presence: 'True' as const,
          workspaceId,
        };
      }

      const { data, error } = await apiClient.POST('/api/feed/v3', {
        body: {
          cursor: pageParam || null,
          limit: pageLimit,
          filters,
        },
      });

      if (error) {
        console.error('Error fetching remasters for clip:', error);
        throw new Error(JSON.stringify(error));
      }

      const rawClips = data?.clips || [];
      const validClips = validateClips(rawClips);

      return {
        clips: validClips,
        nextCursor: data?.next_cursor || null,
        hasMore: !!data?.next_cursor,
        totalClips: validClips.length,
      };
    },
    getNextPageParam: (lastPage) => lastPage.nextCursor,
    initialPageParam: null,
    enabled: isEnabled,
    staleTime: 1000 * 60 * 5, // 5 minutes
    gcTime: 1000 * 60 * 5, // 5 minutes
    retry: (failureCount, error) => {
      console.error('Error fetching remasters for clip:', error);
      if (failureCount > 3) {
        return false;
      }
      return true;
    },
    retryDelay: 2000,
  });

  // Flatten all pages into a single array of clips
  const allClips = query.data?.pages.flatMap((page: any) => page.clips) || [];

  // Calculate total count across all pages
  const totalClips =
    query.data?.pages.reduce(
      (total: number, page: any) => total + page.totalClips,
      0
    ) || 0;

  return {
    // Raw query data
    ...query,

    // Flattened data for easier consumption
    clips: allClips,
    totalClips,

    // Convenience methods
    hasMore: query.hasNextPage,
    isLoadingMore: query.isFetchingNextPage,
    loadMore: query.fetchNextPage,

    // Error handling
    hasError: !!query.error,
    error: query.error,
  };
}

/**
 * Hook for getting all remasters (not specific to a clip)
 * Uses feed v3 API
 */
export function useAllRemasters({
  pageLimit = 20,
  workspaceId,
  enabled = true,
}: UseAllRemastersOptions) {
  const apiClient = useApiClient();

  const query = useInfiniteQuery({
    queryKey: ['remasters', pageLimit, workspaceId],
    queryFn: async ({ pageParam }: { pageParam: string | null }) => {
      const filters: any = {
        remaster: {
          presence: 'True' as const,
        },
      };

      // Only add workspace filter if workspaceId is provided
      if (workspaceId) {
        filters.workspace = {
          presence: 'True' as const,
          workspaceId,
        };
      }

      const { data, error } = await apiClient.POST('/api/feed/v3', {
        body: {
          cursor: pageParam || null,
          limit: pageLimit,
          filters,
        },
      });

      if (error) {
        console.error('Error fetching remasters:', error);
        throw new Error(JSON.stringify(error));
      }

      const rawClips = data?.clips || [];
      const validClips = validateClips(rawClips);

      return {
        clips: validClips,
        nextCursor: data?.next_cursor || null,
        hasMore: !!data?.next_cursor,
        totalClips: validClips.length,
      };
    },
    getNextPageParam: (lastPage) => lastPage.nextCursor,
    initialPageParam: null,
    enabled,
    staleTime: 1000 * 60 * 5, // 5 minutes
    gcTime: 1000 * 60 * 5, // 5 minutes
    retry: (failureCount, error) => {
      console.error('Error fetching remasters:', error);
      if (failureCount > 3) {
        return false;
      }
      return true;
    },
    retryDelay: 2000,
  });

  // Flatten all pages into a single array of clips
  const allClips = query.data?.pages.flatMap((page: any) => page.clips) || [];

  // Calculate total count across all pages
  const totalClips =
    query.data?.pages.reduce(
      (total: number, page: any) => total + page.totalClips,
      0
    ) || 0;

  return {
    // Raw query data
    ...query,

    // Flattened data for easier consumption
    clips: allClips,
    totalClips,

    // Convenience methods
    hasMore: query.hasNextPage,
    isLoadingMore: query.isFetchingNextPage,
    loadMore: query.fetchNextPage,

    // Error handling
    hasError: !!query.error,
    error: query.error,
  };
}
