import { type FC, useCallback, useMemo, useState } from 'react';
import { useFormContext } from 'react-hook-form';

import { useModal } from '@material-hu/hooks/useModal';
import { IconFilter } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuAlert from '@material-hu/components/design-system/Alert';
import HuDialog from '@material-hu/components/design-system/Dialog';
import HuDrawer from '@material-hu/components/design-system/Drawer';
import HuFormInputClassic from '@material-hu/components/design-system/Inputs/Classic/form';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';

import { type User } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { validateRequired } from 'src/utils/validation';

import { AGENTS_PAGE_SIZE, HELP_DESK_NAME_MAX_LENGTH } from '../../constants';
import { type HelpDesk } from '../../types';
import { isSameUserList } from '../../utils';
import { newHelpDeskFields } from '../form';
import { type HelpDeskForm } from '../HelpDesks';
import useAgentSelector from '../hooks/useAgentSelector';

import AgentListDrawer from './AgentListDrawer';
import AgentSelector from './AgentSelector';
import BadgeCountButton from './BadgeCountButton';
import SegmentFilterDrawer from './SegmentFilterDrawer';

type Props = {
  open: boolean;
  onClose: () => void;
  onConfirm: () => void;
  onCancel: () => void;
  loading: boolean;
  isEdit: boolean;
  appliedSegmentations: number[];
  setAppliedSegmentations: (segmentations: number[]) => void;
  duplicateEntity: string | null;
  selectedHelpDesk: HelpDesk | null;
};

