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

import { isNil } from 'lodash-es';
import { type GetDrawerConfiguration } from '@material-hu/hooks/useDrawerV2';

import HuAlert from '@material-hu/components/design-system/Alert';
import HuCircularProgress from '@material-hu/components/design-system/ProgressIndicators/Spinner';

import { getPolicyTypesByUserId } from 'src/services/vacations';
import { type MeUser } from 'src/types/user';
import { type PolicyTypes } from 'src/types/vacations';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { formFieldsRequestCreate } from '../../constant';
import {
  assignDefaultValues,
  type RequestCreateForm,
  useRequestCreate,
} from '../../hooks/useRequestCreate';
import { useRequestValidations } from '../../hooks/useRequestValidations';
import { resolveSelectedPolicyType, vacationsKeys } from '../../queries';
import { RequestForm } from '../requests/RequestForm';

import { CreateRequestFooter } from './footers/CreateRequestFooter';

export type CreateRequestDrawerProps = {
  policyTypes: PolicyTypes[];
  user: MeUser;
  isManagerRequesting?: boolean;
  policyTypeSelected?: { value: number; label: string };
  closePolicyTypeDrawer?: () => void;
  showingAllPolicies?: boolean;
};

export type RequiredPolicyTypeErrors = {
  policy: {
    name: string;
    id: number;
  };
};

export const useCreateRequestDrawer: GetDrawerConfiguration<
  CreateRequestDrawerProps
> = props => {
  const {
    policyTypes,
    user,
    closeDrawer,
    open,
    policyTypeSelected,
    closePolicyTypeDrawer,
    showingAllPolicies,
    isManagerRequesting = false,
  } = props;

  const { t } = useLokaliseTranslation('time_off');

  const form = useForm<RequestCreateForm>({
    defaultValues: assignDefaultValues(policyTypeSelected),
    mode: 'onChange',
  });

  const { isLoading: isLoadingPolicyTypes } = useQuery(
    vacationsKeys.policyTypes.listByUserId(user.id),
    () => getPolicyTypesByUserId(user.id),
    { select: r => r.data, enabled: !!user.id && isManagerRequesting && open },
  );

  const { isLoadingMutation, handleSubmit } = useRequestCreate({
    form,
    user,
    isManagerRequesting,
    closePolicyTypeDrawer,
    closeDrawer,
  });

  const policyTypeField = useWatch({
    control: form.control,
    name: formFieldsRequestCreate.policyTypeId,
  });

  const selectedPolicyTypeId = policyTypeField?.value;
  const selectedPolicyType = resolveSelectedPolicyType(
    selectedPolicyTypeId,
    user.id,
    policyTypes,
  );

  const {
    preview: {
      isLoadingRequestedDays,
      requestedDays,
      amountInMoney,
      amountInTime,
      errorsRequestedDays,
      warningsRequestedDays,
    },
    footer: {
      errorInAmountPerRequest,
      customError,
      requiredFields,
      currentBalance,
      datesAreSelected,
    },
    buttonStates: { isSubmitting, disableSubmit },
  } = useRequestValidations({
    policyType: selectedPolicyType,
    form,
    user,
    openDrawer: open,
    isManagerRequesting,
  });

  const showBalanceFooter = datesAreSelected && !isNil(selectedPolicyType);

  const renderFooter = () => {
    if (isLoadingRequestedDays) {
      return <HuCircularProgress centered />;
    }

    if (customError || requiredFields) {
      return (
        <HuAlert
          severity="error"
          title={customError?.title || t('verify_required_fields')}
          description={customError?.description}
        />
      );
    }

    if (showBalanceFooter) {
      return (
        <CreateRequestFooter
          policyType={selectedPolicyType}
          currentBalance={currentBalance}
          errorInAmountPerRequest={errorInAmountPerRequest}
          requestedDays={requestedDays}
          amountInMoney={amountInMoney}
          amountInTime={amountInTime}
          errorsRequestedDays={errorsRequestedDays}
          warningsRequestedDays={warningsRequestedDays}
          user={user}
          isManagerRequesting={isManagerRequesting}
        />
      );
    }

    return null;
  };

  const handleCloseDrawer = () => {
    form.reset();
    closeDrawer();
  };

  return {
    children: (
      <FormProvider {...form}>
        {isLoadingPolicyTypes && <HuCircularProgress centered />}
        {!isLoadingPolicyTypes && (
          <RequestForm
            amountInTime={amountInTime}
            user={user}
            isManagerRequesting={isManagerRequesting!}
            policyTypes={policyTypes}
            showingAllPolicies={showingAllPolicies!}
            policyType={selectedPolicyType}
            customError={customError}
            open={open}
          />
        )}
      </FormProvider>
    ),
    title: t('create_request'),
    primaryButtonProps: {
      children: t('send_request'),
      loading: isSubmitting || isLoadingMutation,
      onClick: handleSubmit,
      disabled: disableSubmit,
      sx: { width: '100%' },
    },
    footer: renderFooter(),
    onClose: handleCloseDrawer,
    hasBackButton: true,
    onBack: handleCloseDrawer,
  };
};
