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 AgentListDrawer from '../../../AgentManagement/components/AgentListDrawer';
import AgentSelector from '../../../AgentManagement/components/AgentSelector';
import BadgeCountButton from '../../../AgentManagement/components/BadgeCountButton';
import SegmentFilterDrawer from '../../../AgentManagement/components/SegmentFilterDrawer';
import useUserSelector from '../../../AgentManagement/hooks/useUserSelector';
import { newServiceItemFields } from '../../forms';

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

const agentsFormName = newServiceItemFields.assignment.agents();
const USERS_PER_PAGE = 50;
type SegmentationsForm = {
  segmentations: number[];
};

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

  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,
    segmentationGroups,
    segmentationGroupsCount,
    isEmpty,
    isEmptySearch,
  } = useUserSelector({
    limit: USERS_PER_PAGE,
    appliedSegmentations,
    isAgent: true,
    enabled: open,
  });

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

  const selectedAgents: User[] = watch(agentsFormName) ?? [];

  const handleResetSegmentations = () => {
    setAppliedSegmentations([]);
    segmentationsForm.reset();
    setIsSegmentationDrawerOpen(false);
  };

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

  const handleBackFromSegmentFilters = () => {
    setIsSegmentationDrawerOpen(false);
    segmentationsForm.setValue('segmentations', appliedSegmentations);
  };

  const onSelectUser = (user: User) => {
    const isSelected = selectedAgents.some(selected => selected.id === user.id);

    if (isSelected) {
      const filteredAgents = selectedAgents.filter(
        selected => selected.id !== user.id,
      );
      setValue(agentsFormName, filteredAgents);
    } else {
      setValue(agentsFormName, [...selectedAgents, user]);
    }
  };

  const allSelected = useMemo(
    () =>
      users.length > 0 &&
      users.every(u => selectedAgents.some(selected => selected.id === u.id)),
    [selectedAgents, users],
  );

  const onSelectAll = () => {
    if (allSelected) {
      const filteredUsers = selectedAgents.filter(
        selected => !users.some(u => u.id === selected.id),
      );
      setValue(agentsFormName, filteredUsers);
    } else {
      const usersToAdd = users.filter(
        u => !selectedAgents.some(selected => selected.id === u.id),
      );
      setValue(agentsFormName, [...selectedAgents, ...usersToAdd]);
    }
  };

  const handleDeleteAgent = (agentId: number) => {
    const filteredAgents = selectedAgents.filter(
      selected => selected.id !== agentId,
    );
    setValue(agentsFormName, filteredAgents);
    if (filteredAgents.length === 0) {
      setIsSelectedAgentsDrawerOpen(false);
    }
  };

  const resetValues = () => {
    setQuery('');
    setIsSelectedAgentsDrawerOpen(false);
    handleResetSegmentations();
  };

  const handleSelect = () => {
    resetValues();
    onSelect();
  };

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

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

  return (
    <HuDrawer
      open={open}
      onClose={handleClose}
      title={t('specific_agents')}
      primaryButtonProps={{
        onClick: handleSelect,
        children: t('general:confirm'),
        loading,
        disabled: selectedAgents.length <= 0,
        fullWidth: true,
      }}
      secondaryButtonProps={{
        onClick: handleCancel,
        children: t('general:cancel'),
        fullWidth: true,
        disabled: loading,
      }}
      footer={
        <HuAlert
          hasClose={false}
          severity="info"
          title={t('selected_members', {
            count: selectedAgents.length,
          })}
          sx={{ minHeight: '75px' }}
          action={
            selectedAgents.length > 0
              ? {
                  text: t('general:show'),
                  onClick: () => setIsSelectedAgentsDrawerOpen(true),
                }
              : undefined
          }
        />
      }
    >
      <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_agents')}
        onDelete={handleDeleteAgent}
        showSearch
        showCount
      />
      <Stack sx={{ gap: 2, height: '100%' }}>
        <Typography
          variant="globalS"
          sx={{ color: theme => theme.palette.new.text.neutral }}
        >
          {t('specific_collaborators_assignment_helper_text')}
        </Typography>
        <Stack
          sx={{
            gap: 2,
            flexGrow: 1,
            height: 'calc(100% - 200px)',
            backgroundColor: theme => theme.palette.new.border.neutral.default,
            borderRadius: 3,
            p: 2,
          }}
        >
          <Stack sx={{ flexDirection: 'row', gap: 2.5, alignItems: 'center' }}>
            <HuSearch
              value={query}
              onChange={value => setQuery(value)}
            />
            {segmentationGroups.length > 0 && (
              <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}
              isEmptySearch={isEmptySearch}
              allSelected={allSelected}
              fetchNextPage={fetchNextPage}
            />
          </Stack>
        </Stack>
      </Stack>
    </HuDrawer>
  );
};

export default SpecificAgentsDrawer;
