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

import MailOutlineIcon from '@material-hu/icons/material/MailOutline';
import Box from '@material-hu/mui/Box';
import Dialog from '@material-hu/mui/Dialog';
import DialogContent from '@material-hu/mui/DialogContent';
import DialogTitle from '@material-hu/mui/DialogTitle';
import Divider from '@material-hu/mui/Divider';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';

import { tokenManager } from 'src/config/tokens';
import { useAuth } from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import { unableInviteCode } from 'src/services/instance';
import { sendInvitation } from 'src/services/users';
import { SendInvitationData } from 'src/types/instance';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { sendInvitationValues, getInvitationLink } from 'src/utils/instance';
import { checkEmptyArray } from 'src/utils/invitePeople';

import CloseButton from 'src/components/dashboard/invitePeople/components/CloseButton';
import CopyInvitationLink from 'src/components/dashboard/invitePeople/components/CopyInvitationLink';
import InvitationForm from 'src/components/dashboard/invitePeople/components/InvitationForm';
import InvitationLink from 'src/components/dashboard/invitePeople/components/InvitationLink';
import InvitePeopleTitle from 'src/components/dashboard/invitePeople/components/InvitePeopleTitle';
import DeactivateLinkModal from 'src/components/dashboard/invitePeople/DeactivateLinkModal';

export type InvitationFormData = {
  sendInvitations: { email: string }[];
};

export type NewPeopleDialogProps = {
  open: boolean;
  handleClose: () => void;
  handleAddInvitations: any;
};

export const NewPeopleDialog: FC<NewPeopleDialogProps> = props => {
  const { open, handleClose, handleAddInvitations } = props;

  const { t } = useLokaliseTranslation('invitePeople');
  const showGeneralError = useGeneralError();
  const { instance } = useAuth();
  const { accessToken } = tokenManager.getCorrectToken();

  const [openDeactivateLink, setOpenDeactivateLink] = useState(false);
  const [invitationLink, setInvitationLink] = useState('');

  const form = useForm<InvitationFormData>({
    defaultValues: {
      sendInvitations: [{ email: '' }],
    },
  });

  const {
    handleSubmit,
    watch,
    reset,
    formState: { isSubmitting },
  } = form;

  const { mutate, isLoading } = useMutation(
    (invitationData: SendInvitationData): any =>
      sendInvitation({ emails: invitationData.emailsArray }),
    {
      onSuccess: (_, data) => {
        handleAddInvitations(data.emailsArray);
        reset();
      },
      onError: err => {
        showGeneralError(err, t('SEND_INVITATION_ERROR'));
      },
    },
  );

  const handleSendInvitations = async (values: InvitationFormData) => {
    const { sendInvitations } = values;
    const invitationData = sendInvitationValues(sendInvitations, accessToken);
    mutate(invitationData);
  };

  const getLinkInvitation = async () => {
    try {
      const link = await getInvitationLink(instance?.id!, instance?.name!);
      setInvitationLink(link);
    } catch (err) {
      showGeneralError(err, t('GET_INVITATION_LINK_ERROR'));
    }
  };

  const handleUnableInviteCode = async () => {
    try {
      await unableInviteCode(instance?.id!);
      getLinkInvitation();
      setOpenDeactivateLink(false);
    } catch (err) {
      showGeneralError(err, t('DISABLED_INVITE_CODE_ERROR'));
    }
  };

  useEffect(() => {
    getLinkInvitation();
  }, []);

  const submit = (values: InvitationFormData) => {
    handleSendInvitations(values);
  };

  const handleOnClose = () => {
    reset();
    handleClose();
  };

  const handleOnDeactivateLink = () => {
    setOpenDeactivateLink(true);
  };

  return (
    <Dialog
      open={open}
      onClose={handleOnClose}
      maxWidth="sm"
      fullWidth
    >
      <DialogTitle
        sx={{
          mb: 0,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
        }}
      >
        <InvitePeopleTitle
          title={t('INVITE_PEOPLE_TITLE', { companyName: instance?.name! })}
        />
        <CloseButton handleOnClose={handleOnClose} />
      </DialogTitle>
      <DialogContent>
        <CopyInvitationLink handleOnDeactivateLink={handleOnDeactivateLink} />
        <DeactivateLinkModal
          open={openDeactivateLink}
          handleClose={() => setOpenDeactivateLink(false)}
          handleDisableInviteCode={handleUnableInviteCode}
          instanceName={instance?.name!}
        />
        <InvitationLink invitationLink={invitationLink} />
        <Divider sx={{ my: 2, borderWidth: '1px' }} />
        <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
          <MailOutlineIcon sx={{ fontSize: '16px', mr: 0.5 }} />
          <Typography sx={{ fontSize: '12px', fontWeight: '500' }}>
            {t('EMAIL_INVITE')}
          </Typography>
        </Box>
        <FormProvider {...form}>
          <form
            onSubmit={e => {
              e.preventDefault();
            }}
          >
            <InvitationForm />
            <Box
              sx={{
                width: '100%',
                display: 'flex',
                justifyContent: 'flex-end',
              }}
            >
              <Button
                variant="contained"
                onClick={handleSubmit(submit)}
                color="success"
                disabled={
                  checkEmptyArray(watch('sendInvitations')) ||
                  isSubmitting ||
                  isLoading
                }
                sx={{ mt: 2, px: 4, borderRadius: '10px' }}
              >
                <Typography sx={{ fontSize: '16px', fontWeight: 600 }}>
                  {t('general:send')}
                </Typography>
              </Button>
            </Box>
          </form>
        </FormProvider>
      </DialogContent>
    </Dialog>
  );
};

export default NewPeopleDialog;
