import { useEffect, useState } from 'react';
// biome-ignore lint/style/noRestrictedImports: legacy usage, migration pending
import { DragDropContext, Draggable } from 'react-beautiful-dnd';
import { useMutation } from 'react-query';

import { IconGripVertical } from '@material-hu/icons/tabler';
import Box from '@material-hu/mui/Box';
import Divider from '@material-hu/mui/Divider';
import Stack from '@material-hu/mui/Stack';

import { queryClient } from 'src/config/react-query';
import type { DragProps } from 'src/hooks/useDragEnd';
import useDragEnd from 'src/hooks/useDragEnd';
import { sortPinnedGroups } from 'src/services/groups';
import type { Group } from 'src/types/groups';

import StrictModeDroppable from 'src/components/StrictModeDroppable';

import { groupsKeys } from '../queries';

import GroupItem from './GroupItem';

const DROPPABLE_ID = 'pinned-groups-droppable';

type Props = {
  groups: Group[];
};

const PinnedGroupsList = ({ groups }: Props) => {
  const [orderedGroups, setOrderedGroups] = useState<Group[]>(groups);

  useEffect(() => {
    setOrderedGroups(groups);
  }, [groups]);

  const { mutate: reorder } = useMutation(sortPinnedGroups, {
    onSuccess: () => {
      queryClient.invalidateQueries(groupsKeys.allPinnedList());
    },
  });

  const dragPolicy = ({ source, destination }: DragProps) => {
    const from = source.index;
    const to = destination?.index ?? 0;

    const newOrder = [...orderedGroups];
    const [moved] = newOrder.splice(from, 1);
    newOrder.splice(to, 0, moved);

    setOrderedGroups(newOrder);

    reorder({
      groupId: moved.id,
      parentGroupId: newOrder[to - 1]?.id,
    });
  };

  const { handleDragEnd } = useDragEnd(dragPolicy);

  return (
    <DragDropContext onDragEnd={handleDragEnd}>
      <StrictModeDroppable
        droppableId={DROPPABLE_ID}
        direction="vertical"
      >
        {provided => (
          <Stack
            ref={provided.innerRef}
            {...provided.droppableProps}
          >
            {orderedGroups.map((group, index) => (
              <Draggable
                key={group.id}
                draggableId={String(group.id)}
                index={index}
              >
                {(draggableProvided, snapshot) => (
                  <div
                    ref={draggableProvided.innerRef}
                    {...draggableProvided.draggableProps}
                  >
                    {index !== 0 && <Divider />}
                    <Box
                      sx={{
                        display: 'flex',
                        alignItems: 'center',
                        backgroundColor: snapshot.isDragging
                          ? theme => theme.palette.new.background.elements.grey
                          : undefined,
                        borderRadius: snapshot.isDragging ? 1 : undefined,
                        boxShadow: snapshot.isDragging
                          ? '0 4px 12px rgba(0,0,0,0.12)'
                          : undefined,
                      }}
                    >
                      <Box
                        {...draggableProvided.dragHandleProps}
                        sx={{
                          display: 'flex',
                          alignItems: 'center',
                          pl: 2,
                          color: theme =>
                            theme.palette.new.text.neutral.default,
                          opacity: 0.4,
                          cursor: 'grab',
                          '&:hover': { opacity: 0.8 },
                          flexShrink: 0,
                        }}
                      >
                        <IconGripVertical size={18} />
                      </Box>
                      <Box sx={{ flex: 1 }}>
                        <GroupItem
                          group={group}
                          userIsMember
                        />
                      </Box>
                    </Box>
                  </div>
                )}
              </Draggable>
            ))}
            {provided.placeholder}
          </Stack>
        )}
      </StrictModeDroppable>
    </DragDropContext>
  );
};

export default PinnedGroupsList;
