import { mutationOptions } from '@tanstack/react-query';
import { getQueryClient } from '@/lib/query-client';
import {
  createDocumentTemplate,
  createDocumentTemplateMapping,
  createDocumentTemplateVersion,
  deleteDocumentTemplate,
  deleteDocumentTemplateMapping,
  setDocumentTemplateVersionActive,
  updateDocumentTemplate,
  updateDocumentTemplateMapping,
  updateDocumentTemplateVersion
} from './service';
import { documentTemplateKeys } from './queries';
import type {
  DocumentTemplateMappingMutationPayload,
  DocumentTemplateMutationPayload,
  DocumentTemplateVersionMutationPayload
} from './types';

async function invalidateTemplateLists() {
  await getQueryClient().invalidateQueries({ queryKey: documentTemplateKeys.lists() });
}

async function invalidateTemplateDetail(id: string) {
  await Promise.all([
    getQueryClient().invalidateQueries({ queryKey: documentTemplateKeys.detail(id) }),
    getQueryClient().invalidateQueries({ queryKey: documentTemplateKeys.versions(id) })
  ]);
}

export const createDocumentTemplateMutation = mutationOptions({
  mutationFn: (data: DocumentTemplateMutationPayload) => createDocumentTemplate(data),
  onSettled: async (_data, error) => {
    if (!error) {
      await invalidateTemplateLists();
    }
  }
});

export const updateDocumentTemplateMutation = mutationOptions({
  mutationFn: ({ id, values }: { id: string; values: Partial<DocumentTemplateMutationPayload> }) =>
    updateDocumentTemplate(id, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([invalidateTemplateLists(), invalidateTemplateDetail(variables.id)]);
    }
  }
});

export const deleteDocumentTemplateMutation = mutationOptions({
  mutationFn: (id: string) => deleteDocumentTemplate(id),
  onSettled: async (_data, error, id) => {
    if (!error) {
      const queryClient = getQueryClient();
      await invalidateTemplateLists();
      queryClient.removeQueries({ queryKey: documentTemplateKeys.detail(id) });
      queryClient.removeQueries({ queryKey: documentTemplateKeys.versions(id) });
    }
  }
});

export const createDocumentTemplateVersionMutation = mutationOptions({
  mutationFn: ({ id, values }: { id: string; values: DocumentTemplateVersionMutationPayload }) =>
    createDocumentTemplateVersion(id, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([invalidateTemplateLists(), invalidateTemplateDetail(variables.id)]);
    }
  }
});

export const updateDocumentTemplateVersionMutation = mutationOptions({
  mutationFn: ({
    templateId,
    versionId,
    values
  }: {
    templateId: string;
    versionId: string;
    values: Partial<DocumentTemplateVersionMutationPayload>;
  }) => {
    void templateId;
    return updateDocumentTemplateVersion(versionId, values);
  },
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([invalidateTemplateLists(), invalidateTemplateDetail(variables.templateId)]);
    }
  }
});

export const setDocumentTemplateVersionActiveMutation = mutationOptions({
  mutationFn: ({
    templateId,
    versionId,
    isActive
  }: {
    templateId: string;
    versionId: string;
    isActive: boolean;
  }) => {
    void templateId;
    return setDocumentTemplateVersionActive(versionId, isActive);
  },
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([invalidateTemplateLists(), invalidateTemplateDetail(variables.templateId)]);
    }
  }
});

export const createDocumentTemplateMappingMutation = mutationOptions({
  mutationFn: ({
    templateId,
    versionId,
    values
  }: {
    templateId: string;
    versionId: string;
    values: DocumentTemplateMappingMutationPayload;
  }) => {
    void templateId;
    return createDocumentTemplateMapping(versionId, values);
  },
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([invalidateTemplateLists(), invalidateTemplateDetail(variables.templateId)]);
    }
  }
});

export const updateDocumentTemplateMappingMutation = mutationOptions({
  mutationFn: ({
    templateId,
    mappingId,
    values
  }: {
    templateId: string;
    mappingId: string;
    values: Partial<DocumentTemplateMappingMutationPayload>;
  }) => {
    void templateId;
    return updateDocumentTemplateMapping(mappingId, values);
  },
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([invalidateTemplateLists(), invalidateTemplateDetail(variables.templateId)]);
    }
  }
});

export const deleteDocumentTemplateMappingMutation = mutationOptions({
  mutationFn: ({ templateId, mappingId }: { templateId: string; mappingId: string }) => {
    void templateId;
    return deleteDocumentTemplateMapping(mappingId);
  },
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([invalidateTemplateLists(), invalidateTemplateDetail(variables.templateId)]);
    }
  }
});
