'use client';

import React from 'react';
import { useQuery, useQueries, useMutation, UseMutationOptions } from '@tanstack/react-query';
import { ApiError } from '@/lib/api/base/ApiError';

export interface PageDataConfig<TData, TError = ApiError> {
  queryKey: string[];
  queryFn: () => Promise<TData>;
  enabled?: boolean;
  staleTime?: number;
  onError?: (error: TError) => void;
}

/**
 * Single query hook - STANDARDIZED PATTERN
 * Use for: Simple CSR pages
 *
 * @example
 * const { data, isLoading, error, refetch } = usePageData({
 *   queryKey: ['profile'],
 *   queryFn: () => driverService.getProfile(),
 * });
 */
export function usePageData<TData, TError = ApiError>(
  config: PageDataConfig<TData, TError>
) {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const queryOptions: any = {
    queryKey: config.queryKey,
    queryFn: config.queryFn,
    enabled: config.enabled ?? true,
    staleTime: config.staleTime ?? 1000 * 60 * 5,
  };
  
  if (config.onError) {
    queryOptions.onError = config.onError;
  }
  
  return useQuery<TData, TError>(queryOptions);
}

/**
 * Multiple queries hook - STANDARDIZED PATTERN
 * Use for: Complex CSR pages with multiple data sources
 *
 * @example
 * const { data, isLoading, error, refetch } = usePageDataMultiple({
 *   results: {
 *     queryKey: ['raceResults', raceId],
 *     queryFn: () => service.getResults(raceId),
 *   },
 *   sof: {
 *     queryKey: ['raceSOF', raceId],
 *     queryFn: () => service.getSOF(raceId),
 *   },
 * });
 */
export function usePageDataMultiple<T extends Record<string, unknown>>(
  queries: {
    [K in keyof T]: PageDataConfig<T[K]>;
  }
) {
  const queryResults = useQueries({
    queries: Object.entries(queries).map(([_key, config]) => {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const queryOptions: any = {
        queryKey: config.queryKey,
        queryFn: config.queryFn,
        enabled: config.enabled ?? true,
        staleTime: config.staleTime ?? 1000 * 60 * 5,
      };
      if (config.onError) {
        queryOptions.onError = config.onError;
      }
      return queryOptions;
    }),
  });

  // Combine results
  const combined = {} as { [K in keyof T]: T[K] | null };
  const keys = Object.keys(queries) as (keyof T)[];
  
  keys.forEach((key, index) => {
    const result = queryResults[index]?.data;
    if (result !== undefined) {
      combined[key] = result as T[typeof key];
    } else {
      combined[key] = null as T[typeof key] | null;
    }
  });

  const isLoading = queryResults.some(q => q.isLoading);
  const error = queryResults.find(q => q.error)?.error ?? null;

  return {
    data: combined,
    isLoading,
    error,
    refetch: () => queryResults.forEach(q => q.refetch()),
  };
}

/**
 * Mutation hook wrapper - STANDARDIZED PATTERN
 * Use for: All mutation operations
 *
 * @deprecated Use Next.js Server Actions instead for all write operations.
 * See docs/architecture/website/FORM_SUBMISSION.md
 *
 * @example
 * const mutation = usePageMutation(
 *   (variables) => service.mutateData(variables),
 *   { onSuccess: () => refetch() }
 * );
 */
export function usePageMutation<TData, TVariables, TError = ApiError>(
  mutationFn: (variables: TVariables) => Promise<TData>,
  options?: Omit<UseMutationOptions<TData, TError, TVariables>, 'mutationFn'>
) {
  return useMutation<TData, TError, TVariables>({
    mutationFn,
    ...options,
  });
}

/**
 * SSR Hydration Hook - NEW
 * Use for: Passing SSR data to CSR to avoid re-fetching
 *
 * @example
 * // In SSR page
 * const ssrData = await PageDataFetcher.fetch(...);
 *
 * // In client component
 * const { data } = useHydrateSSRData(ssrData, ['queryKey']);
 */
export function useHydrateSSRData<TData>(
  ssrData: TData | null,
  _queryKey: string[]
): { data: TData | null; isHydrated: boolean } {
  const [isHydrated, setIsHydrated] = React.useState(false);
  
  React.useEffect(() => {
    if (ssrData !== null) {
      setIsHydrated(true);
    }
  }, [ssrData]);

  return {
    data: ssrData,
    isHydrated,
  };
}