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

export type IncidentFileDto = components['schemas']['IncidentSummary']
export type IncidentDetailDto = components['schemas']['IncidentDetail']

async function requireData<T>(
  response: Response,
  data: T | undefined,
  error: unknown,
  fallback: string,
): Promise<T> {
  if (!response.ok || error || !data) {
    await throwApiProblem(response, fallback)
  }
  return data as T
}

export async function fetchIncidents(
  agentId = 'iris',
  signal?: AbortSignal,
): Promise<IncidentFileDto[]> {
  const { data, error, response } = await apiClient.GET('/api/v1/incidents', {
    params: { query: { agentId } },
    signal,
  })
  return requireData(
    response,
    data,
    error,
    'Incidents konnten nicht geladen werden',
  )
}

export async function fetchIncident(
  name: string,
  agentId = 'iris',
  signal?: AbortSignal,
): Promise<IncidentDetailDto> {
  const { data, error, response } = await apiClient.GET(
    '/api/v1/incidents/{name}',
    {
      params: {
        path: { name },
        query: { agentId },
      },
      signal,
    },
  )
  return requireData(
    response,
    data,
    error,
    'Incident konnte nicht geladen werden',
  )
}

export function useIncidentsQuery(
  agentId: MaybeRefOrGetter<string> = 'iris',
) {
  const resolvedAgentId = computed(() => toValue(agentId))
  return useQuery({
    queryKey: computed(() => queryKeys.incidents(resolvedAgentId.value)),
    queryFn: ({ signal }) => fetchIncidents(resolvedAgentId.value, signal),
  })
}

export function useIncidentQuery(
  name: MaybeRefOrGetter<string>,
  enabled: MaybeRefOrGetter<boolean> = true,
  agentId: MaybeRefOrGetter<string> = 'iris',
) {
  const resolvedName = computed(() => toValue(name))
  const resolvedAgentId = computed(() => toValue(agentId))
  return useQuery({
    queryKey: computed(() =>
      queryKeys.incident(resolvedAgentId.value, resolvedName.value),
    ),
    queryFn: ({ signal }) =>
      fetchIncident(resolvedName.value, resolvedAgentId.value, signal),
    enabled: computed(() => Boolean(resolvedName.value) && toValue(enabled)),
  })
}
