import React, { useRef, useState, useLayoutEffect } from 'react';
import { FiltersMap } from '@wix/bex-core';
import { observer } from 'mobx-react-lite';
import { KanbanCardProps } from '../Kanban/Card';
import { useDraggable } from '@wix/wix-style-react-incubator/dnd-kit/core';
import { KanbanState } from '../../state/KanbanState';
import { action } from 'mobx';

export interface KanbanDraggableCardItemProps<T, S, F extends FiltersMap> {
  children: React.ComponentType<KanbanCardProps<T, S, F>>;
  id: string;
  cardProps: KanbanCardProps<T, S, F>;
  state: KanbanState<T, S, F>;
}

function _KanbanDraggableCardItem<T, S, F extends FiltersMap>(
  props: KanbanDraggableCardItemProps<T, S, F>,
) {
  const { children: CardComponent, id, cardProps, state } = props;

  const dragHandleRef = useRef<HTMLElement | null>(null);
  const cardRef = useRef<HTMLDivElement | null>(null);
  const [cardHeight, setCardHeight] = useState<number | undefined>(undefined);

  // Measure card height after render
  useLayoutEffect(() => {
    if (cardRef.current) {
      const height = cardRef.current.offsetHeight;
      setCardHeight(height);
    }
  }, [cardProps]);

  // Use useDraggable instead of useSortable since we only support cross-stage movement
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    isDragging,
    setActivatorNodeRef,
  } = useDraggable({
    id,
  });

  const ariaDescribedBy = `draggable-kanban-card-description-${id}`;
  const stateDragAndDrop = state.dragAndDropState;

  const dragHandleProps = {
    ...attributes,
    ...listeners,
    ref: (e: HTMLElement | null) => {
      setActivatorNodeRef(e);
      dragHandleRef.current = e;
    },
    'aria-describedby': ariaDescribedBy,
    onClick: (e: React.MouseEvent) => e.stopPropagation(),
    ...(process.env.NODE_ENV === 'test' && {
      onPointerDown: action(() => {
        stateDragAndDrop.handleDragStart({ active: { id } } as any);
      }),
    }),

    style: { pointerEvents: 'auto' } as React.CSSProperties,
  };

  const dragStyle: React.CSSProperties = {
    // Apply transform for drag feedback
    transform: transform
      ? `translate3d(${transform.x}px, ${transform.y}px, 0)`
      : undefined,
    // Hide the original card when dragging, letting the drag system handle the visual feedback
    visibility: isDragging ? 'hidden' : 'visible',
    // Allow pointer events to pass through to parent droppable when not dragging
    pointerEvents: isDragging ? 'auto' : 'none',
    // Ensure dragged card appears above all other elements including stages
    zIndex: isDragging ? 1000 : 'auto',
    position: 'relative' as const,
  };

  const containerStyle: React.CSSProperties = {
    position: 'relative',
  };

  return (
    <div style={containerStyle} data-hook="kanban-card-item-events">
      {/* Show static placeholder when dragging */}
      {isDragging && (
        <div
          style={{
            position: 'absolute',
            top: 0,
            left: 0,
            height: cardHeight ? `${cardHeight}px` : '129px', // Use measured height or fallback
            width: '246px',
            backgroundColor: '#D6E6FE',
            borderRadius: '8px',
            pointerEvents: 'none',
            zIndex: 1,
            marginLeft: '12px',
          }}
        >
          {/* Empty placeholder - no text, just a silver box */}
        </div>
      )}

      {/* Draggable card content */}
      <div
        ref={(node) => {
          setNodeRef(node);
          cardRef.current = node;
        }}
        style={dragStyle}
      >
        <div {...dragHandleProps} data-hook={`kanban-card-drag-item-${id}`}>
          <CardComponent {...cardProps} />
        </div>
      </div>
    </div>
  );
}

export const KanbanDraggableCardItem = observer(_KanbanDraggableCardItem);
