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

import {
  contractTemplatesService,
  type ArticlePayload,
  type UpdateContractTemplatePayload,
} from "@/services/contract-templates.service";

const KEYS = {
  ROOT: ["contract-templates"] as const,
  list: () => ["contract-templates", "list"] as const,
  byCode: (code: string) => ["contract-templates", "detail", code] as const,
  preview: (code: string) => ["contract-templates", "preview", code] as const,
};

export function useContractTemplates() {
  return useQuery({
    queryKey: KEYS.list(),
    queryFn: () => contractTemplatesService.list(),
  });
}

export function useContractTemplate(code: string | undefined) {
  return useQuery({
    queryKey: KEYS.byCode(code ?? ""),
    queryFn: () => contractTemplatesService.getByCode(code as string),
    enabled: Boolean(code),
  });
}

/** Rendered mock-data HTML preview of the template's saved state. */
export function useContractTemplatePreview(code: string | undefined, enabled = true) {
  return useQuery({
    queryKey: KEYS.preview(code ?? ""),
    queryFn: () => contractTemplatesService.preview(code as string),
    enabled: Boolean(code) && enabled,
    staleTime: 0,
  });
}

function useTemplateMutation<TVariables>(
  mutationFn: (vars: TVariables) => Promise<unknown>,
  successMessage: string,
) {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn,
    onSuccess: () => {
      toast.success(successMessage);
      void queryClient.invalidateQueries({ queryKey: KEYS.ROOT });
    },
    onError: (error: unknown) => {
      const message =
        (error as { response?: { data?: { message?: string } } })?.response?.data
          ?.message ?? "Something went wrong";
      toast.error(Array.isArray(message) ? message.join(", ") : message);
    },
  });
}

export function useUpdateContractTemplate(code: string) {
  return useTemplateMutation(
    (payload: UpdateContractTemplatePayload) =>
      contractTemplatesService.update(code, payload),
    "Template updated",
  );
}

export function useAddArticle(code: string) {
  return useTemplateMutation(
    (payload: ArticlePayload) => contractTemplatesService.addArticle(code, payload),
    "Article added",
  );
}

export function useUpdateArticle(code: string) {
  return useTemplateMutation(
    (vars: { articleId: string; payload: Partial<ArticlePayload> }) =>
      contractTemplatesService.updateArticle(code, vars.articleId, vars.payload),
    "Article updated",
  );
}

export function useRemoveArticle(code: string) {
  return useTemplateMutation(
    (articleId: string) => contractTemplatesService.removeArticle(code, articleId),
    "Article removed",
  );
}

export function useReplaceArticles(code: string) {
  return useTemplateMutation(
    (articles: Array<{ id?: string; title: string; body: string }>) =>
      contractTemplatesService.replaceArticles(code, articles),
    "Articles reordered",
  );
}
