import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query';

import { LibraryItemID } from '@/models/library';
import { IOperationSchema, IOperationSchemaData } from '@/models/oss';
import { OssLoader } from '@/models/OssLoader';

import { useLibrary, useLibrarySuspense } from '@/backend/library/useLibrary';
import { ossApi } from './api';

export function useOss({ itemID }: { itemID?: LibraryItemID }) {
  const { items: libraryItems, isLoading: libraryLoading } = useLibrary();
  const { data, isLoading, error } = useQuery({
    ...ossApi.getOssQueryOptions({ itemID })
  });

  const schema = data && !libraryLoading ? new OssLoader(data, libraryItems).produceOSS() : undefined;
  return { schema: schema, isLoading: isLoading || libraryLoading, error: error };
}

export function useOssSuspense({ itemID }: { itemID?: LibraryItemID }) {
  const { items: libraryItems } = useLibrarySuspense();
  const { data } = useSuspenseQuery({
    ...ossApi.getOssQueryOptions({ itemID })
  });
  const schema = data ? new OssLoader(data, libraryItems).produceOSS() : undefined;
  return { schema };
}

export function useOssUpdate({ itemID }: { itemID?: LibraryItemID }) {
  const { items: libraryItems } = useLibrary();
  const client = useQueryClient();
  const queryKey = [ossApi.getOssQueryOptions({ itemID }).queryKey];
  return {
    update: (data: IOperationSchemaData) =>
      client.setQueryData(queryKey, new OssLoader(data, libraryItems).produceOSS()),
    partialUpdate: (data: Partial<IOperationSchema>) =>
      client.setQueryData(queryKey, (prev: IOperationSchema) => (prev ? { ...prev, ...data } : prev))
  };
}

export function useOssInvalidate({ itemID }: { itemID?: LibraryItemID }) {
  const client = useQueryClient();
  const queryKey = [ossApi.getOssQueryOptions({ itemID }).queryKey];
  return {
    invalidate: () => client.invalidateQueries({ queryKey })
  };
}
