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

import { isBefore, parseISO, startOfDay } from 'date-fns';
import { type GetDrawerConfiguration } from '@material-hu/hooks/useDrawerV2';
import Stack from '@material-hu/mui/Stack';

import Alert from '@material-hu/components/design-system/Alert';
import { type FileCardType } from '@material-hu/components/design-system/FileCard/types';
import HuCircularProgress from '@material-hu/components/design-system/ProgressIndicators/Spinner';

import { useAuth } from 'src/contexts/JWTContext';
import { useGetManagerTypes } from 'src/hooks/queryHooks/vacations';
import useGeneralError from 'src/hooks/useGeneralError';
import { getApprovalStep, getVacationsDetail } from 'src/services/vacations';
import { VacationStatus } from 'src/types/vacations';
import { useLokaliseTranslation } from 'src/utils/i18n';
import {
  getDefaultValueFiles,
  getHasEnabledApproveOrRejectRequest,
  getHasEnabledCancelRequest,
  getStepToEvaluate,
} from 'src/utils/vacations';

import {
  updateAllRequestInCalendar,
  updateRequestsCollaborator,
  updateRequestsManager,
  updateVacations,
  vacationsKeys,
} from '../../queries';
import { AvailableActions } from '../requestReport';
import RequestAlertCreator from '../requestReport/RequestAlertCreator';

import FullDataRequest from './FullDataRequest';

type RequestDetailsDrawer = {
  requestId: number;
  isManagerView?: boolean;
  openWithCalendar?: boolean;
};

export type FormFiles = {
  files: FileCardType[];
};

export const getRequestDetailsDrawer: GetDrawerConfiguration<
  RequestDetailsDrawer
> = props => {
  const {
    requestId,
    isManagerView = false,
    closeDrawer,
    open,
    openWithCalendar,
  } = props;

  const { user: currentUser } = useAuth();

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

  const form = useForm<FormFiles>({
    defaultValues: {
      files: [],
    },
  });

  const { data: vacationDetail, isLoading: vacationIsLoading } = useQuery(
    vacationsKeys.detail(requestId),
    () => getVacationsDetail(requestId),
    {
      select: res => res.data,
      onSuccess: response => {
        form.setValue('files', getDefaultValueFiles(response) ?? []);
      },
      onError: err => {
        showGeneralError(err, t('error_loading_request_one'));
      },
      enabled: open && !!requestId,
    },
  );

  const { data: approvalStepsData, isLoading: approvalStepsIsLoading } =
    useQuery(vacationsKeys.steps(requestId), () => getApprovalStep(requestId), {
      onError: err => {
        showGeneralError(err, t('error_loading_approvers'));
      },
      enabled: open && !!vacationDetail?.state,
    });

  const isLoading = vacationIsLoading || approvalStepsIsLoading;

  const successUpdateRequest = () => {
    closeDrawer();
    updateVacations(requestId);
    if (isManagerView) {
      updateRequestsManager();
      if (openWithCalendar) {
        updateAllRequestInCalendar();
      }
    } else {
      updateRequestsCollaborator();
    }
  };

  const creator = vacationDetail?.creator;

  const approvalSteps = approvalStepsData?.data || [];
  const pendingStep = getStepToEvaluate(approvalSteps);
  const isCurrentUserInApprovers = pendingStep?.potentialApprovers?.some(
    approver => approver.id === currentUser?.id,
  );

  const isIssuerSameAsCreator =
    vacationDetail?.issuer?.id === vacationDetail?.creator?.id;

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

  const enabledToEditRequest =
    isAdmin &&
    vacationDetail?.state === VacationStatus.APPROVED &&
    isManagerView;

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

  const showActionsButtons =
    hasEnabledApproveOrRejectRequest ||
    hasEnabledCancelRequest ||
    enabledToEditRequest;

  const isRequestPreviousCurrentDate = isBefore(
    new Date(parseISO(vacationDetail?.from.date || '')),
    startOfDay(new Date(vacationDetail?.createdAt || '')),
  );

  const showRequestPreviousCurrentDateAlert =
    isRequestPreviousCurrentDate &&
    vacationDetail?.state === VacationStatus.IN_PROGRESS;

  const showRequestCreatorAlert = !isIssuerSameAsCreator && !isLoading;

  const showResolveRequestAsAdminAlert =
    isAdmin &&
    isManagerView &&
    vacationDetail?.state === VacationStatus.IN_PROGRESS &&
    !isCurrentUserInApprovers &&
    !isLoading;

  const shouldRenderFooter =
    showRequestCreatorAlert ||
    showRequestPreviousCurrentDateAlert ||
    showActionsButtons ||
    showResolveRequestAsAdminAlert;

  return {
    title: t('vacations_details'),
    children: (
      <>
        {isLoading && <HuCircularProgress centered />}
        {!isLoading && vacationDetail && (
          <FormProvider {...form}>
            <FullDataRequest
              vacationDetail={vacationDetail}
              isManagerView={isManagerView}
              requestId={requestId}
              open={open}
            />
          </FormProvider>
        )}
      </>
    ),
    footer: shouldRenderFooter && (
      <Stack
        sx={{
          gap: '9px',
          width: '100%',
        }}
      >
        {showRequestCreatorAlert && creator && (
          <RequestAlertCreator user={creator} />
        )}
        {showRequestPreviousCurrentDateAlert && (
          <Alert
            severity="warning"
            title={t('period_before_current_date')}
            hasClose
          />
        )}
        {showResolveRequestAsAdminAlert && (
          <Alert
            severity="info"
            title={t('resolve_request_as_admin')}
            description={t('resolve_request_as_admin_description')}
            hasClose
          />
        )}
        {showActionsButtons && vacationDetail && (
          <AvailableActions
            requestId={requestId}
            vacationDetail={vacationDetail}
            approvalSteps={approvalSteps}
            onClose={closeDrawer}
            successUpdateRequest={successUpdateRequest}
            hasEnabledApproveOrRejectRequest={hasEnabledApproveOrRejectRequest}
            hasEnabledCancelRequest={hasEnabledCancelRequest}
            hasEnabledEditRequest={enabledToEditRequest}
            isManagerView={isManagerView}
            cancelProps={{
              backButton: true,
            }}
          />
        )}
      </Stack>
    ),
  };
};
