import React from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { DefaultService } from '@lib/api';
import { StyleConfig } from '@/types';
import { listApiKeys } from '@/lib/api/userApiKeys';

export const CONFIG_KEYS = {
  all: ['config'] as const,
  models: () => [...CONFIG_KEYS.all, 'models'] as const,
  styles: () => [...CONFIG_KEYS.all, 'styles'] as const,
  options: () => [...CONFIG_KEYS.all, 'options'] as const,
  userApiKeys: () => [...CONFIG_KEYS.all, 'userApiKeys'] as const,
  providerConfigs: () => [...CONFIG_KEYS.all, 'providerConfigs'] as const,
};

export function useModels() {
  return useQuery({
    queryKey: CONFIG_KEYS.models(),
    queryFn: async () => {
      console.log('[useModels] Fetching models...');
      try {
        const response = await DefaultService.getModelsConfig();
        console.log('[useModels] Response:', response);
        // Generated client returns BaseResponse body directly, not AxiosResponse
        return response?.data || { image: {}, video: {}, audio: {}, lyrics: {}, music: {}, llm: {} };
      } catch (error) {
        console.error('[useModels] Error:', error);
        throw error;
      }
    },
    staleTime: 1000 * 60 * 5, // 5 minutes
    gcTime: 1000 * 60 * 30, // 30 minutes
    retry: 2,
  });
}

/**
 * Get supported provider configurations for user API key management
 */
export function useProviderConfigs() {
  return useQuery({
    queryKey: CONFIG_KEYS.providerConfigs(),
    queryFn: async () => {
      const response = await DefaultService.getProviderConfigs();
      return response?.data?.providers || [];
    },
    staleTime: 1000 * 60 * 5, // 5 minutes
    gcTime: 1000 * 60 * 30, // 30 minutes
    retry: 2,
  });
}

/**
 * Get user configured API keys
 * @param enabled - Whether to enable the query (e.g., only when authenticated)
 */
export function useUserApiKeys(enabled: boolean = true) {
  return useQuery({
    queryKey: CONFIG_KEYS.userApiKeys(),
    queryFn: async () => {
      const keys = await listApiKeys(false);
      return keys;
    },
    staleTime: 1000 * 60 * 2, // 2 minutes
    gcTime: 1000 * 60 * 10, // 10 minutes
    retry: 1,
    enabled,
  });
}

/**
 * Get models filtered by configured API keys
 * Only returns models whose provider has a configured API key
 */
export function useConfiguredModels() {
  const { data: modelsData, isLoading: isModelsLoading, error: modelsError } = useModels();
  const { data: apiKeys, isLoading: isKeysLoading, error: keysError } = useUserApiKeys();

  // Extract provider IDs that have configured API keys
  const configuredProviders = React.useMemo(() =>
    new Set(apiKeys?.filter(k => k.isActive).map(k => k.provider) || []),
    [apiKeys]
  );

  // Filter models to only include those with configured providers
  const filteredModels = React.useMemo(() => {
    if (!modelsData) return null;

    const result: Record<string, any> = {};

    for (const [type, models] of Object.entries(modelsData)) {
      if (typeof models === 'object' && models !== null) {
        result[type] = {};
        for (const [id, model] of Object.entries(models)) {
          const modelProvider = (model as any)?.provider;
          // Only include model if its provider has a configured API key
          if (modelProvider && configuredProviders.has(modelProvider)) {
            result[type][id] = model;
          }
        }
      }
    }

    return result;
  }, [modelsData, configuredProviders]);

  // Flatten filtered models for convenience
  const flatModels = React.useMemo(() => {
    if (!filteredModels) return [];

    const allModels: any[] = [];
    Object.values(filteredModels).forEach((typeModels: any) => {
      if (typeModels) {
        Object.values(typeModels).forEach((m: any) => allModels.push(m));
      }
    });
    return allModels;
  }, [filteredModels]);

  return {
    models: filteredModels,
    modelsList: flatModels,
    configuredProviders: Array.from(configuredProviders),
    isLoading: isModelsLoading || isKeysLoading,
    error: modelsError || keysError,
  };
}

export function useStyles() {
  return useQuery({
    queryKey: CONFIG_KEYS.styles(),
    queryFn: async () => {
      const res: any = await DefaultService.getStyles();
      console.log('[useStyles] API response:', res);
      return res?.data || [];
    },
    staleTime: 1000 * 60 * 5,
    gcTime: 1000 * 60 * 30,
  });
}

export function useOptions() {
  return useQuery({
    queryKey: CONFIG_KEYS.options(),
    queryFn: async () => {
      const res = await DefaultService.getOptionsConfig();
      return res?.data || {};
    },
  });
}

export function useCreateStyle() {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: (data: Partial<StyleConfig>) => DefaultService.createStyle(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: CONFIG_KEYS.styles() });
    },
  });
}

export function useUpdateStyle() {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: ({ id, data }: { id: string; data: Partial<StyleConfig> }) => 
      DefaultService.updateStyle(id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: CONFIG_KEYS.styles() });
    },
  });
}

export function useDeleteStyle() {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: (id: string) => DefaultService.deleteStyle(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: CONFIG_KEYS.styles() });
    },
  });
}
