import {
  ApolloCache,
  FetchResult,
  Reference,
  useMutation,
  useQuery,
} from '@apollo/client';
import { TRY_DELETE_ALLIANCE_MEMBER } from '../schema/queries';
import { REMOVE_ALLIANCE_MEMBER } from '../schema/mutations';
import {
  RemoveAllianceMemberMutation,
  RemoveAllianceMemberMutationVariables,
  TryDeleteAllianceMemberQuery,
  TryDeleteAllianceMemberQueryVariables,
} from 'types/graphql';

import { DeleteConfirmationModal } from 'components/modals/confirmation';
import { call } from 'utils/call';

const removeExistingMemberRef =
  (allianceId: string) =>
  (
    cache: ApolloCache<object>,
    { data }: FetchResult<RemoveAllianceMemberMutation>
  ) => {
    const memberId = data?.member?.id;
    if (!memberId) return;
    cache.modify({
      // TODO identify by fragment and id
      id: `Alliance:${allianceId}`,
      fields: {
        members(existingMemberRefs: Reference[], { readField }) {
          return existingMemberRefs.filter((memberRef) => {
            return readField('id', memberRef) !== memberId;
          });
        },
      },
    });
  };

interface LeaveAllianceModalProps {
  memberId: string;
  allianceId: string;
  onComplete?: () => void;
  onDismiss?: () => void;
}

export const LeaveAllianceModal = ({
  memberId,
  allianceId,
  onComplete,
  onDismiss,
}: LeaveAllianceModalProps) => {
  const { data, ...query } = useQuery<
    TryDeleteAllianceMemberQuery,
    TryDeleteAllianceMemberQueryVariables
  >(TRY_DELETE_ALLIANCE_MEMBER, {
    variables: { allianceId, memberId },
  });

  const [removeMember, mutation] = useMutation<
    RemoveAllianceMemberMutation,
    RemoveAllianceMemberMutationVariables
  >(REMOVE_ALLIANCE_MEMBER, {
    update: removeExistingMemberRef(allianceId),
  });

  const handleDelete = async (confirmedIds: string[]) => {
    try {
      await removeMember({
        variables: { allianceId, memberId, confirmedIds },
      });
      call(onComplete);
      call(onDismiss);
    } catch (error) {
      console.error(error);
    }
  };

  const error = query.error || mutation.error;

  return (
    <DeleteConfirmationModal
      title="Leave alliance?"
      message="Do you want to leave the alliance?"
      confirm={data?.confirm}
      loading={query.loading}
      submitting={mutation.loading}
      onSubmit={handleDelete}
      onDismiss={onDismiss}
      submitButton={mutation.loading ? 'Leaving...' : 'Leave'}
      error={error}
    />
  );
};
