import { useState } from 'react';
import { useQuery } from '@apollo/client';
import { WORKSPACE_COLLECTIONS, WORKSPACE } from './schema/queries';
import { WORKSPACE_EVENTS } from './schema/subscriptions';
import {
  WorkspaceCollectionsQuery,
  WorkspaceCollectionsQueryVariables,
  WorkspaceEventsSubscription,
  WorkspaceEventsSubscriptionVariables,
  WorkspaceQuery,
  WorkspaceQueryVariables,
} from 'types/graphql';
import { useStatelessSubscription, useUpdateQuery } from 'lib/apollo';
import { call } from 'utils/call';

const updateCollections =
  (refetch: () => void) =>
  (
    prev: WorkspaceCollectionsQuery | null,
    data: WorkspaceEventsSubscription | undefined
  ) => {
    try {
      if (!data?.event || prev === null) return;
      const collections = [...prev.collections];
      const collection = data.event.collection;

      const index = collections.findIndex((c) => c.id === collection.id);

      if (index === -1) {
        return {
          ...prev,
          collections: collections.concat(collection),
        };
      } else if (
        typeof refetch === 'function' &&
        collection.parentId === null &&
        (collection.status === 'finished' || collection.status === 'deleted')
      ) {
        refetch();
      }
    } catch (error) {
      console.log('updateQuery', error);
    }
  };

export function useWorkspaceQuery(workspaceId: string) {
  const [skipQuery, setSkipQuery] = useState(true);

  const workspaceQuery = useQuery<WorkspaceQuery, WorkspaceQueryVariables>(
    WORKSPACE,
    {
      variables: { workspaceId: workspaceId! },
      skip: skipQuery,
    }
  );

  const collectionsQuery = useQuery<
    WorkspaceCollectionsQuery,
    WorkspaceCollectionsQueryVariables
  >(WORKSPACE_COLLECTIONS, {
    variables: { workspaceId: workspaceId! },
    skip: skipQuery,
    fetchPolicy: 'network-only',
    nextFetchPolicy: 'cache-first',
  });

  const updateQuery = useUpdateQuery<
    WorkspaceCollectionsQuery,
    WorkspaceEventsSubscription
  >(WORKSPACE_COLLECTIONS, { workspaceId });

  useStatelessSubscription<
    WorkspaceEventsSubscription,
    WorkspaceEventsSubscriptionVariables
  >(WORKSPACE_EVENTS, {
    variables: { workspaceId: workspaceId! },
    onUpdate: updateQuery(updateCollections(workspaceQuery.refetch)),
    onSubscribe: () => {
      if (!skipQuery) {
        call(workspaceQuery.refetch);
        call(collectionsQuery.refetch);
      } else {
        setSkipQuery(false);
      }
    },
  });

  const loading = workspaceQuery.loading || collectionsQuery.loading;
  const error = workspaceQuery.error || collectionsQuery.error;

  return {
    loading,
    error,
    collections: collectionsQuery.data?.collections,
    workspace: workspaceQuery.data?.workspace,
  } as const;
}
