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

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 HuDrawer from '@material-hu/components/design-system/Drawer';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';

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

import { type AgentsForm } from '../Agents';
import useUserSelector from '../hooks/useUserSelector';

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

type Props = {
  open: boolean;
  onCancel: () => void;
  onClose: () => void;
  onSelect: () => void;
  loading: boolean;
};

const agentsName: keyof AgentsForm = 'agents';

const MAX_COLLABORATORS = 100;
const USERS_PER_PAGE = 50;

const CreateAgentDrawer: FC<Props> = ({
  open,
  onClose,
  onCancel,
  onSelect,
  loading,
}) => {
  const { t } = useLokaliseTranslation(['service_management', 'general']);
  const { watch, setValue } = useFormContext<AgentsForm>();

  const [appliedSegmentations, setAppliedSegmentations] = useState<number[]>(
    [],
  );
  const [isSegmentationDrawerOpen, setIsSegmentationDrawerOpen] =
    useState(false);
  const [isSelectedAgentsDrawerOpen, setIsSelectedAgentsDrawerOpen] =
    useState(false);

  const {
    query,
    setQuery,
    coordinators: users,
    isLoading,
    hasNextPage,
    isFetchingNextPage,
    isSuccess,
    fetchNextPage,
    segmentationGroupsCount,
    isEmpty,
    isEmptySearch,
  } = useUserSelector({
    limit: USERS_PER_PAGE,
    appliedSegmentations,
  });

  const segmentationsForm = useForm({
    defaultValues: {
      segmentations: [],
    },
  });

  const selectedAgents = watch(agentsName);

  const agentsSelectedExceeded = selectedAgents.length >= MAX_COLLABORATORS;

  const handleResetSegmentations = () => {
    segmentationsForm.reset();
  };

  const handleApplySegmentations = () => {
    setAppliedSegmentations(segmentationsForm.getValues('segmentations'));
    setIsSegmentationDrawerOpen(false);
  };

  const handleBackFromSegmentFilters = () => {
    setIsSegmentationDrawerOpen(false);
    segmentationsForm.reset();
  };

  const onSelectUser = (user: User) => {
    if (user.isAgent) return;

    // Check if coordinator is already selected
    const isSelected = selectedAgents.some(selected => selected.id === user.id);

    if (isSelected) {
      // If already selected, remove it
      const filteredAgents = selectedAgents.filter(
        selected => selected.id !== user.id,
      );
      setValue(agentsName, filteredAgents);
    } else if (selectedAgents.length < MAX_COLLABORATORS) {
      // If not selected and below max limit, add it
      setValue(agentsName, [...selectedAgents, user]);
    }
  };

  // Filter out users that are agents
  const nonAgentUsers = useMemo(() => users.filter(u => !u.isAgent), [users]);

  // Check if all non-agent coordinators are already selected
  const allSelected = useMemo(
    () =>
      nonAgentUsers.every(u =>
        selectedAgents.some(selected => selected.id === u.id),
      ),
    [selectedAgents, nonAgentUsers],
  );

  const onSelectAll = () => {
    if (allSelected) {
      // If all are selected, remove them all
      const filteredUsers = selectedAgents.filter(
        selected => !nonAgentUsers.some(u => u.id === selected.id),
      );
      setValue(agentsName, filteredUsers);
    } else {
      // Add only non-agent users that are not already selected, up to the MAX_COLLABORATORS limit
      const usersToAdd = nonAgentUsers.filter(
        u => !selectedAgents.some(selected => selected.id === u.id),
      );

      // Calculate how many more users we can add
      const remainingSlots = MAX_COLLABORATORS - selectedAgents.length;

      // Add only up to the remaining slots
      const newSelectedUsers = [
        ...selectedAgents,
        ...usersToAdd.slice(0, Math.max(0, remainingSlots)),
      ];

      setValue(agentsName, newSelectedUsers);
    }
  };

  const handleDeleteAgent = (agentId: number) => {
    const filteredAgents = selectedAgents.filter(
      selected => selected.id !== agentId,
    );
    setValue(agentsName, filteredAgents);
  };

  const resetValues = () => {
    setQuery('');
    setAppliedSegmentations([]);
    handleResetSegmentations();
  };

  const handleClose = () => {
    resetValues();
    onClose();
  };

  const handleCancel = () => {
    resetValues();
    onCancel();
  };

  const isSelectionDisabled = (user: User) => !!user.isAgent;

  return (
    <HuDrawer
      open={open}
      onClose={handleClose}
      title={t('new_agent')}
      primaryButtonProps={{
        onClick: onSelect,
        children: t('general:confirm'),
        loading: loading,
        disabled: selectedAgents.length <= 0,
        fullWidth: true,
      }}
      secondaryButtonProps={{
        onClick: handleCancel,
        children: t('general:cancel'),
        fullWidth: true,
        disabled: loading,
      }}
    >
      <FormProvider {...segmentationsForm}>
        <SegmentFilterDrawer
          name="segmentations"
          open={isSegmentationDrawerOpen}
          onClose={handleBackFromSegmentFilters}
          onApply={handleApplySegmentations}
          onReset={handleResetSegmentations}
        />
      </FormProvider>
      <AgentListDrawer
        open={isSelectedAgentsDrawerOpen}
        onClose={() => setIsSelectedAgentsDrawerOpen(false)}
        agents={selectedAgents}
        title={t('selected_members_title')}
        onDelete={handleDeleteAgent}
      />
      <Stack sx={{ gap: 2, height: '100%' }}>
        <Typography
          variant="globalS"
          sx={{ color: ({ palette }) => palette.new.text.neutral.default }}
        >
          {t('help_desk_new_helper_text')}
        </Typography>
        <Stack
          sx={{
            gap: 2,
            flexGrow: 1,
            height: `calc(100% - ${agentsSelectedExceeded ? '216px' : '200px'})`,
            backgroundColor: ({ palette }) =>
              palette.new.background.elements.grey,
            borderRadius: 3,
            p: 2,
          }}
        >
          <Stack sx={{ flexDirection: 'row', gap: 2.5, alignItems: 'center' }}>
            <HuSearch
              value={query}
              onChange={value => setQuery(value)}
            />
            <BadgeCountButton
              buttonText={t('general:filter')}
              count={segmentationGroupsCount}
              buttonProps={{
                variant: 'secondary',
                size: 'small',
                startIcon: <IconFilter size={16} />,
                onClick: () => setIsSegmentationDrawerOpen(true),
                sx: {
                  height: '36px',
                },
              }}
            />
          </Stack>
          <Stack
            sx={{
              overflowY: 'auto',
              height: isEmpty || isEmptySearch ? 'min(100%, 200px)' : '100%',
            }}
          >
            <AgentSelector
              loading={isLoading}
              hasNextPage={!!hasNextPage}
              isFetchingNextPage={isFetchingNextPage}
              onSelectAll={onSelectAll}
              onSelect={onSelectUser}
              selectedAgents={selectedAgents}
              agents={users}
              isSuccess={isSuccess}
              isEmpty={isEmpty}
              isUserSelector
              isEmptySearch={isEmptySearch}
              allSelected={allSelected}
              fetchNextPage={fetchNextPage}
              checkDisabledFunction={isSelectionDisabled}
              disabledSelectAll={agentsSelectedExceeded}
            />
          </Stack>
        </Stack>
        {!agentsSelectedExceeded && (
          <HuAlert
            hasClose={false}
            severity="info"
            title={t('selected_members', {
              count: selectedAgents.length,
            })}
            sx={{
              minHeight: '75px', // Prevent shift when action is shown
            }}
            action={
              selectedAgents.length > 0
                ? {
                    text: t('general:show'),
                    onClick: () => setIsSelectedAgentsDrawerOpen(true),
                  }
                : undefined
            }
          />
        )}
        {agentsSelectedExceeded && (
          <HuAlert
            hasClose={false}
            severity="warning"
            title={t('max_collaborators_selected_title')}
            description={t('max_collaborators_selected_description', {
              count: MAX_COLLABORATORS,
            })}
            action={{
              text: t('general:show'),
              onClick: () => setIsSelectedAgentsDrawerOpen(true),
            }}
          />
        )}
      </Stack>
    </HuDrawer>
  );
};

export default CreateAgentDrawer;
