import {
  ApolloCache,
  Reference,
  useMutation,
  useQuery,
  gql,
} from '@apollo/client';
import {
  DeleteAllianceMutation,
  DeleteAllianceMutationVariables,
  TryDeleteAllianceQuery,
  TryDeleteAllianceQueryVariables,
} from 'types/graphql';

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

export const TRY_DELETE_ALLIANCE = gql`
  query TRY_DELETE_ALLIANCE($allianceId: ID!) {
    confirm: tryDeleteAlliance(allianceId: $allianceId) {
      ...confirmation
    }
  }
  ${fragments.confirmation}
`;

export const DELETE_ALLIANCE = gql`
  mutation DELETE_ALLIANCE($allianceId: ID!, $confirmedIds: [ID]) {
    alliance: deleteAlliance(
      allianceId: $allianceId
      acceptedConsequences: $confirmedIds
    ) {
      id
    }
  }
`;

const deleteExistingAllianceRef =
  (allianceId: string) => (cache: ApolloCache<object>) => {
    cache.modify({
      fields: {
        allAlliances(existingAllianceRefs: Reference[], { readField }) {
          const filtered = existingAllianceRefs.filter(
            (allianceRef) => readField('id', allianceRef) !== allianceId
          );
          return filtered;
        },
      },
    });
  };

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

export const DeleteAllianceModal = ({
  allianceId,
  onDismiss,
  onComplete,
}: DeleteAllianceModalProps) => {
  const { data, ...query } = useQuery<
    TryDeleteAllianceQuery,
    TryDeleteAllianceQueryVariables
  >(TRY_DELETE_ALLIANCE, {
    variables: { allianceId },
  });

  const [deleteAlliance, mutation] = useMutation<
    DeleteAllianceMutation,
    DeleteAllianceMutationVariables
  >(DELETE_ALLIANCE, {
    awaitRefetchQueries: true,
    errorPolicy: 'none',
    update: deleteExistingAllianceRef(allianceId),
  });

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

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

  return (
    <DeleteConfirmationModal
      title="Delete alliance?"
      message="Once you delete the alliance you can't undo it!"
      confirm={data?.confirm}
      loading={query.loading}
      submitting={mutation.loading}
      onSubmit={handleDelete}
      onDismiss={onDismiss}
      submitButton={mutation.loading ? 'Deleting...' : 'Delete'}
      error={error}
    />
  );
};
