import { useMemo, useState } from 'react';

import CollapsibleSelectionList from '@composed-components/CollapsibleSelectionList';
import Search from '@design-system/Inputs/Search';
import Skeleton from '@design-system/Skeleton';
import StateCard from '@design-system/StateCard';
import Title from '@design-system/Title';
import FormHelperText from '@mui/material/FormHelperText';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import { IconZoomExclamation } from '@tabler/icons-react';
import { appearFromBottom } from '@utils/animations';

import { type SegmentationGroupItemsSelectionProps } from './types';

const SegmentationGroupItemsSelection = ({
  segmentationsQuery,
  segmentationsQueryDataParser = data => data,
  value,
  onChange,
  excludedGroupsIds = new Set(),
  allowSelectAll,
  slotProps,
  error,
  sx,
}: SegmentationGroupItemsSelectionProps) => {
  const [search, setSearch] = useState('');

  const segmentationGroups = useMemo(
    () => segmentationsQueryDataParser(segmentationsQuery?.data),
    [segmentationsQuery?.data],
  );

  const filteredSegmentationGroups = segmentationGroups
    ?.map(group => ({
      ...group,
      items: group.items.filter(item => !excludedGroupsIds?.has(item.id)),
    }))
    .filter(
      ({ items, name: groupName }) =>
        items.length &&
        groupName.toLocaleLowerCase().includes(search.toLowerCase()),
    );

  return (
    <Stack sx={{ gap: 2, ...sx }}>
      {slotProps?.title?.title && (
        <Title
          variant="M"
          title={slotProps.title?.title}
          {...slotProps.title}
        />
      )}

      {slotProps?.search && (
        <Search
          value={search}
          disabled={segmentationsQuery.isLoading}
          onChange={setSearch}
          {...slotProps.search}
        />
      )}

      {segmentationsQuery.isLoading && (
        <Stack sx={{ gap: 2 }}>
          <Skeleton sx={{ height: 48 }} />
          <Skeleton sx={{ height: 48 }} />
          <Skeleton sx={{ height: 48 }} />
        </Stack>
      )}

      {!filteredSegmentationGroups?.length &&
        !segmentationsQuery.isLoading &&
        !!search &&
        slotProps?.stateCard?.title && (
          <StateCard
            icon={IconZoomExclamation}
            slotProps={{
              card: {
                sx: {
                  border: 'none',
                  animation: `${appearFromBottom} 0.1s ease-in-out backwards`,
                },
              },
              ...slotProps.stateCard.slotProps,
            }}
            {...slotProps.stateCard}
          />
        )}

      {!segmentationsQuery.isLoading &&
        filteredSegmentationGroups?.map((segmentationGroup, index) => {
          const currentSelectionSet = new Set<number>(
            value?.[segmentationGroup.id] || [],
          );

          return (
            <CollapsibleSelectionList
              {...slotProps?.collapsibleSelectionList}
              key={segmentationGroup.id}
              selected={currentSelectionSet}
              items={segmentationGroup.items}
              title={segmentationGroup.name}
              allowSelectAll={allowSelectAll ?? false}
              itemRenderer={item => (
                <Typography
                  variant="globalS"
                  color={theme => theme.palette.new.text.neutral.default}
                >
                  {item.name}
                </Typography>
              )}
              onChange={_value => {
                onChange?.({
                  selectedSegmentationIds: {
                    ...value,
                    [segmentationGroup.id]: new Set(_value),
                  },
                });
              }}
              sx={{
                animation: `${appearFromBottom} 125ms ease-in-out backwards`,
                animationDelay: `${32 * index}ms`,
                ...((slotProps?.collapsibleSelectionList?.sx ?? {}) as object),
              }}
            />
          );
        })}

      {error && <FormHelperText error>{error?.message}</FormHelperText>}
    </Stack>
  );
};

export type { SegmentationGroupItemsSelectionProps };

export default SegmentationGroupItemsSelection;
