import { useRef } from 'react';

import { type LibrariesSidebarProps } from '@composed-components/LibrariesSidebar';
import { SidebarEmpty } from '@composed-components/LibrariesSidebar/components/empty/SidebarEmpty';
import { SidebarChildRow } from '@composed-components/LibrariesSidebar/components/list/children/SidebarChildRow';
import { SortableRows } from '@composed-components/LibrariesSidebar/components/list/SortableRows';
import { SidebarLoading } from '@composed-components/LibrariesSidebar/components/loading/SidebarLoading';
import { ROOT_ROW_HEIGHT } from '@composed-components/LibrariesSidebar/constants';
import { useSidebarContext } from '@composed-components/LibrariesSidebar/context';
import { useSidebarColors } from '@composed-components/LibrariesSidebar/hooks/useGetSidebarColors';
import { useSortableList } from '@composed-components/LibrariesSidebar/hooks/useSortableList';
import {
  getChildrenListSx,
  getChildVirtualRowStyle,
} from '@composed-components/LibrariesSidebar/styles';
import { type LibrariesTreeItem } from '@composed-components/LibrariesSidebar/types';
import useVirtualizer from '@hooks/useVirtualizer';
import { Stack } from '@mui/material';

type SidebarChildrenListProps = Pick<
  LibrariesSidebarProps,
  'loading' | 'onAdd'
> & {
  depth?: number;
  parentId: number;
};

export const SidebarChildrenList = ({
  loading,
  parentId,
  onAdd,
  depth = 0,
}: SidebarChildrenListProps) => {
  const colors = useSidebarColors();
  const { getTreeItem } = useSidebarContext();
  const { isSortMode, listItems, handleDragEnd } = useSortableList(parentId);

  // Only the top-level list owns the scroll container, so virtualization is
  // scoped to it. Nested levels render inline inside their parent's measured
  // row (no nested scroll containers).
  const isVirtualized = depth === 0;
  const scrollElementRef = useRef<HTMLDivElement>(null);

  const { virtualRows, rowVirtualizer } = useVirtualizer({
    scrollElementRef,
    registers: listItems,
    virtualizerOptions: {
      count: listItems.length,
      estimateSize: () => ROOT_ROW_HEIGHT,
      getScrollElement: () => scrollElementRef.current,
      overscan: 8,
      enabled: isVirtualized,
    },
  });

  const parentAtLimit = Boolean(getTreeItem(parentId)?.hasReachedLimit);
  const listSx = getChildrenListSx(colors);

  if (loading) return <SidebarLoading />;
  if (!listItems.length && !parentAtLimit) return <SidebarEmpty />;

  const renderRow = (item: LibrariesTreeItem) => (
    <SidebarChildRow
      item={item}
      depth={depth}
      onAdd={onAdd}
    />
  );

  // Only use SortableRows when in sort mode.
  if (isSortMode) {
    return (
      <SortableRows
        items={listItems}
        onDragEnd={handleDragEnd}
        renderRow={renderRow}
        sx={listSx}
      />
    );
  }

  // Nested levels render inline so the parent virtualized row measures their
  // full expanded height.
  if (!isVirtualized) {
    return (
      <Stack sx={listSx}>
        {listItems.map(item => (
          <SidebarChildRow
            key={item.id}
            item={item}
            depth={depth}
            onAdd={onAdd}
          />
        ))}
      </Stack>
    );
  }

  return (
    <Stack
      ref={scrollElementRef}
      sx={listSx}
    >
      <Stack
        style={{
          height: `${rowVirtualizer.getTotalSize()}px`,
          width: '100%',
          position: 'relative',
        }}
      >
        {virtualRows.map(virtualRow => {
          const item = listItems[virtualRow.index];
          if (!item) return null;

          return (
            <div
              key={item.id}
              data-index={virtualRow.index}
              ref={rowVirtualizer.measureElement}
              style={getChildVirtualRowStyle(virtualRow.start)}
            >
              <SidebarChildRow
                item={item}
                depth={depth}
                onAdd={onAdd}
              />
            </div>
          );
        })}
      </Stack>
    </Stack>
  );
};
