import { useCallback } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  OAuthConfigSchema,
  CreateOAuthConfigRequest,
  UpdateOAuthConfigRequest,
  ListOAuthConfigsResponse,
  OAuthProvidersSchema,
} from '@insforge/shared-schemas';
import { oAuthConfigService } from '#features/auth/services/oauth-config.service';
import { useToast } from '@insforge/ui';

export function useOAuthConfig(selectedProvider?: OAuthProvidersSchema | null) {
  const queryClient = useQueryClient();
  const { showToast } = useToast();

  // Query to fetch all OAuth configurations
  const {
    data: configs,
    isLoading: isLoadingConfigs,
    error: configsError,
    refetch: refetchConfigs,
  } = useQuery<ListOAuthConfigsResponse>({
    queryKey: ['oauth-configs'],
    queryFn: () => oAuthConfigService.getAllConfigs(),
  });

  // Query to fetch specific provider config
  const {
    data: providerConfig,
    isLoading: isLoadingProvider,
    error: providerError,
    refetch: refetchProvider,
  } = useQuery<OAuthConfigSchema & { clientSecret?: string }>({
    queryKey: ['oauth-config', selectedProvider],
    queryFn: () => oAuthConfigService.getConfigByProvider(selectedProvider ?? ''),
    enabled: !!selectedProvider,
  });

  // Mutation to create OAuth configuration
  const createConfigMutation = useMutation({
    mutationFn: (config: CreateOAuthConfigRequest) => oAuthConfigService.createConfig(config),
    onSuccess: (data) => {
      void queryClient.invalidateQueries({ queryKey: ['oauth-configs'] });
      void queryClient.invalidateQueries({ queryKey: ['oauth-config', data.provider] });
      showToast(`OAuth configuration for ${data.provider} created successfully`, 'success');
    },
    onError: (error: Error) => {
      showToast(error.message || 'Failed to create OAuth configuration', 'error');
    },
  });

  // Mutation to update OAuth configuration
  const updateConfigMutation = useMutation({
    mutationFn: ({ provider, config }: { provider: string; config: UpdateOAuthConfigRequest }) =>
      oAuthConfigService.updateConfig(provider, config),
    onSuccess: (data) => {
      void queryClient.invalidateQueries({ queryKey: ['oauth-configs'] });
      void queryClient.invalidateQueries({ queryKey: ['oauth-config', data.provider] });
      showToast(`OAuth configuration for ${data.provider} updated successfully`, 'success');
    },
    onError: (error: Error) => {
      showToast(error.message || 'Failed to update OAuth configuration', 'error');
    },
  });

  // Mutation to delete OAuth configuration
  const deleteConfigMutation = useMutation({
    mutationFn: (provider: string) => oAuthConfigService.deleteConfig(provider),
    onSuccess: (_, provider) => {
      queryClient.removeQueries({ queryKey: ['oauth-configs'] });
      queryClient.removeQueries({ queryKey: ['oauth-config', provider] });
      showToast(`OAuth configuration for ${provider} deleted successfully`, 'success');
    },
    onError: (error: Error) => {
      showToast(error.message || 'Failed to delete OAuth configuration', 'error');
    },
  });

  // Helper to check if a provider is configured
  const isProviderConfigured = useCallback(
    (provider: OAuthProvidersSchema): boolean => {
      return configs?.data?.some((config) => config.provider === provider) ?? false;
    },
    [configs]
  );

  // Helper to get config for a specific provider from the list
  const getProviderConfig = useCallback(
    (provider: OAuthProvidersSchema): OAuthConfigSchema | undefined => {
      return configs?.data?.find((config) => config.provider === provider);
    },
    [configs]
  );

  return {
    // State
    configs: configs?.data ?? [],
    configsCount: configs?.count ?? 0,
    providerConfig,

    // Loading states
    isLoadingConfigs,
    isLoadingProvider,
    isCreating: createConfigMutation.isPending,
    isUpdating: updateConfigMutation.isPending,
    isDeleting: deleteConfigMutation.isPending,

    // Errors
    configsError,
    providerError,

    // Actions
    createConfig: createConfigMutation.mutate,
    updateConfig: updateConfigMutation.mutate,
    deleteConfig: deleteConfigMutation.mutate,
    refetchConfigs,
    refetchProvider,

    // Helpers
    isProviderConfigured,
    getProviderConfig,
  };
}
