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

import { useMutation, useQuery } from 'react-query';

import { useDrawer } from '@material-hu/hooks/useDrawer';

import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import useRequiredParams from 'src/hooks/useRequiredParams';
import {
  getGroupNotificationConfiguration,
  updateGroupNotificationConfiguration,
} from 'src/services/groups';
import { GroupNotificationConfigurationConfigModes } from 'src/types/groups';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';

import { GroupMailNotificationSettings } from '../constants';
import { useGroupMember } from '../GroupMemberContext';
import { groupsKeys } from '../queries';

import GroupNotificationsSettings from './GroupNotificationsSettings';

export const GROUP_NOTIFICATIONS_SETTINGS_MAIL_FORM_NAME = 'emailNotifications';
export const NOTIFICATION_CENTER_SETTINGS_MAIL_FORM_NAME =
  'notificationsCenter';
export const PUSH_NOTIFICATIONS_SETTINGS_FORM_NAME = 'pushNotifications';

type FormValues = {
  emailNotifications: GroupMailNotificationSettings;
  notificationsCenter: GroupMailNotificationSettings;
  pushNotifications: GroupMailNotificationSettings;
};

const useGroupNotificationsSettingsDrawer = () => {
  const { t } = useTranslation(['group']);
  const { id } = useRequiredParams(['id']);
  const { userIsMember } = useGroupMember();
  const { enqueueSnackbar } = useHuSnackbar();

  const form = useForm<FormValues>({
    defaultValues: {
      emailNotifications: GroupMailNotificationSettings.OFF,
      notificationsCenter: GroupMailNotificationSettings.OFF,
      pushNotifications: GroupMailNotificationSettings.OFF,
    },
  });

  const { data: notificationConfigResponse } = useQuery(
    groupsKeys.notifications.mailNotificationSettings(id),
    () =>
      getGroupNotificationConfiguration(id, [
        GroupNotificationConfigurationConfigModes.EMAIL,
        GroupNotificationConfigurationConfigModes.NOTIFICATION_CENTER,
        GroupNotificationConfigurationConfigModes.PUSH,
      ]),
    {
      enabled: userIsMember,
    },
  );

  useEffect(() => {
    const findEnabled = (mode: GroupNotificationConfigurationConfigModes) =>
      notificationConfigResponse?.data?.configs.find(
        config => config.mode === mode,
      )?.enabled;

    const emailEnabled = findEnabled(
      GroupNotificationConfigurationConfigModes.EMAIL,
    );
    const notificationsCenterEnabled = findEnabled(
      GroupNotificationConfigurationConfigModes.NOTIFICATION_CENTER,
    );
    const pushEnabled = findEnabled(
      GroupNotificationConfigurationConfigModes.PUSH,
    );

    if (
      emailEnabled !== undefined ||
      notificationsCenterEnabled !== undefined ||
      pushEnabled !== undefined
    ) {
      const toSetting = (enabled: boolean | undefined) =>
        enabled
          ? GroupMailNotificationSettings.ON
          : GroupMailNotificationSettings.OFF;

      form.reset({
        emailNotifications: toSetting(emailEnabled),
        notificationsCenter: toSetting(notificationsCenterEnabled),
        pushNotifications: toSetting(pushEnabled),
      });
    }
  }, [notificationConfigResponse]);

  const {
    mutateAsync: updateMailConfiguration,
    isLoading: isUpdatingMailConfiguration,
  } = useMutation((enabled: boolean) =>
    updateGroupNotificationConfiguration(
      id,
      GroupNotificationConfigurationConfigModes.EMAIL,
      enabled,
    ),
  );
  const {
    mutateAsync: updateNotificationsCenterConfiguration,
    isLoading: isUpdatingNotificationsCenterConfiguration,
  } = useMutation((enabled: boolean) =>
    updateGroupNotificationConfiguration(
      id,
      GroupNotificationConfigurationConfigModes.NOTIFICATION_CENTER,
      enabled,
    ),
  );
  const {
    mutateAsync: updatePushConfiguration,
    isLoading: isUpdatingPushConfiguration,
  } = useMutation((enabled: boolean) =>
    updateGroupNotificationConfiguration(
      id,
      GroupNotificationConfigurationConfigModes.PUSH,
      enabled,
    ),
  );

  const isOn = (value: GroupMailNotificationSettings) =>
    value === GroupMailNotificationSettings.ON;

  const onSubmit = (data: FormValues) => {
    const emailNotifications = updateMailConfiguration(
      isOn(data.emailNotifications),
    );
    const notificationsCenter = updateNotificationsCenterConfiguration(
      isOn(data.notificationsCenter),
    );
    const pushNotifications = updatePushConfiguration(
      isOn(data.pushNotifications),
    );

    Promise.all([
      emailNotifications,
      notificationsCenter,
      pushNotifications,
    ]).then(() => {
      form.reset({}, { keepValues: true });
      closeDrawer();
      enqueueSnackbar({
        title: t('group:notifications_saved'),
        variant: 'success',
      });
    });
  };

  const { drawer, showDrawer, closeDrawer } = useDrawer(
    () => (
      <FormProvider {...form}>
        <GroupNotificationsSettings />
      </FormProvider>
    ),
    {
      title: t('group:notifications_tools'),
      primaryButtonProps: {
        children: t('general:save'),
        sx: { width: '100%' },
        disabled: !form.formState.isDirty,
        onClick: form.handleSubmit(onSubmit),
        loading:
          isUpdatingMailConfiguration ||
          isUpdatingNotificationsCenterConfiguration ||
          isUpdatingPushConfiguration,
      },
    },
  );

  return { drawer, showDrawer };
};

export default useGroupNotificationsSettingsDrawer;
