import { ApolloCache, Reference, useMutation } from '@apollo/client';
import { TEMP_CONNECT_AD_ACCOUNT, UNSHARE_AUDIENCE } from '../schema/mutations';
import {
  TempConnectAdAccountMutation,
  TempConnectAdAccountMutationVariables,
  UnshareAudienceMutation,
  UnshareAudienceMutationVariables,
} from 'types/graphql';
import { call } from 'utils/call';

import { useDelay } from 'hooks/useDelay';

import { Box, Button, Text } from 'components/common';
import { ModalContainer } from 'components/modals';

const updateAudienceRef =
  (audienceId: string, adAccountId: string) => (cache: ApolloCache<object>) => {
    cache.modify({
      // TODO identify by fragment and id
      // id: cache.identify(audience),
      id: `AudienceExtended:${audienceId}`,
      fields: {
        sharedWith(existingAdAccounts, { readField }) {
          return existingAdAccounts.filter((adAccountRef: Reference) => {
            return readField('id', adAccountRef) !== adAccountId;
          });
        },
      },
    });
  };

interface ResolveAdAccountAccessModalProps {
  audienceId: string;
  audienceName: string;
  adAccountId: string;
  adAccountName: string;
  onDismiss?: () => void;
}

export const ResolveAdAccountAccessModal = ({
  audienceId,
  audienceName,
  adAccountId,
  adAccountName,
  onDismiss,
}: ResolveAdAccountAccessModalProps) => {
  const [mutate, mutation] = useMutation<
    UnshareAudienceMutation,
    UnshareAudienceMutationVariables
  >(UNSHARE_AUDIENCE, {
    update: updateAudienceRef(audienceId, adAccountId),
  });

  const [connect, connectMutation] = useMutation<
    TempConnectAdAccountMutation,
    TempConnectAdAccountMutationVariables
  >(TEMP_CONNECT_AD_ACCOUNT);

  const handleRevoke: React.MouseEventHandler<HTMLButtonElement> = async (
    ev
  ) => {
    ev.preventDefault();

    const variables = { audienceId, adAccountId };
    try {
      await mutate({ variables });
      call(onDismiss);
    } catch (error) {
      console.log(error);
    }
  };

  const handleConnect: React.MouseEventHandler<HTMLButtonElement> = async (
    ev
  ) => {
    ev.preventDefault();

    const variables = { id: adAccountId, name: adAccountName };
    try {
      await connect({ variables });
      call(onDismiss);
    } catch (error) {
      console.log(error);
    }
  };

  const loading = mutation.loading || connectMutation.loading;

  const [remainder] = useDelay(15000);

  return (
    <ModalContainer title="Resolve Problem">
      <div className="mb4">
        <Text size="s" align="center">
          Audience <b>{audienceName}</b> is shared with not connected{' '}
          <b>{adAccountName}</b> ad account
        </Text>
      </div>
      <Box spacingY={4}>
        <Box display="flex" spacing={2}>
          <Button onClick={handleConnect} color="blue" block disabled={loading}>
            Keep Ad Account
          </Button>
          <Button
            onClick={handleRevoke}
            color="red"
            block
            disabled={remainder > 0 || loading}
          >
            {remainder > 0 ? `Wait (${remainder / 1000})` : 'Revoke access'}
          </Button>
        </Box>
        <Button onClick={onDismiss} color="gray" block>
          Cancel
        </Button>
      </Box>
    </ModalContainer>
  );
};
