'use client';

import React, { useMemo } from 'react';
import { List, useDynamicRowHeight, type RowComponentProps } from 'react-window';
import type { KanbanItem } from './kanbanBoardTypes';
import {
  KANBAN_COLUMN_VIRTUAL_ROW_DEFAULT_HEIGHT,
} from './kanbanColumnVirtual';
import styles from './KanbanBoard.module.scss';

export type KanbanVirtualSortableRowProps = {
  /** Opcional na coluna virtual — o item vem de `items[index]`. */
  item?: KanbanItem;
  onClickItem: (item: KanbanItem) => void;
  onEditItem: (item: KanbanItem) => void;
  onDeleteItem: (itemId: string | number) => void;
  renderItem?: (item: KanbanItem) => React.ReactNode;
  getRenderItemAriaLabel?: (item: KanbanItem) => string;
  testIdPrefix: string;
  variant: 'default' | 'crm';
  /** Componente sortable (useSortable) definido no KanbanBoard. */
  SortableItemCard: React.ComponentType<{
    item: KanbanItem;
    onClickItem: (item: KanbanItem) => void;
    onEditItem: (item: KanbanItem) => void;
    onDeleteItem: (itemId: string | number) => void;
    renderItem?: (item: KanbanItem) => React.ReactNode;
    getRenderItemAriaLabel?: (item: KanbanItem) => string;
    testIdPrefix: string;
    variant: 'default' | 'crm';
  }>;
};

type VirtualRowExtra = KanbanVirtualSortableRowProps & {
  items: KanbanItem[];
  observeRowElements: ReturnType<typeof useDynamicRowHeight>['observeRowElements'];
  rowGap: number;
};

function KanbanVirtualRow({ index, style, ariaAttributes, ...rowExtra }: RowComponentProps<VirtualRowExtra>) {
  const {
    items,
    observeRowElements,
    rowGap,
    SortableItemCard,
    onClickItem,
    onEditItem,
    onDeleteItem,
    renderItem,
    getRenderItemAriaLabel,
    testIdPrefix,
    variant,
  } = rowExtra;
  const item = items[index];
  const cleanupRef = React.useRef<(() => void) | null>(null);

  const setRowRef = React.useCallback(
    (node: HTMLDivElement | null) => {
      cleanupRef.current?.();
      cleanupRef.current = null;
      if (node) {
        cleanupRef.current = observeRowElements([node]);
      }
    },
    [observeRowElements],
  );

  React.useEffect(
    () => () => {
      cleanupRef.current?.();
      cleanupRef.current = null;
    },
    [],
  );

  if (!item) {
    return null;
  }

  return (
    <div
      {...ariaAttributes}
      ref={setRowRef}
      style={{
        ...style,
        boxSizing: 'border-box',
        paddingBottom: index < items.length - 1 ? rowGap : 0,
      }}
    >
      <SortableItemCard
        item={item}
        onClickItem={onClickItem}
        onEditItem={onEditItem}
        onDeleteItem={onDeleteItem}
        renderItem={renderItem}
        getRenderItemAriaLabel={getRenderItemAriaLabel}
        testIdPrefix={testIdPrefix}
        variant={variant}
      />
    </div>
  );
}

export type KanbanColumnVirtualBodyProps = KanbanVirtualSortableRowProps & {
  items: KanbanItem[];
  className?: string;
  style?: React.CSSProperties;
};

export function KanbanColumnVirtualBody({
  items,
  className,
  style,
  SortableItemCard,
  onClickItem,
  onEditItem,
  onDeleteItem,
  renderItem,
  getRenderItemAriaLabel,
  testIdPrefix,
  variant,
}: KanbanColumnVirtualBodyProps) {
  const rowGap = variant === 'crm' ? 10 : 8;
  const dynamicHeight = useDynamicRowHeight({
    defaultRowHeight: KANBAN_COLUMN_VIRTUAL_ROW_DEFAULT_HEIGHT + rowGap,
    key: `${items.length}:${items[0]?.id ?? 'empty'}`,
  });

  const rowProps: VirtualRowExtra = useMemo(
    () => ({
      items,
      observeRowElements: dynamicHeight.observeRowElements,
      rowGap,
      SortableItemCard,
      onClickItem,
      onEditItem,
      onDeleteItem,
      renderItem,
      getRenderItemAriaLabel,
      testIdPrefix,
      variant,
    }),
    [
      items,
      dynamicHeight.observeRowElements,
      rowGap,
      SortableItemCard,
      onClickItem,
      onEditItem,
      onDeleteItem,
      renderItem,
      getRenderItemAriaLabel,
      testIdPrefix,
      variant,
    ],
  );

  return (
    <div
      className={[className, styles.columnVirtualHost].filter(Boolean).join(' ')}
      style={style}
      data-testid={`${testIdPrefix}-column-virtual-body`}
    >
      <List<VirtualRowExtra>
        rowCount={items.length}
        rowHeight={dynamicHeight}
        rowProps={rowProps}
        rowComponent={KanbanVirtualRow}
        overscanCount={6}
        style={{ height: '100%', width: '100%' }}
      />
    </div>
  );
}
