/**
 * React Query Hooks for Settings API
 *
 * Provides hooks for fetching and mutating plugin settings.
 */

import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import type { UseQueryOptions, UseMutationOptions } from "@tanstack/react-query";

import {
  getSettings,
  updateSettings,
  updateFonts,
  type SettingsData,
  type SettingsUpdatePayload,
  type FontUpdateResponse,
  type FontsRequestPayload,
  type ApiError,
} from "@/api/settings";
import { aiQueryKeys } from "@pro/hooks/useAi";
import { useSettingsStore } from "@/stores/settingsStore";
import type { FontsMap } from "@/utils/fontUtils";

/**
 * Query keys for settings
 */
export const settingsKeys = {
  all: ["settings"] as const,
  detail: () => [...settingsKeys.all, "detail"] as const,
};

/**
 * Hook to fetch settings
 */
export function useSettings(options?: Omit<UseQueryOptions<SettingsData, ApiError>, "queryKey" | "queryFn">) {
  const setSettings = useSettingsStore((state) => state.setSettings);

  return useQuery({
    queryKey: settingsKeys.detail(),
    queryFn: async () => {
      const data = await getSettings();
      // Update store when data is fetched (inside queryFn, not select, to avoid infinite loops)
      setSettings({
        googleFontsLocal: data.google_fonts_local,
        googleFontsCdn: data.google_fonts_cdn,
        googleFontsDisabled: data.google_fonts_disabled,
        googleFontsCache: data.google_fonts_cache || {},
        aiProvider: data.ai_provider,
        aiApiKey: data.ai_api_key,
        aiModel: data.ai_model,
        hasApiKey: data.has_api_key,
        defaultScenario: data.default_scenario,
      });
      return data;
    },
    ...options,
  });
}

/**
 * Hook to update settings
 */
export function useUpdateSettings(options?: UseMutationOptions<SettingsData, ApiError, SettingsUpdatePayload>) {
  const queryClient = useQueryClient();
  const setSettings = useSettingsStore((state) => state.setSettings);
  const setIsSaving = useSettingsStore((state) => state.setIsSaving);

  return useMutation({
    mutationFn: updateSettings,
    onMutate: () => {
      setIsSaving(true);
    },
    onSuccess: (data) => {
      // Update cache
      queryClient.setQueryData(settingsKeys.detail(), data);
      // Update store
      setSettings({
        googleFontsLocal: data.google_fonts_local,
        googleFontsCdn: data.google_fonts_cdn,
        googleFontsDisabled: data.google_fonts_disabled,
        googleFontsCache: data.google_fonts_cache || {},
        aiProvider: data.ai_provider,
        aiApiKey: data.ai_api_key,
        aiModel: data.ai_model,
        hasApiKey: data.has_api_key,
        defaultScenario: data.default_scenario,
      });
      // Invalidate AI validation
      queryClient.invalidateQueries({ queryKey: aiQueryKeys.validation() });
    },
    onSettled: () => {
      setIsSaving(false);
    },
    ...options,
  });
}

/**
 * Hook to update/download local fonts
 */
export function useUpdateFonts(
  options?: UseMutationOptions<FontUpdateResponse, ApiError, { fonts: FontsRequestPayload; googleFontsLocal?: boolean }>
) {
  const queryClient = useQueryClient();
  const updateFontsCache = useSettingsStore((state) => state.updateFontsCache);
  const setGoogleFontsLocal = useSettingsStore((state) => state.setGoogleFontsLocal);
  const setIsUpdatingFonts = useSettingsStore((state) => state.setIsUpdatingFonts);

  return useMutation({
    mutationFn: updateFonts,
    onMutate: () => {
      setIsUpdatingFonts(true);
    },
    onSuccess: (data) => {
      // Update store cache
      updateFontsCache(data.cache);
      // Auto-enable local fonts if fonts were downloaded
      if (data.google_fonts_local) {
        setGoogleFontsLocal(true);
      }
      // Invalidate settings query to refresh cache data
      queryClient.invalidateQueries({ queryKey: settingsKeys.detail() });
    },
    onSettled: () => {
      setIsUpdatingFonts(false);
    },
    ...options,
  });
}

/**
 * Hook to update fonts for specific font names (used during save)
 * This is a simplified version that doesn't track loading state
 */
export function useUpdateFontsOnSave() {
  const googleFontsLocal = useSettingsStore((state) => state.googleFontsLocal);
  const updateFontsMutation = useUpdateFonts();

  return async (fonts: FontsMap) => {
    // Only update if local fonts are enabled and there are fonts to update
    if (!googleFontsLocal || Object.keys(fonts).length === 0) {
      return;
    }

    try {
      await updateFontsMutation.mutateAsync({ fonts, googleFontsLocal });
    } catch (error) {
      // Log but don't fail the save operation
      console.warn("Failed to update local fonts:", error);
    }
  };
}
