import { Group, Rect, Line, Text } from 'react-konva';
import type { ProjectedOpening } from '../utils/projectionMapping';
import { projectionToPixel } from '../utils/projectionMapping';
import type { DoorOpenDirection } from '@house-plan-maker/shared';
import { useCanvasColors } from '../utils/canvasThemeColors';

interface ProjectionDoorProps {
  readonly projected: ProjectedOpening;
  readonly wallHeight: number;
  readonly scale: number;
  readonly padding: number;
  readonly isSelected: boolean;
  readonly isDragging?: boolean;
  readonly dragAlongWall?: number;
  readonly onClick: () => void;
  readonly onDragStart?: (openingId: string, evt: MouseEvent) => void;
}

/**
 * Build polyline points for a quarter-circle arc used as the door swing indicator.
 * The arc origin and sweep direction depend on the open direction.
 */
function buildSwingArcPoints(
  topLeftX: number,
  topLeftY: number,
  pxWidth: number,
  pxHeight: number,
  openDirection: DoorOpenDirection,
): number[] {
  const arcRadius = pxWidth * 0.8;
  const steps = 12;
  const points: number[] = [];

  // Hinge at left or right bottom corner; arc sweeps accordingly
  const hingeLeft = openDirection === 'LEFT' || openDirection === 'INWARD' || openDirection === 'OUTWARD';

  for (let i = 0; i <= steps; i++) {
    const t = i / steps;
    const angle = (Math.PI / 2) * t;

    if (hingeLeft) {
      // Hinge at bottom-left, arc sweeps rightward and upward
      points.push(
        topLeftX + Math.sin(angle) * arcRadius,
        topLeftY + pxHeight - Math.cos(angle) * arcRadius,
      );
    } else {
      // Hinge at bottom-right, arc sweeps leftward and upward
      points.push(
        topLeftX + pxWidth - Math.sin(angle) * arcRadius,
        topLeftY + pxHeight - Math.cos(angle) * arcRadius,
      );
    }
  }

  return points;
}

/** Render a door in wall elevation view. */
export function ProjectionDoor({
  projected,
  wallHeight,
  scale,
  padding,
  isSelected,
  isDragging = false,
  dragAlongWall,
  onClick,
  onDragStart,
}: ProjectionDoorProps) {
  const colors = useCanvasColors();
  const { rect, opening } = projected;
  const openDirection: DoorOpenDirection = opening.openDirection ?? 'LEFT';

  const displayX = isDragging && dragAlongWall != null
    ? dragAlongWall - opening.width / 2
    : rect.x;

  const topLeft = projectionToPixel(displayX, rect.y + rect.height, wallHeight, scale, padding);
  const pxWidth = rect.width * scale;
  const pxHeight = rect.height * scale;

  const arcPoints = buildSwingArcPoints(topLeft.x, topLeft.y, pxWidth, pxHeight, openDirection);

  // Door leaf line position depends on hinge side
  const isHingeLeft = openDirection === 'LEFT' || openDirection === 'INWARD' || openDirection === 'OUTWARD';
  const leafPoints = isHingeLeft
    ? [topLeft.x, topLeft.y, topLeft.x, topLeft.y + pxHeight]
    : [topLeft.x + pxWidth, topLeft.y, topLeft.x + pxWidth, topLeft.y + pxHeight];

  return (
    <Group
      onClick={onClick}
      onMouseDown={(e) => {
        if (onDragStart && e.evt.button === 0) {
          onDragStart(opening.id, e.evt);
        }
      }}
    >
      {/* Drag ghost outline */}
      {isDragging && (
        <Rect
          x={topLeft.x - 2}
          y={topLeft.y - 2}
          width={pxWidth + 4}
          height={pxHeight + 4}
          stroke={colors.selectedStroke}
          strokeWidth={1}
          dash={[3, 3]}
          fill="transparent"
        />
      )}
      {/* Door opening (gap in wall) */}
      <Rect
        x={topLeft.x}
        y={topLeft.y}
        width={pxWidth}
        height={pxHeight}
        fill={colors.canvasBg}
        stroke={isSelected ? colors.selectedStroke : colors.electricalStroke}
        strokeWidth={isSelected ? 2 : 1}
      />
      {/* Door leaf line (vertical line showing hinge side) */}
      <Line
        points={leafPoints}
        stroke={colors.dimensionLine}
        strokeWidth={2}
      />
      {/* Door swing indicator arc */}
      <Line
        points={arcPoints}
        stroke={colors.dimensionLine}
        strokeWidth={1}
        dash={[4, 3]}
      />
      {/* Door label */}
      <Text
        x={topLeft.x}
        y={topLeft.y + pxHeight / 2 - 6}
        width={pxWidth}
        text="D"
        align="center"
        fontSize={11}
        fill={colors.dimensionText}
      />
    </Group>
  );
}
