import { Fragment, useMemo, useState } from 'react';

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

import useSnackbar from '@material-hu/components/design-system/Snackbar';

import { type Shift } from 'src/types/shifts';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { useRepositoryDrawer } from '../../../ShiftsRepositoryDrawer/useRepositoryDrawer';

import AddShiftDrawerContent from './AddShiftDrawerContent';
import { shiftOverlapsWithAny } from './shiftOverlap';

import { type RotationDayShiftRef } from '../../../../form';

type Params = {
  onConfirm: (shift: Shift) => void;
};

type ShowDrawerOptions = {
  /**
   * Shifts already assigned to the day the user is adding to. Used to flag
   * time overlaps with the shift being picked. Defaults to no existing
   * shifts (i.e. the user is creating a brand-new day).
   */
  existingShifts?: RotationDayShiftRef[];
};

export const useAddShiftDrawer = ({ onConfirm }: Params) => {
  const { t } = useLokaliseTranslation('shifts');
  const { enqueueSnackbar } = useSnackbar();
  const [selectedShift, setSelectedShift] = useState<Shift | null>(null);
  const [existingShifts, setExistingShifts] = useState<RotationDayShiftRef[]>(
    [],
  );

  const handleSelect = (shift: Shift) => {
    setSelectedShift(prev => (prev?.id === shift.id ? null : shift));
  };

  const resetState = () => {
    setSelectedShift(null);
    setExistingShifts([]);
  };

  const hasOverlap = useMemo(() => {
    if (!selectedShift || existingShifts.length === 0) return false;
    return shiftOverlapsWithAny(selectedShift, existingShifts);
  }, [selectedShift, existingShifts]);

  const handleTemplateCreated = (shift: Shift) => {
    if (
      existingShifts.length > 0 &&
      shiftOverlapsWithAny(shift, existingShifts)
    ) {
      enqueueSnackbar({
        title: t('templates.form.overlap'),
        description: t('templates.form.overlap_description'),
        variant: 'error',
      });
      return;
    }
    closeAddShiftDrawer();
    resetState();
    onConfirm(shift);
    enqueueSnackbar({
      title: t('templates.feedback.success_shift'),
      variant: 'success',
    });
  };

  const handleTemplateCreateError = () => {
    enqueueSnackbar({
      title: t('templates.feedback.error_shift'),
      description: t('actions.try_again'),
      variant: 'error',
    });
  };

  const { RepositoryDrawer, showRepositoryDrawer } = useRepositoryDrawer({
    onTemplateCreated: handleTemplateCreated,
    onTemplateCreateError: handleTemplateCreateError,
    disableDefaultSnackbar: true,
  });

  const {
    showDrawer: showAddShiftDrawerInternal,
    drawer: BaseAddShiftDrawer,
    closeDrawer: closeAddShiftDrawer,
  } = useDrawerV2(({ closeDrawer }) => ({
    title: t('templates.form.add_shift'),
    children: (
      <AddShiftDrawerContent
        selectedShift={selectedShift}
        hasOverlap={hasOverlap}
        onSelect={handleSelect}
        onCreateNewShift={() => showRepositoryDrawer()}
      />
    ),
    onClose: () => {
      resetState();
      closeDrawer();
    },
    primaryButtonProps: {
      children: t('templates.form.add_shift'),
      fullWidth: true,
      disabled: !selectedShift || hasOverlap,
      onClick: () => {
        if (!selectedShift || hasOverlap) return;
        const shift = selectedShift;
        closeDrawer();
        resetState();
        onConfirm(shift);
        enqueueSnackbar({
          title: t('templates.feedback.success_shift'),
          variant: 'success',
        });
      },
    },
  }));

  const AddShiftDrawer = (
    <Fragment>
      {BaseAddShiftDrawer}
      {RepositoryDrawer}
    </Fragment>
  );

  const showAddShiftDrawer = (options?: ShowDrawerOptions) => {
    setSelectedShift(null);
    setExistingShifts(options?.existingShifts ?? []);
    showAddShiftDrawerInternal({});
  };

  return {
    AddShiftDrawer,
    showAddShiftDrawer,
  };
};
