import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";

import { api } from "../client";
import type { components } from "../schema";
import { HttpError, InUseError } from "../errors";
import { keys } from "../query-keys";

type LabelInput = components["schemas"]["LabelInput"];

export function useAuthorities(kind: string | null | undefined) {
  return useQuery({
    queryKey: keys.authorities(kind),
    enabled: !!kind,
    queryFn: async () => {
      const { data, error } = await api.GET("/api/admin/authorities", {
        params: { query: { kind: kind! } },
      });

      if (error || !data) throw new Error("failed to load authorities");

      return data;
    },
    staleTime: 5 * 60 * 1000,
  });
}

export function useCreateAuthority() {
  const qc = useQueryClient();

  return useMutation({
    mutationFn: async ({
      kind,
      external_uri,
      labels,
    }: {
      kind: string;
      external_uri: string | null;
      labels: LabelInput[];
    }) => {
      const { response } = await api.POST("/api/admin/authorities", {
        body: { kind, external_uri, labels },
      });

      if (response.status !== 201) throw new HttpError(response.status);
    },
    onSuccess: (_result, { kind }) =>
      qc.invalidateQueries({ queryKey: keys.authorities(kind) }),
    meta: { successMessage: "toast.created", suppressErrorToast: true },
  });
}

export function useUpdateAuthority() {
  const qc = useQueryClient();

  return useMutation({
    mutationFn: async ({
      id,
      external_uri,
      labels,
    }: {
      id: string;
      kind: string;
      external_uri: string | null;
      labels: LabelInput[];
    }) => {
      const { response } = await api.PATCH("/api/admin/authorities/{id}", {
        params: { path: { id } },
        body: { external_uri, labels },
      });

      if (response.status !== 204) throw new HttpError(response.status);
    },
    onSuccess: (_d, { kind }) => qc.invalidateQueries({ queryKey: keys.authorities(kind) }),
    meta: { successMessage: "toast.saved", suppressErrorToast: true },
  });
}

export function useDeleteAuthority() {
  const qc = useQueryClient();

  return useMutation({
    mutationFn: async ({ id }: { id: string; kind: string }) => {
      const { error, response } = await api.DELETE("/api/admin/authorities/{id}", {
        params: { path: { id } },
      });

      if (response.status === 409) throw new InUseError((error as { count?: number })?.count ?? 0);
      if (response.status !== 204) throw new HttpError(response.status);
    },
    onSuccess: (_d, { kind }) => qc.invalidateQueries({ queryKey: keys.authorities(kind) }),
    meta: { successMessage: "toast.deleted", suppressErrorToast: true },
  });
}
