import { useEffect, useState } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';

import Stack from '@material-hu/mui/Stack';

import {
  useGetManagerTypes,
  useHolidaysByCalendarYears,
  useVacations,
} from 'src/hooks/queryHooks/vacations';
import { type MeUser } from 'src/types/user';
import {
  ActivityType,
  ConsumptionType,
  type PolicyTypes,
  UnitVacations,
} from 'src/types/vacations';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { formFieldsRequestCreate } from '../../constant';
import {
  HoursRequestType,
  type RequestCreateForm,
} from '../../hooks/useRequestCreate';
import DatesInput from '../inputs/DatesInput';
import DescriptionInput from '../inputs/DescriptionInput';
import { DropZoneVacations } from '../inputs/DropZoneVacations';
import PolicyTypeInput from '../inputs/PolicyTypeInput';
import SellingBalanceRouter from '../inputs/sellingBalance/SellingBalanceRouter';
import { RequestedOnBehalfOf } from '../requestReport/RequestOnBehalfOf';
import { SkipApproval } from '../requestReport/SkipApproval';

import { HourRequestForm } from './HourRequestForm';
import RequestHourType from './RequestHourType';
import SubstituteApprover from './SubstituteApprover';

type Props = {
  user: MeUser;
  isManagerRequesting: boolean;
  isEditing?: boolean;
  policyTypes: PolicyTypes[];
  amountInTime: number;
  showingAllPolicies: boolean;
  policyType: PolicyTypes | undefined;
  customError: {
    title: string;
    description?: string;
  } | null;
  open?: boolean;
};

