import CONTENT_BLOCK_QUERY from '@/graphql/gql/queries/contentBlockQuery.gql';
import INSTRUMENT_FRAGMENT from '@/graphql/gql/fragments/instrumentParts.gql';
import { pushToArray, removeAtIndex } from '@/graphql/immutable-operations';
import { graphql } from '@/__generated__';

const compareUuid = (uuid: string) => (element) => element.uuid === uuid;
type UpdateCurry = (newBookmarkedValue: boolean) => (store) => void;
type GetVariables = (newBookmarkedValue: boolean) => any;

interface Mutation {
  mutation: any;
  optimisticResponse: any;
  updateCurry: UpdateCurry;
  getVariables: GetVariables;
}

export const constructContentComponentBookmarkMutation: (uuid: string, parent: any, root: any) => Mutation = (
  uuid,
  parent,
  root
) => {
  let mutation: any;
  let updateCurry: UpdateCurry;
  let getVariables: GetVariables;
  let optimisticResponse: any;

  if (parent.__typename === 'InstrumentNode') {
    updateCurry = (newBookmarkedValue: boolean) => (store) => {
      const fragment = INSTRUMENT_FRAGMENT;
      const id = store.identify({
        __typename: 'InstrumentNode',
        slug: root,
      });
      const instrument = store.readFragment({
        fragment,
        id,
      });

      let bookmarks: any[];
      console.log(newBookmarkedValue);

      if (newBookmarkedValue) {
        const element = {
          note: null,
          uuid,
          __typename: 'InstrumentBookmarkNode',
        };
        bookmarks = pushToArray(instrument.bookmarks, element);
      } else {
        const index = instrument.bookmarks.findIndex(compareUuid(uuid));
        if (index > -1) {
          bookmarks = removeAtIndex(instrument.bookmarks, index);
        } else {
          bookmarks = [...instrument.bookmarks];
        }
      }

      const data = {
        ...instrument,
        bookmarks,
      };
      console.log(data);

      store.writeFragment({
        data,
        fragment,
        id,
      });
    };
    getVariables = (newBookmarkedValue: boolean) => {
      return {
        input: {
          uuid,
          instrument: root,
          bookmarked: newBookmarkedValue,
        },
      };
    };
    mutation = graphql(`
      mutation UpdateInstrumentBookmark($input: UpdateInstrumentBookmarkInput!) {
        updateInstrumentBookmark(input: $input) {
          success
        }
      }
    `);
    optimisticResponse = {
      __typename: 'Mutation',
      updateInstrumentBookmark: {
        __typename: 'UpdateInstrumentBookmarkPayload',
        success: true,
      },
    };
  } else {
    updateCurry = (newBookmarkedValue: boolean) => (store) => {
      const query = CONTENT_BLOCK_QUERY;
      const variables = { id: root };
      const { contentBlock } = store.readQuery({
        query,
        variables,
      });

      // const bookmarks = data.contentBlock.bookmarks;
      let bookmarks: any[];

      if (newBookmarkedValue) {
        const element = {
          note: null,
          uuid,
          __typename: 'ContentBlockBookmarkNode',
        };
        bookmarks = pushToArray(contentBlock.bookmarks, element);
      } else {
        const index = contentBlock.bookmarks.findIndex(compareUuid(uuid));
        if (index > -1) {
          bookmarks = removeAtIndex(contentBlock.bookmarks, index);
        } else {
          bookmarks = [...contentBlock.bookmarks];
        }
      }

      const data = {
        contentBlock: {
          ...contentBlock,
          bookmarks,
        },
      };

      store.writeQuery({
        data,
        query,
        variables,
      });
    };
    getVariables = (newBookmarkedValue: boolean) => {
      return {
        input: {
          uuid,
          contentBlock: root,
          bookmarked: newBookmarkedValue,
        },
      };
    };
    mutation = graphql(`
      mutation UpdateContentBookmark($input: UpdateContentBookmarkInput!) {
        updateContentBookmark(input: $input) {
          success
        }
      }
    `);
    optimisticResponse = {
      __typename: 'Mutation',
      updateContentBookmark: {
        __typename: 'UpdateContentBookmarkPayload',
        success: true,
      },
    };
  }
  return { mutation, updateCurry, getVariables, optimisticResponse };
};
