import {
  useMutation,
  useQuery,
  useQueryClient,
  type UseMutationResult,
  type UseQueryResult
} from '@tanstack/react-query'
import type { DdevAddonRegistryEntry, DdevInstalledAddon } from '@shared/types'
import { useTerminalStore } from '../stores/terminalStore'
import { useStatusStore } from '../stores/statusStore'

const installedAddonsKey = (name: string): readonly [string, string, string] =>
  ['addons', 'installed', name] as const

// The registry is a static-ish list of ~270 third-party repos — cache it for
// a while instead of refetching on every mount.
export function useAddonRegistry(): UseQueryResult<DdevAddonRegistryEntry[], Error> {
  return useQuery({
    queryKey: ['addons', 'registry'],
    queryFn: () => window.api.addons.listRegistry(),
    staleTime: 60 * 60 * 1000
  })
}

export function useInstalledAddons(name: string): UseQueryResult<DdevInstalledAddon[], Error> {
  return useQuery({
    queryKey: installedAddonsKey(name),
    queryFn: () => window.api.addons.listInstalled(name)
  })
}

function beginOperation(label: string): string {
  const operationId = crypto.randomUUID()
  useTerminalStore.getState().startOperation(operationId, label)
  useStatusStore.getState().begin(operationId, label)
  return operationId
}

export function useInstallAddon(name: string): UseMutationResult<void, Error, string> {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: async (addonRepo: string) => {
      const operationId = beginOperation(`Install ${addonRepo}`)
      await window.api.addons.install(operationId, name, addonRepo)
    },
    onSettled: () => queryClient.invalidateQueries({ queryKey: installedAddonsKey(name) })
  })
}

export function useRemoveAddon(name: string): UseMutationResult<void, Error, string> {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: async (addonName: string) => {
      const operationId = beginOperation(`Remove ${addonName}`)
      await window.api.addons.remove(operationId, name, addonName)
    },
    onSettled: () => queryClient.invalidateQueries({ queryKey: installedAddonsKey(name) })
  })
}
