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

import { useDrawerV2 } from '@material-hu/hooks/useDrawerV2';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import Alert from '@material-hu/components/design-system/Alert';
import FormAutocomplete from '@material-hu/components/design-system/Inputs/Autocomplete/form';
import FormInputClassic from '@material-hu/components/design-system/Inputs/Classic/form';
import useSnackbar from '@material-hu/components/design-system/Snackbar';
import Title from '@material-hu/components/design-system/Title';

import { useRequiredAuth } from 'src/contexts/JWTContext';
import { type UserActionSource } from 'src/pages/dashboard/Users/hooks/useUserActions';
import { usersKeys } from 'src/pages/dashboard/Users/queries';
import { updateUserStatus } from 'src/services/usersService';
import { type DeactivationReason, type User, UserStatus } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { LogEvents, logEvent } from 'src/utils/logging';
import { getFullname } from 'src/utils/userUtils';

import HugoPotentialBossAutocomplete from 'src/components/UsersAutocomplete/HugoPotentialBossAutocomplete';

import { useDeactivationReasons } from './useDeactivationReasons';

const DEACTIVATE_FORM_DEFAULTS = {
  deactivateReason: null as { value: DeactivationReason } | null,
  deactivateObservation: '',
  deactivateNewBoss: null as User | null,
};

export type UseDeactivateUserDrawerParams = {
  user: User;
  userBoss?: User;
  hasSubordinates: boolean;
  source?: UserActionSource;
};

export const useDeactivateUserDrawer = ({
  user,
  userBoss,
  hasSubordinates,
  source,
}: UseDeactivateUserDrawerParams) => {
  const queryClient = useQueryClient();
  const { instance, user: loggedUser } = useRequiredAuth();
  const { t } = useLokaliseTranslation('users');
  const { enqueueSnackbar } = useSnackbar();

  const fullName = getFullname(user ?? undefined);

  const { data: deactivationReasons = [] } = useDeactivationReasons(response =>
    response.data.map(r => ({
      value: r,
      label: t(`deactivation_reasons.${r}`),
    })),
  );

  const form = useForm<typeof DEACTIVATE_FORM_DEFAULTS>({
    defaultValues: DEACTIVATE_FORM_DEFAULTS,
  });

  const deactivationReason = useWatch({
    control: form.control,
    name: 'deactivateReason',
  })?.value;

  useEffect(() => {
    if (deactivationReason && user?.id) {
      logEvent(LogEvents.USER_DEACTIVATION_REASON_SELECTED, {
        targetUserId: user.id,
        deactivationReason,
      });
    }
  }, [deactivationReason, user?.id]);

  const { mutate, isLoading } = useMutation(
    (_: { handleClose: () => void }) => {
      const { deactivateNewBoss, deactivateReason, deactivateObservation } =
        form.getValues();
      return updateUserStatus(user.id, {
        status: UserStatus.DEACTIVATED,
        newBossId: deactivateNewBoss?.id || userBoss?.id,
        deactivationReason: deactivateReason?.value || null,
        deactivationObservation: deactivateObservation.trim() || null,
      });
    },
    {
      onSuccess: async (_, { handleClose }) => {
        enqueueSnackbar({ title: t('user_deactivated'), variant: 'success' });
        logEvent(LogEvents.USER_DEACTIVATION_SUCCESS_VIEWED, {
          targetUserId: user.id,
        });
        await queryClient.invalidateQueries(usersKeys.user(user.id));
        await queryClient.invalidateQueries(usersKeys.all());
        logEvent(LogEvents.USER_STATUS_CHANGE, {
          userId: user.id,
          employeeInternalId: user.employeeInternalId,
          actorId: loggedUser.id,
          status: UserStatus.DEACTIVATED,
          instanceId: instance.id,
        });
        handleClose();
      },
    },
  );

  const optionalLabel = (label: string) =>
    `${label} (${t('general:optional').toLowerCase()})`;

  const { drawer: deactivateUserDrawer, showDrawer } = useDrawerV2(
    ({ closeDrawer }) => {
      const handleClose = () => {
        form.reset(DEACTIVATE_FORM_DEFAULTS);
        closeDrawer();
      };

      return {
        title: t('deactivate_name', { name: fullName }),
        onClose: () => handleClose(),
        primaryButtonProps: {
          children: t('general:deactivate'),
          onClick: () => {
            logEvent(LogEvents.USER_DEACTIVATED, {
              deactivationReason,
              targetUserId: user.id,
              hasObservation: !!form.getValues('deactivateObservation').trim(),
            });
            mutate({ handleClose });
          },
          loading: isLoading,
        },
        secondaryButtonProps: {
          children: t('general:cancel'),
          onClick: handleClose,
        },
        children: (
          <FormProvider {...form}>
            <Stack sx={{ gap: 2 }}>
              <Typography variant="globalS">
                {t('deactivate_info_body')}
              </Typography>
              <Stack
                sx={{
                  bgcolor: ({ palette }) =>
                    palette.new?.background?.layout?.default,
                  borderRadius: 2,
                  p: 2,
                  gap: 2,
                }}
              >
                <FormAutocomplete
                  name="deactivateReason"
                  options={deactivationReasons}
                  autocompleteProps={{
                    label: optionalLabel(t('deactivation_reason')),
                    placeholder: t('general:select'),
                    isServerFiltered: false,
                  }}
                />
                <FormInputClassic
                  name="deactivateObservation"
                  inputProps={{
                    label: optionalLabel(t('observations')),
                    placeholder: t('general:write_here'),
                    multiline: true,
                    minRows: 5,
                    maxRows: 5,
                    hasCounter: false,
                  }}
                />
              </Stack>
              {hasSubordinates && (
                <Stack
                  sx={{
                    bgcolor: ({ palette }) =>
                      palette.new?.background?.layout?.default,
                    borderRadius: 2,
                    p: 2,
                    gap: 1,
                  }}
                >
                  <Title
                    title={t('boss_replace_optional')}
                    description={t('boss_replace_helper', { name: fullName })}
                  />
                  <HugoPotentialBossAutocomplete
                    name="deactivateNewBoss"
                    potentialBossesId={user.id}
                    autocompleteProps={{
                      placeholder: t('general:select'),
                    }}
                  />
                </Stack>
              )}
            </Stack>
          </FormProvider>
        ),
        footer: hasSubordinates && (
          <Alert
            severity="warning"
            title={t('deactivate_boss_warning', { name: fullName })}
          />
        ),
      };
    },
  );

  const openDeactivateUser = () => {
    logEvent(LogEvents.USER_DEACTIVATION_DRAWER_VIEWED, {
      targetUserId: user.id,
      source,
      drawerType: hasSubordinates ? 'direct_manager' : 'collaborator',
    });
    showDrawer({});
  };

  return { openDeactivateUser, deactivateUserDrawer };
};