export const RequestForm = ({
  user,
  isManagerRequesting,
  isEditing,
  policyTypes,
  showingAllPolicies,
  amountInTime,
  policyType,
  customError,
  open,
}: Props) => {
  const form = useFormContext<RequestCreateForm>();
  const [currentYear, setCurrentYear] = useState(new Date().getFullYear());
  const { t } = useLokaliseTranslation('time_off');
  const { isManager, isAdmin } = useGetManagerTypes();
  const { manager } = useVacations();
  const managerHasRequests = manager?.hasRequests;
  const cantAssignSubstituteApprover =
    (isManager || isAdmin || managerHasRequests) &&
    policyType?.activityType === ActivityType.NON_WORK;

  const [policyTypeIdForm, fromDate, hourRequestType] = useWatch({
    control: form.control,
    name: [
      formFieldsRequestCreate.policyTypeId,
      formFieldsRequestCreate.fromDate,
      formFieldsRequestCreate.hoursRequestType,
    ],
  });

  const policyTypeId = policyTypeIdForm?.value;

  const needsCalendarHolidays =
    !!policyType?.requireMultiplesOfSeven || !!policyType?.requireMondayStart;

  const { holidays } = useHolidaysByCalendarYears({
    userId: user.id,
    year: currentYear,
    enabled: !!open && needsCalendarHolidays,
  });

  useEffect(() => {
    if (policyType?.unit === UnitVacations.DAYS) {
      form.setValue(formFieldsRequestCreate.hoursRequestType, null);
      form.setValue(
        formFieldsRequestCreate.consumptionTypeFromDate,
        ConsumptionType.FULL_DAY,
      );
      form.setValue(
        formFieldsRequestCreate.consumptionTypeToDate,
        ConsumptionType.FULL_DAY,
      );
    }
  }, [policyType?.unit, policyTypeId]);

  useEffect(() => {
    if (hourRequestType === HoursRequestType.LESS_THAN_ONE_DAY) {
      form.setValue(
        formFieldsRequestCreate.consumptionTypeFromDate,
        ConsumptionType.HOURS,
      );
      form.setValue(
        formFieldsRequestCreate.consumptionTypeToDate,
        ConsumptionType.HOURS,
      );
    }
    if (hourRequestType === HoursRequestType.MORE_THAN_ONE_DAY) {
      form.setValue(
        formFieldsRequestCreate.consumptionTypeFromDate,
        ConsumptionType.FULL_DAY,
      );
      form.setValue(
        formFieldsRequestCreate.consumptionTypeToDate,
        ConsumptionType.FULL_DAY,
      );
    }
  }, [hourRequestType]);

  const allowedToDisplayForm =
    policyType?.unit !== UnitVacations.HOURS || !!hourRequestType;

  const disabledToCompleteField = !policyTypeId;
  const disabledToCompleteToDate = !fromDate || disabledToCompleteField;
  const disabledField = disabledToCompleteField || isEditing;

  return (
    <Stack
      sx={{
        gap: 2,
        height: '100%',
        justifyContent: 'space-between',
      }}
    >
      <Stack sx={{ pb: 2, gap: 3 }}>
        {isManagerRequesting && <RequestedOnBehalfOf user={user} />}

        <PolicyTypeInput
          name={formFieldsRequestCreate.policyTypeId}
          policyTypes={policyTypes}
          showingAllPolicies={showingAllPolicies}
        />
        {!customError && (
          <>
            {policyType?.unit === UnitVacations.HOURS && <RequestHourType />}
            {allowedToDisplayForm && (
              <>
                <DatesInput
                  isManagerRequesting={isManagerRequesting}
                  nameDateInput={formFieldsRequestCreate.fromDate}
                  nameConsumptionTypeInput={
                    formFieldsRequestCreate.consumptionTypeFromDate
                  }
                  description={
                    hourRequestType === HoursRequestType.LESS_THAN_ONE_DAY
                      ? t('request_day_description')
                      : t('select_start_date')
                  }
                  user={user}
                  datePickerProps={{
                    label:
                      hourRequestType === HoursRequestType.LESS_THAN_ONE_DAY
                        ? t('what_day_request_title')
                        : t('since_when'),
                    disabled: disabledToCompleteField,
                    maxDate: new Date(
                      `${new Date().getFullYear() + (policyType?.noFutureRequests ? 0 : 1)}-12-31`,
                    ),
                    onMonthChange: (date: Date) => {
                      setCurrentYear(date.getFullYear());
                    },
                    onYearChange: (date: Date) => {
                      setCurrentYear(date.getFullYear());
                    },
                  }}
                  holidays={holidays}
                  policyTypeId={policyTypeId}
                />
                {hourRequestType !== HoursRequestType.LESS_THAN_ONE_DAY && (
                  <DatesInput
                    isManagerRequesting={isManagerRequesting}
                    nameDateInput={formFieldsRequestCreate.toDate}
                    nameConsumptionTypeInput={
                      formFieldsRequestCreate.consumptionTypeToDate
                    }
                    description={t('select_end_date')}
                    rules={{
                      validateIsAfterDate: {
                        dateToCompare: fromDate || '',
                        allowEqual: true,
                        message: t('from_date_is_after_to_date_error'),
                      },
                    }}
                    user={user}
                    holidays={holidays}
                    datePickerProps={{
                      label: t('until_when'),
                      minDate: fromDate,
                      disabled: disabledToCompleteToDate,
                    }}
                    policyTypeId={policyTypeId}
                  />
                )}
                {policyType?.unit === UnitVacations.HOURS &&
                  hourRequestType === HoursRequestType.LESS_THAN_ONE_DAY && (
                    <HourRequestForm
                      minimumTimeFraction={policyType?.minimumTimeFraction}
                    />
                  )}
                <SellingBalanceRouter
                  amountInTime={amountInTime}
                  policyType={policyType}
                />
                <DescriptionInput
                  name={formFieldsRequestCreate.description}
                  policyType={policyType}
                  disabled={disabledField}
                />
                <DropZoneVacations
                  name={formFieldsRequestCreate.files}
                  policyTypeId={policyTypeId}
                  userId={isManagerRequesting ? user.id : undefined}
                  disabled={disabledField}
                />
                {cantAssignSubstituteApprover && (
                  <SubstituteApprover disabled={disabledField} />
                )}
                {!!(isManagerRequesting && isAdmin && !isEditing) && (
                  <SkipApproval />
                )}
              </>
            )}
          </>
        )}
      </Stack>
    </Stack>
  );
};
