import { Box, Flex } from '@mantine/core';
import { VariableSizeList as List } from 'react-window';
import AutoSizer from 'react-virtualized-auto-sizer';
import { useMemo } from 'react';
import table from '../../../helpers/table';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { GripVertical } from 'lucide-react';
import useChannelsTableStore from '../../../store/channelsTable';

const CustomTableBody = ({
  getRowModel,
  expandedRowIds,
  expandedRowRenderer,
  renderBodyCell,
  getExpandedRowHeight,
  getRowStyles,
  tableBodyProps,
  tableCellProps,
  enableDragDrop = false,
}) => {
  const renderExpandedRow = (row) => {
    if (expandedRowRenderer) {
      return expandedRowRenderer({ row });
    }

    return <></>;
  };

  const rows = getRowModel().rows;

  // Calculate minimum width based only on fixed-size columns
  const minTableWidth = useMemo(() => {
    if (rows.length === 0) return 0;

    return rows[0].getVisibleCells().reduce((total, cell) => {
      // Only count columns with fixed sizes, flexible columns will expand
      const columnSize = cell.column.columnDef.size
        ? cell.column.getSize()
        : cell.column.columnDef.minSize || 150; // Default min for flexible columns
      return total + columnSize;
    }, 0);
  }, [rows]);

  const renderTableBodyContents = () => {
    const virtualized = false;

    if (virtualized) {
      return (
        <Box
          className="tbody"
          style={{ flex: 1, ...(tableBodyProps && tableBodyProps()) }}
        >
          <AutoSizer disableWidth>
            {({ height }) => {
              const getItemSize = (index) => {
                const row = rows[index];
                const isExpanded = expandedRowIds.includes(row.original.id);
                console.log(isExpanded);

                // Default row height
                let rowHeight = 28;

                if (isExpanded && getExpandedRowHeight) {
                  // If row is expanded, adjust the height to be larger (based on your logic)
                  // You can get this height from your state, or calculate based on number of items in the expanded row
                  rowHeight += getExpandedRowHeight(row); // This function would calculate the expanded row's height
                }

                return rowHeight;
              };

              return (
                <List
                  height={height}
                  itemCount={rows.length}
                  itemSize={getItemSize}
                  width="100%"
                  overscanCount={10}
                >
                  {({ index, style }) => {
                    const row = rows[index];
                    return renderTableBodyRow(row, index, style);
                  }}
                </List>
              );
            }}
          </AutoSizer>
        </Box>
      );
    }

    return (
      <Box className="tbody" style={{ flex: 1 }}>
        {rows.map((row, index) => renderTableBodyRow(row, index))}
      </Box>
    );
  };

  const renderTableBodyRow = (row, index, style = {}) => {
    // Get custom styles for this row if the function exists
    const customRowStyles = getRowStyles ? getRowStyles(row) : {};

    // Extract any className from customRowStyles
    const customClassName = customRowStyles.className || '';
    delete customRowStyles.className; // Remove from object so it doesn't get applied as inline style

    return (
      <DraggableRowWrapper
        row={row}
        key={`row-${row.id}`}
        style={style}
        enableDragDrop={enableDragDrop}
      >
        <Box
          key={`tr-${row.id}`}
          className={`tr ${index % 2 == 0 ? 'tr-even' : 'tr-odd'} ${customClassName}`}
          style={{
            display: 'flex',
            width: '100%',
            minWidth: '100%', // Force full width
            ...(row.getIsSelected() && {
              backgroundColor: '#163632',
            }),
            ...customRowStyles, // Apply the remaining custom styles here
          }}
        >
          {row.getVisibleCells().map((cell) => {
            return (
              <Box
                className="td"
                key={`td-${cell.id}`}
                style={{
                  ...(cell.column.columnDef.grow
                    ? {
                        flex: `${cell.column.columnDef.grow === true ? 1 : cell.column.columnDef.grow} 1 0%`,
                        minWidth: 0,
                        ...(cell.column.columnDef.maxSize && {
                          maxWidth: `${cell.column.columnDef.maxSize}px`,
                        }),
                      }
                    : {
                        flex: `0 0 ${cell.column.getSize ? cell.column.getSize() : 150}px`,
                        width: `${cell.column.getSize ? cell.column.getSize() : 150}px`,
                        maxWidth: `${cell.column.getSize ? cell.column.getSize() : 150}px`,
                      }),
                  ...(tableCellProps && tableCellProps({ cell })),
                }}
              >
                <Flex align="center" style={{ height: '100%' }}>
                  {renderBodyCell({ row, cell })}
                </Flex>
              </Box>
            );
          })}
        </Box>
        {expandedRowIds.includes(row.original.id) && renderExpandedRow(row)}
      </DraggableRowWrapper>
    );
  };

  return renderTableBodyContents();
};

const DraggableRowWrapper = ({
  row,
  children,
  style = {},
  enableDragDrop = false,
}) => {
  const isUnlocked = useChannelsTableStore((s) => s.isUnlocked);
  const shouldEnableDrag = enableDragDrop && isUnlocked;

  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({
    id: row.id,
    disabled: !shouldEnableDrag,
  });

  const dragStyle = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.5 : 1,
    position: 'relative',
    ...style,
  };

  return (
    <Box ref={setNodeRef} style={dragStyle}>
      {shouldEnableDrag && (
        <Box
          {...attributes}
          {...listeners}
          style={{
            position: 'absolute',
            left: 0,
            top: 0,
            bottom: 0,
            width: 24,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            cursor: isDragging ? 'grabbing' : 'grab',
            backgroundColor: 'rgba(255, 255, 255, 0.05)',
            borderRight: '1px solid rgba(255, 255, 255, 0.1)',
            borderBottom: '1px solid rgba(255, 255, 255, 0.05)',
            zIndex: 1,
          }}
        >
          <GripVertical size={16} opacity={0.5} />
        </Box>
      )}
      <div style={{ paddingLeft: shouldEnableDrag ? 28 : 0, width: '100%' }}>
        {children}
      </div>
    </Box>
  );
};

export default CustomTableBody;
