import { FC } from 'react';
import { FormProvider, useForm } from 'react-hook-form';

import { useMutation, useQueryClient } from 'react-query';
import { matchPath } from 'react-router-dom';

import { addDays } from 'date-fns';
import { useDrawer } from '@material-hu/hooks/useDrawer';
import { useModal } from '@material-hu/hooks/useModal';
import { IconChevronRight, IconSpeakerphone } from '@material-hu/icons/tabler';

import HuDialog from '@material-hu/components/design-system/Dialog';
import HuListItem from '@material-hu/components/design-system/List/components/ListItem';
import HuMenuItem from '@material-hu/components/design-system/Menu/components/MenuItem';
import useSnackbar from '@material-hu/components/design-system/Snackbar';

import { useMoreMenu } from 'src/contexts/MoreMenuContext';
import useGeneralError from 'src/hooks/useGeneralError';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { feedKeys } from 'src/pages/dashboard/feed/queries';
import { markPostAsKeyUpdate, unmarkPostAsKeyUpdate } from 'src/services/posts';
import { NotificationMode } from 'src/types/key-updates';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';

import { groupsKeys } from '../../groups/queries';
import { feedRoutes } from '../routes';

import MarkPostAsKeyUpdateDrawerContent from './MarkPostAsKeyUpdateDrawerContent';

export type MarkPostAsKeyUpdateMenuItemProps = {
  id: number;
  isKeyUpdate?: boolean;
  isGroupPost?: boolean;
  groupId?: number;
};

const MarkPostAsKeyUpdateMenuItem: FC<
  MarkPostAsKeyUpdateMenuItemProps
> = props => {
  const { id, isKeyUpdate = false, isGroupPost = false, groupId } = props;
  const { t } = useTranslation();
  const { enqueueSnackbar } = useSnackbar();
  const showGeneralError = useGeneralError();
  const queryClient = useQueryClient();
  const { closeMenu } = useMoreMenu();
  const HuGoThemeProvider = useHuGoTheme();

  const formMethods = useForm({
    defaultValues: {
      notifyViaPush: false,
      notifyViaEmail: false,
      showPreview: false,
      previewDaysCount: 1,
    },
  });

  const isKeyUpdatePage = !!matchPath(
    { path: feedRoutes.keyUpdates(), end: true },
    window.location.pathname,
  );

  const markAsKeyUpdateMutation = useMutation(
    (params: {
      notifyViaPush: boolean;
      notifyViaEmail: boolean;
      showPreview: boolean;
      previewDaysCount: number;
    }) =>
      isKeyUpdate
        ? unmarkPostAsKeyUpdate(id)
        : markPostAsKeyUpdate(
            id,
            [
              params.notifyViaPush ? 'PUSH' : undefined,
              params.notifyViaEmail ? 'EMAIL' : undefined,
            ].filter(Boolean) as NotificationMode[],
            params.showPreview
              ? addDays(new Date(), params.previewDaysCount)
              : undefined,
          ),
    {
      onSuccess: () => {
        if (isGroupPost && groupId) {
          queryClient.invalidateQueries(groupsKeys.detail(id.toString()));
          queryClient.invalidateQueries(
            groupsKeys.postList(groupId.toString()),
          );
        } else {
          queryClient.invalidateQueries(feedKeys.list());
          queryClient.invalidateQueries(feedKeys.detail(id));
        }
        queryClient.invalidateQueries(feedKeys.keyUpdates.all());

        enqueueSnackbar({
          title: isKeyUpdate
            ? t('post:post_unmarked_as_key_update_success')
            : t('post:post_marked_as_key_update_success'),
          variant: 'success',
        });

        closeMenu?.();
      },
      onError: err => {
        showGeneralError(err, t('post:post_mark_as_key_update_error'));
        closeDrawer?.();
        closeModal?.();
        closeMenu?.();
      },
    },
  );

  const handleConfirm = () => {
    const { notifyViaPush, notifyViaEmail, previewDaysCount, showPreview } =
      formMethods.getValues();
    markAsKeyUpdateMutation.mutate({
      notifyViaPush,
      notifyViaEmail,
      showPreview,
      previewDaysCount,
    });
  };

  const drawerTitle = isKeyUpdate
    ? t('post:unmark_as_key_update')
    : t('post:mark_as_key_update_title');

  const { drawer, showDrawer, closeDrawer } = useDrawer(
    () => (
      <FormProvider {...formMethods}>
        <MarkPostAsKeyUpdateDrawerContent />
      </FormProvider>
    ),
    {
      title: drawerTitle,
      primaryButtonProps: {
        children: t('group:update_role_modal_confirm'),
        onClick: () => {
          handleConfirm();
          closeDrawer();
        },
        disabled: markAsKeyUpdateMutation.isLoading,
        sx: { width: '100%' },
      },
      onClose: () => {
        closeDrawer();
        closeMenu?.();
      },
      sx: { zIndex: 1500 },
    },
  );

  const {
    modal: confirmUnmarkModal,
    showModal,
    closeModal,
  } = useModal(
    () => (
      <HuDialog
        title={t('post:unmark_as_key_update_modal_title')}
        textBody={t('post:unmark_as_key_update_modal_description')}
        primaryButtonProps={{
          children: t('post:yes_remove'),
          onClick: () => {
            handleConfirm();
            closeModal();
          },
        }}
        secondaryButtonProps={{
          children: t('general:cancel'),
          onClick: closeModal,
        }}
        onClose={closeModal}
      />
    ),
    {
      sx: { zIndex: 2000 },
    },
  );

  return (
    <>
      <HuMenuItem
        onClick={() => (isKeyUpdate ? showModal() : showDrawer())}
        sx={{ p: 0 }}
      >
        <HuListItem
          sx={{ p: 0 }}
          avatar={{ Icon: IconSpeakerphone }}
          text={{
            title: isKeyUpdate
              ? t('post:unmark_as_key_update')
              : t('post:mark_as_key_update'),
          }}
          sideContent={isKeyUpdatePage && <IconChevronRight />}
        />
      </HuMenuItem>
      <HuGoThemeProvider>
        {confirmUnmarkModal}
        {drawer}
      </HuGoThemeProvider>
    </>
  );
};

export default MarkPostAsKeyUpdateMenuItem;
