import { useQuery } from '@tanstack/vue-query'
import { computed, toValue, type MaybeRefOrGetter } from 'vue'
import { apiClient } from './client'
import { throwApiProblem } from './contracts'
import type { components, paths } from './generated/schema'
import { queryClient, queryKeys } from './queryClient'

type JsonBody<TResponse> = TResponse extends {
  content: { 'application/json': infer TBody }
}
  ? TBody
  : never

type GeneratedModelAuthQuery = NonNullable<
  paths['/api/v1/openclaw/models/auth-status']['get']['parameters']['query']
>

export type OpenClawModelAuthCollectionDto = JsonBody<
  paths['/api/v1/openclaw/models/auth-status']['get']['responses'][200]
>
export type OpenClawModelAuthProviderDto =
  components['schemas']['OpenClawModelAuthProviderDto']

export async function fetchOpenClawModelAuthStatus(
  refresh = false,
  signal?: AbortSignal,
): Promise<OpenClawModelAuthCollectionDto> {
  const query: GeneratedModelAuthQuery = { refresh }
  const { data, error, response } = await apiClient.GET(
    '/api/v1/openclaw/models/auth-status',
    {
      params: { query },
      signal,
    },
  )
  if (!response.ok || error || !data) {
    await throwApiProblem(response, 'Provider-Authentifizierungsstatus konnte nicht geladen werden')
  }
  return data as OpenClawModelAuthCollectionDto
}

export function openClawModelAuthQueryOptions() {
  return {
    queryKey: queryKeys.openClawModelAuth(),
    queryFn: ({ signal }: { signal: AbortSignal }) =>
      fetchOpenClawModelAuthStatus(false, signal),
    staleTime: 30_000,
  } as const
}

export function useOpenClawModelAuthQuery(
  enabled: MaybeRefOrGetter<boolean> = true,
) {
  return useQuery({
    ...openClawModelAuthQueryOptions(),
    enabled: computed(() => toValue(enabled)),
  })
}

export function refreshOpenClawModelAuthStatus(): Promise<OpenClawModelAuthCollectionDto> {
  return queryClient.fetchQuery({
    ...openClawModelAuthQueryOptions(),
    queryFn: ({ signal }) => fetchOpenClawModelAuthStatus(true, signal),
    staleTime: 0,
  })
}
