import { useQuery } from 'react-query';

import { useDrawerV2 } from '@material-hu/hooks/useDrawerV2';
import { useModal } from '@material-hu/hooks/useModal';
import {
  IconCheck,
  IconX as IconClose,
  IconDotsVertical,
  IconEdit,
  IconEye,
  IconMail,
  IconTrash,
} from '@material-hu/icons/tabler';
import IconButton from '@material-hu/mui/IconButton';
import Typography from '@material-hu/mui/Typography';

import MenuList, {
  type MenuListProps,
} from '@material-hu/components/composed-components/MenuList';
import NewModal from '@material-hu/components/deprecated/NewModal';

import { useAuth } from 'src/contexts/JWTContext';
import {
  useGetManagerTypes,
  useSendReminderRequest,
} from 'src/hooks/queryHooks/vacations';
import useGeneralError from 'src/hooks/useGeneralError';
import {
  updateRequestsCollaborator,
  updateRequestsManager,
  updateVacations,
  vacationsKeys,
} from 'src/pages/dashboard/timeOff/queries';
import { getApprovalStep, getVacationsDetail } from 'src/services/vacations';
import {
  type ResponseRequestTimeOff,
  VacationActionsSources,
  VacationStatus,
} from 'src/types/vacations';
import { insertIf } from 'src/utils/arrays';
import { useLokaliseTranslation } from 'src/utils/i18n';
import {
  getHasEnabledApproveOrRejectRequest,
  getHasEnabledCancelRequest,
  getHasEnabledSendReminder,
  getStepToEvaluate,
  updateNotificationsManager,
} from 'src/utils/vacations';

import useEditRequestDrawer from '../Drawers/useEditRequestDrawer';
import useResolutionDrawer from '../shared/useResolutionDrawer';

export type RequestTableActionsMenu = {
  requestId: number;
} | null;

export type RequestActionsMenuProps = {
  vacations: ResponseRequestTimeOff;
  onOpenDrawer: (requestId: number) => void;
  isManagerView: boolean;
  menuOpen: boolean;
  onOpenMenu: () => void;
  onCloseMenu: () => void;
};

