/**
 * React Query hooks for layout management
 */

import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import type { UseQueryResult, UseMutationResult } from "@tanstack/react-query";
import type { UserLayout, WidgetPlacement } from "@mosaic/shared";
import { apiGet, apiPost, apiPatch, apiDelete } from "@/lib/api/client";

const LAYOUTS_KEY = ["layouts"];

interface CreateLayoutData {
  name: string;
  layout: WidgetPlacement[];
  isDefault?: boolean;
  metadata?: Record<string, unknown>;
}

interface UpdateLayoutData {
  id: string;
  name?: string;
  layout?: WidgetPlacement[];
  isDefault?: boolean;
  metadata?: Record<string, unknown>;
}

/**
 * Fetch all layouts for the current user
 */
export function useLayouts(): UseQueryResult<UserLayout[]> {
  return useQuery<UserLayout[]>({
    queryKey: LAYOUTS_KEY,
    queryFn: async (): Promise<UserLayout[]> => {
      return apiGet<UserLayout[]>("/api/layouts");
    },
  });
}

/**
 * Fetch a single layout by ID
 */
export function useLayout(id: string): UseQueryResult<UserLayout> {
  return useQuery<UserLayout>({
    queryKey: [...LAYOUTS_KEY, id],
    queryFn: async (): Promise<UserLayout> => {
      return apiGet<UserLayout>(`/api/layouts/${id}`);
    },
    enabled: !!id,
  });
}

/**
 * Fetch the default layout
 */
export function useDefaultLayout(): UseQueryResult<UserLayout> {
  return useQuery<UserLayout>({
    queryKey: [...LAYOUTS_KEY, "default"],
    queryFn: async (): Promise<UserLayout> => {
      return apiGet<UserLayout>("/api/layouts/default");
    },
  });
}

/**
 * Create a new layout (uses API client for CSRF protection)
 */
export function useCreateLayout(): UseMutationResult<UserLayout, Error, CreateLayoutData> {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (data: CreateLayoutData): Promise<UserLayout> => {
      return apiPost<UserLayout>("/api/layouts", data);
    },
    onSuccess: (): void => {
      // Invalidate layouts cache to refetch
      void queryClient.invalidateQueries({ queryKey: LAYOUTS_KEY });
    },
  });
}

/**
 * Update an existing layout (uses API client for CSRF protection)
 */
export function useUpdateLayout(): UseMutationResult<UserLayout, Error, UpdateLayoutData> {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({ id, ...data }: UpdateLayoutData): Promise<UserLayout> => {
      return apiPatch<UserLayout>(`/api/layouts/${id}`, data);
    },
    onSuccess: (_data, variables): void => {
      // Invalidate affected queries
      void queryClient.invalidateQueries({ queryKey: LAYOUTS_KEY });
      void queryClient.invalidateQueries({ queryKey: [...LAYOUTS_KEY, variables.id] });
    },
  });
}

/**
 * Delete a layout (uses API client for CSRF protection)
 */
export function useDeleteLayout(): UseMutationResult<void, Error, string> {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (id: string): Promise<void> => {
      await apiDelete(`/api/layouts/${id}`);
    },
    onSuccess: (): void => {
      // Invalidate layouts cache to refetch
      void queryClient.invalidateQueries({ queryKey: LAYOUTS_KEY });
    },
  });
}

interface UseSaveLayoutReturn {
  saveLayout: (layout: WidgetPlacement[]) => void;
  isSaving: boolean;
  error: Error | null;
}

/**
 * Helper hook to save layout changes with debouncing
 */
export function useSaveLayout(layoutId: string): UseSaveLayoutReturn {
  const updateLayout = useUpdateLayout();

  const saveLayout = (layout: WidgetPlacement[]): void => {
    updateLayout.mutate({
      id: layoutId,
      layout,
    });
  };

  return {
    saveLayout,
    isSaving: updateLayout.isPending,
    error: updateLayout.error,
  };
}
