import {
  ApolloCache,
  FetchResult,
  Reference,
  useMutation,
} from '@apollo/client';
import { CREATE_LOOKALIKE } from '../schema/mutations';
import { audience_extended } from '../schema/fragments';
import {
  CreateLookalikeMutation,
  CreateLookalikeMutationVariables,
} from 'types/graphql';
import { handleGraphQLError } from 'lib/appsync/utils';
import { SERVICE_INFO_ERROR } from 'lib/appsync/errorTypes';
import { call } from 'utils/call';

import { useSimpleForm } from 'hooks/useSimpleForm';

import { Box, Button, Spinner } from 'components/common';
import { Input } from 'components/inputs';
import { InfoModal } from 'components/modals/InfoModal';
import { ModalContainer } from 'components/modals';

const updateAudiencesCache = (
  cache: ApolloCache<object>,
  { data }: FetchResult<CreateLookalikeMutation>
) => {
  if (!data?.audience) return;
  cache.modify({
    fields: {
      fbListAudiences(existingAudienceRefs: Reference[]) {
        const newAudienceRef = cache.writeFragment({
          data: data.audience,
          fragment: audience_extended,
          fragmentName: 'audience_extended',
        });

        return [...existingAudienceRefs, newAudienceRef];
      },
    },
  });
};

interface ConfirmAudienceModalProps {
  input: {
    audienceId: string;
    countries: string | string[];
    ratio: number;
  };
  onDismiss?: () => void;
  dismissParent?: () => void;
}

export const ConfirmAudienceModal = ({
  input,
  onDismiss,
  dismissParent,
}: ConfirmAudienceModalProps) => {
  const [submit, mutation] = useMutation<
    CreateLookalikeMutation,
    CreateLookalikeMutationVariables
  >(CREATE_LOOKALIKE, {
    update: updateAudiencesCache,
  });

  const [state, handleChange] = useSimpleForm({
    name: '',
    description: '',
  });

  const dismissAll = () => {
    call(onDismiss);
    call(dismissParent);
  };

  const handleSubmit: React.FormEventHandler<HTMLFormElement> = async (ev) => {
    ev.preventDefault();

    const variables = {
      ...input,
      name: state.name,
      description: state.description,
    };
    try {
      await submit({ variables });
      dismissAll();
    } catch (error) {
      console.error(error);
    }
  };

  const serviceError = handleGraphQLError(mutation.error, SERVICE_INFO_ERROR);
  if (serviceError) {
    return (
      <InfoModal
        title="Something went wrong"
        message={serviceError.message}
        onDismiss={onDismiss}
      />
    );
  }

  const loading = mutation.loading;

  return (
    <ModalContainer title="Create Audience">
      <form onSubmit={handleSubmit} className="spacingY4">
        <Box position="relative" spacingY={2}>
          <Input
            name="name"
            value={state.name}
            onChange={handleChange}
            placeholder="Audience name"
            disabled={loading}
            autoFocus
          />
          <Input
            name="description"
            value={state.description}
            onChange={handleChange}
            placeholder="Audience description"
            disabled={loading}
          />
          <Spinner show={loading} />
        </Box>
        <Box display="flex" marginY={4} spacing={2}>
          <Button block onClick={onDismiss} color="gray">
            Cancel
          </Button>
          <Button
            block
            type="submit"
            // onClick={handleSubmit}
            color="blue"
            disabled={!state.name || loading}
          >
            Create
          </Button>
        </Box>
      </form>
    </ModalContainer>
  );
};