export const RequestActionsMenu = (props: RequestActionsMenuProps) => {
  const {
    vacations,
    onOpenDrawer,
    isManagerView,
    menuOpen,
    onOpenMenu,
    onCloseMenu,
  } = props;

  const handleOpenMenuClick = () => {
    onOpenMenu();
  };

  const { t } = useLokaliseTranslation('time_off');
  const showGeneralError = useGeneralError();
  const { isAdmin } = useGetManagerTypes();
  const { user } = useAuth();

  const hasEnabledEditRequest =
    isAdmin && vacations.state === VacationStatus.APPROVED && isManagerView;

  const { data: approvalStepsData, isLoading: approvalStepsIsLoading } =
    useQuery(
      vacationsKeys.steps(vacations.id),
      () => getApprovalStep(vacations.id),
      {
        onError: err => {
          showGeneralError(err, t('error_loading_approvers'));
        },
        enabled: menuOpen,
      },
    );

  const { data: vacationDetail, isLoading: isLoadingVacationDetail } = useQuery(
    vacationsKeys.detail(vacations.id),
    () => getVacationsDetail(vacations.id),
    {
      select: res => res.data,
      enabled: menuOpen,
    },
  );

  const approvalSteps = approvalStepsData?.data || [];
  const isSingleApprovalStep = approvalSteps.length === 1;
  const stepToEvaluate = getStepToEvaluate(approvalSteps);

  const openDetailRequest = () => {
    onOpenDrawer(vacations.id);
    onCloseMenu();
  };

  const successUpdateRequest = () => {
    updateVacations(vacations.id);
    updateRequestsManager();
    if (isManagerView) {
      updateRequestsManager();
    } else {
      updateRequestsCollaborator();
    }
  };

  const handleOnSuccessApproveOrRejectRequest = (state: VacationStatus) => {
    updateNotificationsManager({
      approvalSteps,
      currentPosition: stepToEvaluate?.position,
      user,
      state,
    });
    successUpdateRequest();
  };

  const { drawer: editRequestDrawer, showDrawer: showEditRequestDrawer } =
    useDrawerV2(useEditRequestDrawer);

  const { drawer: approveDrawer, mutation: approveMutation } =
    useResolutionDrawer({
      mutationProps: {
        requestId: vacations.id,
        stepId: stepToEvaluate?.id,
        policyTypeId: vacations.policyType?.id,
        state: VacationStatus.APPROVED,
        source: VacationActionsSources.MANAGEMENT_LIST,
        onSuccess: () =>
          handleOnSuccessApproveOrRejectRequest(VacationStatus.APPROVED),
        onError: onCloseMenu,
        isSingleApprovalStep,
      },
    });

  const { mutation: rejectMutation, drawer: rejectDrawer } =
    useResolutionDrawer({
      mutationProps: {
        requestId: vacations.id,
        stepId: stepToEvaluate?.id,
        policyTypeId: vacations.policyType?.id,
        state: VacationStatus.REJECTED,
        source: VacationActionsSources.MANAGEMENT_LIST,
        onSuccess: () =>
          handleOnSuccessApproveOrRejectRequest(VacationStatus.REJECTED),
        onError: onCloseMenu,

        isSingleApprovalStep,
      },
    });

  const { mutation: cancelMutation, drawer: cancelDrawer } =
    useResolutionDrawer({
      mutationProps: {
        requestId: vacations.id,
        policyTypeId: vacations.policyType?.id,
        state: VacationStatus.CANCELLED,
        source: isManagerView
          ? VacationActionsSources.MANAGEMENT_LIST
          : VacationActionsSources.COLLABORATOR_LIST,
        onSuccess: successUpdateRequest,
        onError: onCloseMenu,
        isSingleApprovalStep,
      },
    });

  const { mutate: sendReminderMutate, isLoading: isLoadingSendReminder } =
    useSendReminderRequest({
      requestId: vacations.id,
      onSettled: () => {
        closeSendReminderModal();
      },
    });

  const {
    modal: sendReminderModal,
    showModal: showSendReminderModal,
    closeModal: closeSendReminderModal,
  } = useModal(() => (
    <NewModal
      title={t('send_reminder_modal_title')}
      primaryButtonProps={{
        children: t('confirm'),
        onClick: () => sendReminderMutate(),
        loading: isLoadingSendReminder,
        color: 'primary',
      }}
      secondaryButtonProps={{
        children: t('cancel'),
        onClick: () => closeSendReminderModal(),
        disabled: isLoadingSendReminder,
        color: 'secondary',
      }}
      body={<Typography>{t('send_reminder_modal_body')}</Typography>}
      onClose={() => closeSendReminderModal()}
    />
  ));

  const approveVacationRequest = () => {
    approveDrawer.showDrawer();
    onCloseMenu();
  };
  const cancelVacationRequest = () => {
    cancelDrawer.showDrawer();
    onCloseMenu();
  };

  const rejectVacationRequest = () => {
    rejectDrawer.showDrawer();
    onCloseMenu();
  };

  const showSendReminderModalHandler = () => {
    showSendReminderModal();
    onCloseMenu();
  };

  const editRequest = () => {
    showEditRequestDrawer({ vacationDetail });
    onCloseMenu();
  };

  const disableMenuOptions =
    approvalStepsIsLoading ||
    rejectMutation.isLoading ||
    approveMutation.isLoading ||
    cancelMutation.isLoading ||
    isLoadingVacationDetail;

  const hasEnabledApproveOrRejectRequest = getHasEnabledApproveOrRejectRequest(
    isManagerView,
    vacations,
    isAdmin,
  );

  const hasEnabledSendReminder = getHasEnabledSendReminder(
    isManagerView,
    vacations,
    isAdmin,
  );

  const hasEnabledCancelRequest = getHasEnabledCancelRequest(
    isManagerView,
    vacationDetail!,
    isAdmin,
    user?.id!,
    approvalSteps,
  );

  const options: MenuListProps['options'] = [
    {
      title: t('see_detail'),
      onClick: openDetailRequest,
      Icon: IconEye,
      disabled: disableMenuOptions,
    },
    ...insertIf(hasEnabledEditRequest, {
      title: t('edit'),
      onClick: editRequest,
      Icon: IconEdit,
      disabled: disableMenuOptions,
    }),
    ...insertIf(hasEnabledSendReminder, {
      title: t('send_reminder'),
      onClick: showSendReminderModalHandler,
      Icon: IconMail,
      disabled: disableMenuOptions,
    }),
    ...insertIf(hasEnabledApproveOrRejectRequest, {
      title: t('approve'),
      onClick: approveVacationRequest,
      Icon: IconCheck,
      disabled: disableMenuOptions,
    }),
    ...insertIf(hasEnabledApproveOrRejectRequest, {
      title: t('reject'),
      onClick: rejectVacationRequest,
      Icon: IconClose,
      disabled: disableMenuOptions,
    }),
    ...insertIf(hasEnabledCancelRequest, {
      title: t('cancel_request'),
      onClick: cancelVacationRequest,
      Icon: IconTrash,
      disabled: disableMenuOptions,
    }),
  ];

  return (
    <>
      {editRequestDrawer}
      {sendReminderModal}
      {approveDrawer.drawer}
      {rejectDrawer.drawer}
      {cancelDrawer.drawer}
      <MenuList
        customButton={
          <IconButton
            onClick={handleOpenMenuClick}
            aria-label={t('advanced_options')}
          >
            <IconDotsVertical />
          </IconButton>
        }
        options={options}
      />
    </>
  );
};

export default RequestActionsMenu;