const CreateHelpDeskDrawer: FC<Props> = ({
  open,
  onClose,
  onConfirm,
  onCancel,
  loading,
  isEdit,
  appliedSegmentations,
  setAppliedSegmentations,
  duplicateEntity,
  selectedHelpDesk,
}) => {
  const { t } = useLokaliseTranslation(['service_management', 'general']);
  const [isFilterDrawerOpen, setIsFilterDrawerOpen] = useState(false);
  const [isSelectedAgentsDrawerOpen, setIsSelectedAgentsDrawerOpen] =
    useState(false);

  const {
    coordinatorsQuery,
    setCoordinatorsQuery,
    coordinators,
    isLoading,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isSuccess,
    isEmpty,
    isEmptySearch,
    segmentationGroups,
    segmentationGroupsIsLoading,
    segmentationGroupsCount,
    resetQuery,
  } = useAgentSelector({
    limit: AGENTS_PAGE_SIZE,
    appliedSegmentations,
  });

  const {
    setValue,
    getValues,
    watch,
    formState: { isValid },
  } = useFormContext<HelpDeskForm>();

  const selectedCoordinators = watch(newHelpDeskFields.coordinators);

  const duplicateCheckValidation = useCallback(
    (value: string) => {
      if (duplicateEntity && duplicateEntity === value) {
        return t('NAME_ALREADY_IN_USE');
      }
      return true;
    },
    [duplicateEntity, t],
  );

  const validationRules = useMemo(
    () => ({
      ...validateRequired(t('REQUIRED_FIELD')),
      validate: {
        duplicateCheck: duplicateCheckValidation,
      },
    }),
    [duplicateCheckValidation, t],
  );

  const handleSelectAllCoordinators = () => {
    // Check if all coordinators are already selected
    const allSelected = coordinators.every(coordinator =>
      selectedCoordinators.some(selected => selected.id === coordinator.id),
    );

    if (allSelected) {
      // If all are selected, remove them all
      const filteredCoordinators = selectedCoordinators.filter(
        selected =>
          !coordinators.some(coordinator => coordinator.id === selected.id),
      );
      setValue(newHelpDeskFields.coordinators, filteredCoordinators);
    } else {
      // Add only coordinators that are not already selected
      const newSelectedCoordinators = [
        ...selectedCoordinators,
        ...coordinators.filter(
          coordinator =>
            !selectedCoordinators.some(
              selected => selected.id === coordinator.id,
            ),
        ),
      ];
      setValue(newHelpDeskFields.coordinators, newSelectedCoordinators);
    }
  };

  const handleSelectCoordinator = (coordinator: User) => {
    // Check if coordinator is already selected
    const isSelected = selectedCoordinators.some(
      selected => selected.id === coordinator.id,
    );

    if (isSelected) {
      // If already selected, remove it
      const filteredCoordinators = selectedCoordinators.filter(
        selected => selected.id !== coordinator.id,
      );
      setValue(newHelpDeskFields.coordinators, filteredCoordinators);
    } else {
      // If not selected, add it
      setValue(newHelpDeskFields.coordinators, [
        ...selectedCoordinators,
        coordinator,
      ]);
    }
  };

  const handleDeleteCoordinator = (coordinatorId: number) => {
    const filteredCoordinators = selectedCoordinators.filter(
      selected => selected.id !== coordinatorId,
    );
    setValue(newHelpDeskFields.coordinators, filteredCoordinators);
  };

  const handleApplySegmentFilters = () => {
    setAppliedSegmentations(getValues('segmentations'));
    setIsFilterDrawerOpen(false);
  };

  const handleBackFromSegmentFilters = () => {
    setIsFilterDrawerOpen(false);
    // Restore form value to previous state
    setValue('segmentations', appliedSegmentations);
  };

  const handleResetFilters = () => {
    setValue('segmentations', []);
  };

  const handleClose = () => {
    setCoordinatorsQuery('');
    onClose();
  };

  const handleCancel = () => {
    setCoordinatorsQuery('');
    onCancel();
  };

  const handleSave = () => {
    if (!isEdit) {
      // New help desk, save without confirmation
      handleConfirmSave();
      return;
    }

    const formValues = getValues();
    const hasNameChanged = formValues.name !== selectedHelpDesk?.name;
    const haveCoordinatorsChanged = !isSameUserList(
      formValues.coordinators,
      selectedHelpDesk?.coordinators ?? [],
    );

    // Form values have changed, ask for confirmation
    if (hasNameChanged || haveCoordinatorsChanged) {
      confirmEditModal.showModal();
    } else {
      handleConfirmSave();
    }
  };

  const handleConfirmSave = () => {
    resetQuery();
    onConfirm();
  };

  // Memoize computed values to prevent recalculation on every render
  const disableCreateButton = useMemo(
    () => !isValid || selectedCoordinators.length === 0,
    [isValid, selectedCoordinators.length],
  );

  const showErrorAlert = useMemo(
    () => isEdit && selectedCoordinators.length === 0,
    [isEdit, selectedCoordinators.length],
  );

  const confirmEditModal = useModal(() => (
    <HuDialog
      title={t('confirm_edit_help_desk')}
      textBody={t('confirm_edit_help_desk_description')}
      onClose={confirmEditModal.closeModal}
      primaryButtonProps={{
        children: t('general:confirm'),
        onClick: () => {
          handleConfirmSave();
          confirmEditModal.closeModal();
        },
        loading,
      }}
      secondaryButtonProps={{
        children: t('general:cancel'),
        onClick: confirmEditModal.closeModal,
        disabled: loading,
      }}
    />
  ));

  return (
    <HuDrawer
      open={open}
      onClose={handleClose}
      title={isEdit ? t('help_desk_edit') : t('help_desk_new')}
      primaryButtonProps={{
        onClick: handleSave,
        loading,
        disabled: disableCreateButton,
        children: isEdit ? t('general:save') : t('general:create'),
        fullWidth: true,
      }}
      secondaryButtonProps={{
        onClick: handleCancel,
        children: t('general:cancel'),
        fullWidth: true,
        disabled: loading,
      }}
    >
      {confirmEditModal.modal}
      <SegmentFilterDrawer
        name="segmentations"
        open={isFilterDrawerOpen}
        onClose={handleBackFromSegmentFilters}
        onApply={handleApplySegmentFilters}
        onReset={handleResetFilters}
      />
      <AgentListDrawer
        open={isSelectedAgentsDrawerOpen}
        onClose={() => setIsSelectedAgentsDrawerOpen(false)}
        agents={selectedCoordinators}
        onDelete={handleDeleteCoordinator}
      />
      <Stack
        sx={{
          gap: 2,
          height: 1,
          minHeight: 0,
          overflow: 'auto',
        }}
      >
        <Typography
          variant="globalS"
          sx={{
            color: ({ palette }) => palette.new.text.neutral.default,
            flexShrink: 0,
          }}
        >
          {t('help_desk_new_helper_text')}
        </Typography>
        <Stack
          sx={{
            p: 2,
            borderRadius: 2,
            backgroundColor: ({ palette }) =>
              palette.new.background.elements.grey,
            flexShrink: 0,
          }}
        >
          <HuFormInputClassic
            name={newHelpDeskFields.name}
            inputProps={{
              label: t('name'),
              placeholder: t('help_desk_new_name_placeholder'),
              hasCounter: true,
              maxLength: HELP_DESK_NAME_MAX_LENGTH,
            }}
            rules={validationRules}
          />
        </Stack>
        <Stack
          sx={{
            p: 2,
            borderRadius: 2,
            backgroundColor: ({ palette }) =>
              palette.new.background.elements.grey,
            gap: 0.5,
            flex: 1,
            minHeight: 260,
            minWidth: 0, // Prevent flex item from overflowing
            overflow: 'hidden',
          }}
        >
          <Stack
            sx={{
              gap: 1,
              height: 1,
              minHeight: 0,
            }}
          >
            <Typography
              variant="globalS"
              fontWeight="fontWeightSemiBold"
              sx={{ flexShrink: 0 }}
            >
              {t('coordinators')}
            </Typography>
            <Stack
              sx={{
                flexDirection: 'row',
                gap: 2.5,
                alignItems: 'center',
                flexShrink: 0,
              }}
            >
              <HuSearch
                value={coordinatorsQuery}
                onChange={value => setCoordinatorsQuery(value)}
              />
              {!segmentationGroupsIsLoading &&
                segmentationGroups.length > 0 && (
                  <BadgeCountButton
                    buttonText={t('general:filter')}
                    count={segmentationGroupsCount}
                    buttonProps={{
                      variant: 'secondary',
                      size: 'small',
                      startIcon: <IconFilter size={16} />,
                      onClick: () => setIsFilterDrawerOpen(true),
                    }}
                  />
                )}
            </Stack>
            <Stack
              sx={{
                flex: 1,
                minHeight: isEmpty || isEmptySearch ? 'auto' : 0,
                maxHeight: isEmpty || isEmptySearch ? 200 : 'none',
              }}
            >
              <AgentSelector
                loading={isLoading}
                hasNextPage={!!hasNextPage}
                isFetchingNextPage={isFetchingNextPage}
                fetchNextPage={fetchNextPage}
                onSelectAll={handleSelectAllCoordinators}
                onSelect={handleSelectCoordinator}
                selectedAgents={selectedCoordinators}
                agents={coordinators}
                isSuccess={isSuccess}
                isEmpty={isEmpty}
                isEmptySearch={isEmptySearch}
              />
            </Stack>
          </Stack>
        </Stack>
        {!showErrorAlert && (
          <HuAlert
            hasClose={false}
            severity="info"
            title={t('selected_coordinators', {
              count: selectedCoordinators.length,
            })}
            sx={{
              minHeight: 76, // Prevent shift when action is shown
              flexShrink: 0,
            }}
            action={
              selectedCoordinators?.length > 0
                ? {
                    text: t('general:show'),
                    onClick: () => setIsSelectedAgentsDrawerOpen(true),
                  }
                : undefined
            }
          />
        )}
        {showErrorAlert && (
          <HuAlert
            hasClose={false}
            severity="error"
            title={t('no_coordinators_selected')}
            description={t('no_coordinators_selected_helper_text')}
            sx={{ flexShrink: 0 }}
          />
        )}
      </Stack>
    </HuDrawer>
  );
};

export default CreateHelpDeskDrawer;
