/**
 * Agent Types Hooks
 *
 * TanStack Query hooks for managing agent type operations.
 * Provides data fetching and mutations for the agent-types API.
 */

'use client';

import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '@/lib/api/client';
import { useAuth } from '@/lib/auth/AuthContext';
import type {
  AgentTypeCreate,
  AgentTypeUpdate,
  AgentTypeResponse,
  AgentTypeListResponse,
  AgentTypeListParams,
} from '@/lib/api/types/agentTypes';

/**
 * Query keys for agent types
 */
export const agentTypeKeys = {
  all: ['agent-types'] as const,
  lists: () => [...agentTypeKeys.all, 'list'] as const,
  list: (params: AgentTypeListParams) => [...agentTypeKeys.lists(), params] as const,
  details: () => [...agentTypeKeys.all, 'detail'] as const,
  detail: (id: string) => [...agentTypeKeys.details(), id] as const,
  bySlug: (slug: string) => [...agentTypeKeys.all, 'slug', slug] as const,
};

/**
 * Default page limit for listing agent types
 */
const DEFAULT_PAGE_LIMIT = 20;

/**
 * Hook to fetch paginated list of agent types
 *
 * @param params - Query parameters for filtering and pagination
 * @returns Query result with agent types list
 */
export function useAgentTypes(params: AgentTypeListParams = {}) {
  const { user } = useAuth();

  const { page = 1, limit = DEFAULT_PAGE_LIMIT, is_active = true, search } = params;

  return useQuery({
    queryKey: agentTypeKeys.list({ page, limit, is_active, search }),
    queryFn: async (): Promise<AgentTypeListResponse> => {
      const response = await apiClient.instance.get('/api/v1/agent-types', {
        params: {
          page,
          limit,
          is_active,
          ...(search ? { search } : {}),
        },
      });
      return response.data;
    },
    enabled: !!user,
    staleTime: 30000, // 30 seconds
  });
}

/**
 * Hook to fetch a single agent type by ID
 *
 * @param id - Agent type UUID
 * @returns Query result with agent type details
 */
export function useAgentType(id: string | null) {
  const { user } = useAuth();

  return useQuery({
    queryKey: agentTypeKeys.detail(id ?? ''),
    queryFn: async (): Promise<AgentTypeResponse> => {
      if (!id) throw new Error('Agent type ID is required');
      const response = await apiClient.instance.get(`/api/v1/agent-types/${id}`);
      return response.data;
    },
    enabled: !!user && !!id,
    staleTime: 60000, // 1 minute
  });
}

/**
 * Hook to fetch an agent type by slug
 *
 * @param slug - Agent type slug
 * @returns Query result with agent type details
 */
export function useAgentTypeBySlug(slug: string | null) {
  const { user } = useAuth();

  return useQuery({
    queryKey: agentTypeKeys.bySlug(slug ?? ''),
    queryFn: async (): Promise<AgentTypeResponse> => {
      if (!slug) throw new Error('Agent type slug is required');
      const response = await apiClient.instance.get(`/api/v1/agent-types/slug/${slug}`);
      return response.data;
    },
    enabled: !!user && !!slug,
    staleTime: 60000, // 1 minute
  });
}

/**
 * Hook to create a new agent type
 *
 * @returns Mutation for creating agent types
 */
export function useCreateAgentType() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (data: AgentTypeCreate): Promise<AgentTypeResponse> => {
      const response = await apiClient.instance.post('/api/v1/agent-types', data);
      return response.data;
    },
    onSuccess: () => {
      // Invalidate all agent type lists to refetch
      queryClient.invalidateQueries({ queryKey: agentTypeKeys.lists() });
    },
  });
}

/**
 * Hook to update an existing agent type
 *
 * @returns Mutation for updating agent types
 */
export function useUpdateAgentType() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({
      id,
      data,
    }: {
      id: string;
      data: AgentTypeUpdate;
    }): Promise<AgentTypeResponse> => {
      const response = await apiClient.instance.patch(`/api/v1/agent-types/${id}`, data);
      return response.data;
    },
    onSuccess: (updatedAgentType) => {
      // Update the cache for this specific agent type
      queryClient.setQueryData(agentTypeKeys.detail(updatedAgentType.id), updatedAgentType);
      // Invalidate lists to reflect changes
      queryClient.invalidateQueries({ queryKey: agentTypeKeys.lists() });
    },
  });
}

/**
 * Hook to deactivate (soft delete) an agent type
 *
 * @returns Mutation for deactivating agent types
 */
export function useDeactivateAgentType() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (id: string): Promise<{ success: boolean; message: string }> => {
      const response = await apiClient.instance.delete(`/api/v1/agent-types/${id}`);
      return response.data;
    },
    onSuccess: (_data, id) => {
      // Invalidate all agent type queries
      queryClient.invalidateQueries({ queryKey: agentTypeKeys.all });
      // Remove specific agent type from cache
      queryClient.removeQueries({ queryKey: agentTypeKeys.detail(id) });
    },
  });
}

/**
 * Hook to duplicate an agent type
 *
 * @returns Mutation for duplicating agent types
 */
export function useDuplicateAgentType() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (agentType: AgentTypeResponse): Promise<AgentTypeResponse> => {
      // Create a new agent type based on the existing one
      const newAgentType: AgentTypeCreate = {
        name: `${agentType.name} (Copy)`,
        slug: `${agentType.slug}-copy`,
        description: agentType.description,
        expertise: [...agentType.expertise],
        personality_prompt: agentType.personality_prompt,
        primary_model: agentType.primary_model,
        fallback_models: [...agentType.fallback_models],
        model_params: { ...agentType.model_params },
        mcp_servers: [...agentType.mcp_servers],
        tool_permissions: { ...agentType.tool_permissions },
        is_active: false, // Start as inactive/draft
      };

      const response = await apiClient.instance.post('/api/v1/agent-types', newAgentType);
      return response.data;
    },
    onSuccess: () => {
      // Invalidate lists to show the new duplicate
      queryClient.invalidateQueries({ queryKey: agentTypeKeys.lists() });
    },
  });
}
