import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { api } from '@/api/client';
import type { Connection, CredentialType } from '@/types';

/**
 * Connections: saved API keys, encrypted on the server. Nothing here ever
 * receives a secret back — a key goes up once, when it is added or replaced.
 */

const connectionsKey = ['flowwp', 'connections'] as const;

export function useCredentialTypes() {
  return useQuery({
    queryKey: ['flowwp', 'credential-types'],
    queryFn: async () => (await api.get<CredentialType[]>('/credential-types')).data,
    staleTime: Infinity,
  });
}

/**
 * @param refreshOnFocus For the editor: connections are added on their own
 *                       page, often in another tab, so coming back refreshes.
 */
export function useConnections(refreshOnFocus = false) {
  return useQuery({
    queryKey: connectionsKey,
    queryFn: async () => (await api.get<Connection[]>('/credentials')).data,
    refetchOnWindowFocus: refreshOnFocus,
  });
}

/** The page and every connection field share one list; a change refreshes it. */
function useInvalidate() {
  const client = useQueryClient();

  return () => {
    void client.invalidateQueries({ queryKey: connectionsKey });
  };
}

export function useCreateConnection() {
  const invalidate = useInvalidate();

  return useMutation({
    mutationFn: async (input: { type: string; label: string; values: Record<string, string> }) =>
      (await api.post<Connection>('/credentials', input)).data,
    onSuccess: invalidate,
  });
}

export function useUpdateConnection() {
  const invalidate = useInvalidate();

  return useMutation({
    mutationFn: async ({ id, ...input }: { id: number; label: string; values: Record<string, string> }) =>
      (await api.put<Connection>(`/credentials/${id}`, input)).data,
    onSuccess: invalidate,
  });
}

export function useDeleteConnection() {
  const invalidate = useInvalidate();

  return useMutation({
    mutationFn: async (id: number) => (await api.delete<unknown>(`/credentials/${id}`)).data,
    onSuccess: invalidate,
  });
}

export function useTestConnection() {
  return useMutation({
    mutationFn: async (id: number) => (await api.post<{ ok: boolean }>(`/credentials/${id}/test`)).data,
  });
}
