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

import { IconCopy, IconUsersPlus } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';
import Chip from '@material-hu/components/design-system/Chip';
import Drawer from '@material-hu/components/design-system/Drawer';
import useSnackbar from '@material-hu/components/design-system/Snackbar';

import { logEvent } from 'src/config/logging';
import { useAuth } from 'src/contexts/JWTContext';
import useRequiredParams from 'src/hooks/useRequiredParams';
import { addMembers, inviteMembers } from 'src/services/groups';
import { EventName } from 'src/types/amplitude';
import { GroupPrivacyPolicies } from 'src/types/groups';
import { User } from 'src/types/user';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { getFullName } from 'src/utils/userUtils';

import { useGroupMember } from '../GroupMemberContext';
import { invalidateGroup } from '../queries';

import { FormAutocompleteGroupMemberSelect } from './inputs/FormAutocompleteGroupMemberSelect';

type Props = {
  privacyPolicy: GroupPrivacyPolicies;
};
const GroupsMemberSelect: FC<Props> = props => {
  const { privacyPolicy } = props;
  const [open, setOpen] = useState(false);
  const { id: groupId } = useRequiredParams(['id']);
  const { t } = useTranslation(['group']);
  const { enqueueSnackbar } = useSnackbar();
  const { userIsMember, isGroupAdmin } = useGroupMember();
  const { user: loggedInUser } = useAuth();
  const isAddMode =
    isGroupAdmin ||
    (userIsMember && privacyPolicy === GroupPrivacyPolicies.OPEN);
  const form = useForm<{ selectedMembers: User[] }>({
    defaultValues: {
      selectedMembers: [],
    },
  });

  const handleToggle = () => {
    setOpen(!open);
    form.reset();
  };

  const { remove } = useFieldArray<{ selectedMembers: User[] }>({
    control: form.control,
    name: 'selectedMembers',
  });
  const selectedMembers = form.watch('selectedMembers');

  const addOrInviteMutation = useMutation(
    (userIds: number[]) =>
      (isAddMode ? addMembers : inviteMembers)(groupId, userIds),
    {
      onSuccess: (resp, userIds) => {
        invalidateGroup(Number(groupId));
        handleToggle();
        logEvent(EventName.GROUPS_USER_ADDED, {
          userId: loggedInUser?.id,
          groupId,
          action: isAddMode ? 'ADD' : 'INVITE',
          addedUserIds: userIds,
        });
        enqueueSnackbar({
          title: t(
            isAddMode ? 'group:invite_sent' : 'group:invite_request_sent',
          ),
          variant: 'success',
        });
      },
    },
  );

  const handleAdd = () =>
    addOrInviteMutation.mutate(selectedMembers.map(u => u.id));

  const handleRemoveUser = (user: User) =>
    remove(selectedMembers.indexOf(user));

  const handleReset = () => {
    form.reset();
    setOpen(false);
  };

  const inviteLink = `https://app.humand.co/groups/${groupId}`;
  const handleCopyInviteLink = async () => {
    await navigator.clipboard.writeText(inviteLink);
    enqueueSnackbar({
      title: t('group:invite_link_copied'),
      variant: 'success',
    });
  };

  return (
    <FormProvider {...form}>
      <Button
        variant="outlined"
        onClick={() => handleToggle()}
        startIcon={<IconUsersPlus />}
      >
        {t('group:new_people')}
      </Button>
      <Drawer
        anchor="right"
        open={open}
        onClose={handleToggle}
        title={t('group:new_people')}
      >
        <Stack
          sx={{
            overflow: 'auto',
            flex: 1,
            justifyContent: 'space-between',
          }}
        >
          <Stack>
            <Stack
              sx={{
                gap: 2,
                borderRadius: 2,
                p: 2,
                backgroundColor: theme =>
                  theme.palette.new.background.layout.default,
                mb: 0,
              }}
            >
              <FormAutocompleteGroupMemberSelect enabled={open} />
              {!!selectedMembers.length && (
                <Stack
                  sx={{
                    flexDirection: 'row',
                    gap: 1,
                    flexWrap: 'wrap',
                    maxWidth: '100%',
                  }}
                >
                  {selectedMembers.map(user => (
                    <Chip
                      key={user.id}
                      label={getFullName(user)}
                      onDelete={() => handleRemoveUser(user)}
                    />
                  ))}
                </Stack>
              )}
            </Stack>
            {(privacyPolicy === GroupPrivacyPolicies.OPEN ||
              privacyPolicy === GroupPrivacyPolicies.CLOSE) && (
              <Stack
                sx={{
                  mt: 3,
                  flexDirection: 'row',
                  justifyContent: 'space-between',
                  alignItems: 'center',
                }}
              >
                <Typography variant="body1">
                  {t('group:invite_link_title')}
                </Typography>
                <Button
                  variant="outlined"
                  size="small"
                  sx={theme => ({
                    borderRadius: 1.5,
                    color: theme.palette.new.text.neutral.disabled,
                    backgroundColor: theme =>
                      theme.palette.new.background.layout.tertiary,
                  })}
                  endIcon={<IconCopy />}
                  onClick={handleCopyInviteLink}
                >
                  <Typography
                    variant="button"
                    sx={{
                      overflow: 'hidden',
                      textOverflow: 'ellipsis',
                      maxWidth: '147px',
                      textTransform: 'none',
                    }}
                  >
                    {inviteLink}
                  </Typography>
                </Button>
              </Stack>
            )}
          </Stack>
          <Stack
            sx={{
              flexDirection: 'row',
              justifyContent: 'space-between',
              gap: 1,
              pt: 1,
            }}
          >
            <Button
              onClick={handleReset}
              fullWidth
            >
              {t('general:cancel')}
            </Button>
            <Button
              disabled={!selectedMembers.length}
              onClick={handleAdd}
              loading={addOrInviteMutation.isLoading}
              variant="primary"
              fullWidth
            >
              {t('general:add')}
            </Button>
          </Stack>
        </Stack>
      </Drawer>
    </FormProvider>
  );
};

export default GroupsMemberSelect;
