import { FC, useState } from 'react';
import { useForm } from 'react-hook-form';
import { useMutation, useQuery } from 'react-query';

import { useDrawer } from '@material-hu/hooks/useDrawer';
import { useModal } from '@material-hu/hooks/useModal';
import { IconUserPlus } from '@material-hu/icons/tabler';

import NewModal from '@material-hu/components/deprecated/NewModal';
import Button from '@material-hu/components/design-system/Buttons/Button';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import { createInvitation, getUninvitedUsersCount } from 'src/services/events';
import { Event, EventInvitation } from 'src/types/events';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { useInvalidateEvent } from '../hooks/useInvalidateEvent';
import { eventsKeys } from '../queries';
import { formatInvitation, getInviteDefaultValues } from '../utils';

import InvitePeople from './InvitePeople';
import InvitePeopleFooter from './InvitePeopleFooter';
import { SelectedPeople } from './SelectedPeople';

type Props = {
  event: Event;
  fullWidth?: boolean;
  size?: 'small' | 'medium' | 'large';
};

const InvitePeopleButton: FC<Props> = ({
  event,
  fullWidth,
  size = 'small',
}) => {
  const { t } = useLokaliseTranslation('events');
  const { enqueueSnackbar } = useHuSnackbar();
  const invalidateEvent = useInvalidateEvent(event.id);
  const [segmentationItems, setSegmentationItems] = useState<number[]>([]);
  const form = useForm({
    defaultValues: getInviteDefaultValues(),
  });
  const { selectAllUsers, excludedUserIds } = form.watch();

  const mutation = useMutation(
    (invitationData: EventInvitation) =>
      createInvitation(event.id, invitationData),
    {
      onSuccess: () => {
        handleExitComplete();
        invalidateEvent();
        enqueueSnackbar({
          title: t('INVITATION_SENT', { count: selectedUsersCount }),
          variant: 'info',
        });
      },
    },
  );

  const submit = form.handleSubmit(() => {
    const values = form.getValues();
    const formattedValues = formatInvitation(values);
    mutation.mutate(formattedValues);
  });

  const { data: uninvitedCount } = useQuery(
    eventsKeys.eventUninvitedUsersCount(event.id, {
      segmentationItemIds: segmentationItems,
    }),
    () =>
      getUninvitedUsersCount(event.id, {
        segmentationItemIds: segmentationItems,
      }),
    {
      select: r => r.data.count,
      onSuccess: count => {
        if (count === 0) {
          form.setValue('selectAllUsers', true);
        }
      },
    },
  );

  const selectedUsersCount =
    selectAllUsers && uninvitedCount
      ? uninvitedCount - excludedUserIds.length
      : excludedUserIds.length;

  const handleExitComplete = () => {
    form.reset();
    drawer.closeDrawer();
    leaveModal.closeModal();
  };

  const leaveModal = useModal(() => (
    <NewModal
      textBody={t('CHANGES_WILL_BE_LOST')}
      title={t('LEAVE_INVITES_TITLE')}
      primaryButtonProps={{
        children: t('EXIT'),
        onClick: handleExitComplete,
        color: 'primary',
      }}
      secondaryButtonProps={{
        children: t('CANCEL'),
        onClick: () => leaveModal.closeModal(),
        color: 'primary',
      }}
      onClose={() => leaveModal.closeModal()}
    />
  ));

  const selectedDrawer = useDrawer(
    SelectedPeople,
    {
      hasBackButton: true,
      title: t('PEOPLE_SELECTED'),
      footer: !!selectedUsersCount && (
        <InvitePeopleFooter selectedUsersCount={selectedUsersCount} />
      ),
    },
    {
      event,
      selection: {
        selectAllUsers,
        excludedUserIds,
        segmentationItemIds: segmentationItems,
      },
    },
  );

  const handleLeaveDrawer = () => {
    selectedUsersCount ? leaveModal.showModal() : handleExitComplete();
    setSegmentationItems([]);
  };

  const drawer = useDrawer(
    InvitePeople,
    {
      title: t('INVITE_PEOPLE'),
      primaryButtonProps: {
        children: t('INVITE'),
        onClick: submit,
        loading: mutation.isLoading,
        disabled: !selectedUsersCount,
      },
      secondaryButtonProps: {
        children: t('CANCEL'),
        onClick: handleLeaveDrawer,
      },
      onClose: handleLeaveDrawer,
      footer: !!selectedUsersCount && (
        <InvitePeopleFooter
          selectedUsersCount={selectedUsersCount}
          onClick={() => selectedDrawer.showDrawer()}
        />
      ),
    },
    { event, form, uninvitedCount, segmentationItems, setSegmentationItems },
  );

  return (
    <>
      {leaveModal.modal}
      {drawer.drawer}
      {selectedDrawer.drawer}
      <Button
        startIcon={<IconUserPlus size={16} />}
        variant="secondary"
        size={size}
        onClick={() => drawer.showDrawer()}
        fullWidth={fullWidth}
      >
        {t('INVITE')}
      </Button>
    </>
  );
};

export default InvitePeopleButton;
