import { mutationOptions } from '@tanstack/react-query';
import { getQueryClient } from '@/lib/query-client';
import {
  activateDocumentLibraryVersion,
  archiveDocumentLibraryVersion,
  createDocumentLibrary,
  deleteDraftDocumentLibraryVersion,
  publishDocumentLibraryVersion,
  updateDocumentLibrary,
  uploadDocumentLibraryVersion
} from './service';
import { documentLibraryKeys } from './queries';
import type {
  DocumentLibraryMutationPayload,
  DocumentLibraryVersionUploadPayload
} from './types';

async function invalidateLibraryLists() {
  await getQueryClient().invalidateQueries({ queryKey: documentLibraryKeys.lists() });
}

async function invalidateLibraryDetail(id: string) {
  await getQueryClient().invalidateQueries({ queryKey: documentLibraryKeys.detail(id) });
}

export const createDocumentLibraryMutation = mutationOptions({
  mutationFn: (values: DocumentLibraryMutationPayload) => createDocumentLibrary(values),
  onSettled: async (_data, error) => {
    if (!error) {
      await invalidateLibraryLists();
    }
  }
});

export const updateDocumentLibraryMutation = mutationOptions({
  mutationFn: ({
    id,
    values
  }: {
    id: string;
    values: Partial<DocumentLibraryMutationPayload>;
  }) => updateDocumentLibrary(id, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([invalidateLibraryLists(), invalidateLibraryDetail(variables.id)]);
    }
  }
});

export const uploadDocumentLibraryVersionMutation = mutationOptions({
  mutationFn: ({
    libraryId,
    values
  }: {
    libraryId: string;
    values: DocumentLibraryVersionUploadPayload;
  }) => uploadDocumentLibraryVersion(libraryId, values),
  onSettled: async (_data, error, variables) => {
    if (!error) {
      await Promise.all([
        invalidateLibraryLists(),
        invalidateLibraryDetail(variables.libraryId)
      ]);
    }
  }
});

function makeVersionLifecycleMutation(
  action: (versionId: string) => Promise<unknown>
) {
  return mutationOptions({
    mutationFn: ({
      libraryId,
      versionId
    }: {
      libraryId: string;
      versionId: string;
    }) => action(versionId),
    onSettled: async (_data, error, variables) => {
      if (!error) {
        await Promise.all([
          invalidateLibraryLists(),
          invalidateLibraryDetail(variables.libraryId)
        ]);
      }
    }
  });
}

export const publishDocumentLibraryVersionMutation = makeVersionLifecycleMutation(
  publishDocumentLibraryVersion
);
export const activateDocumentLibraryVersionMutation = makeVersionLifecycleMutation(
  activateDocumentLibraryVersion
);
export const archiveDocumentLibraryVersionMutation = makeVersionLifecycleMutation(
  archiveDocumentLibraryVersion
);
export const deleteDraftDocumentLibraryVersionMutation = makeVersionLifecycleMutation(
  deleteDraftDocumentLibraryVersion
);
