import { GraphQLClient } from 'graphql-request';
import { QueryClient } from '@tanstack/react-query';

// GraphQL endpoint - configure based on environment
const GRAPHQL_ENDPOINT = import.meta.env.VITE_GRAPHQL_ENDPOINT || 'http://localhost:5000/graphql';

// Create GraphQL client
export const graphqlClient = new GraphQLClient(GRAPHQL_ENDPOINT, {
  headers: {
    // Add auth headers here when authentication is implemented
    // 'Authorization': `Bearer ${token}`,
  },
});

// Configure headers dynamically (for auth tokens, etc.)
export const setAuthHeader = (token: string) => {
  graphqlClient.setHeader('Authorization', `Bearer ${token}`);
};

export const removeAuthHeader = () => {
  graphqlClient.setHeader('Authorization', '');
};

// Create TanStack Query client with default options
export const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      // Cache data for 5 minutes
      staleTime: 5 * 60 * 1000,
      // Keep unused data in cache for 30 minutes
      gcTime: 30 * 60 * 1000,
      // Retry failed requests 3 times
      retry: 3,
      // Retry delay with exponential backoff
      retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
      // Refetch on window focus for fresh data
      refetchOnWindowFocus: true,
    },
    mutations: {
      // Retry mutations once
      retry: 1,
    },
  },
});

// Helper function to make GraphQL requests with error handling
export async function fetchGraphQL<TData, TVariables extends Record<string, unknown>>(
  query: string,
  variables?: TVariables
): Promise<TData> {
  try {
    const data = await graphqlClient.request<TData>(query, variables);
    return data;
  } catch (error) {
    // Log error for debugging
    console.error('GraphQL Error:', error);

    // Re-throw with more context
    if (error instanceof Error) {
      throw new Error(`GraphQL request failed: ${error.message}`);
    }
    throw error;
  }
}

// Type-safe query helper
export function createQueryKey(base: string, params?: Record<string, unknown>): string[] {
  const key = [base];
  if (params) {
    key.push(JSON.stringify(params));
  }
  return key;
}
