import { memo, useMemo } from 'react';
import { Layer, Group, Rect, Line } from 'react-konva';
import type { Point, FurnitureItem } from '@house-plan-maker/shared';
import { BedSilhouette } from '../symbols/furniture/BedSilhouette';
import { DeskSilhouette } from '../symbols/furniture/DeskSilhouette';
import { WardrobeSilhouette } from '../symbols/furniture/WardrobeSilhouette';
import { SofaSilhouette } from '../symbols/furniture/SofaSilhouette';
import { TableSilhouette } from '../symbols/furniture/TableSilhouette';
import { ChairSilhouette } from '../symbols/furniture/ChairSilhouette';
import { ShelfSilhouette } from '../symbols/furniture/ShelfSilhouette';
import { TvSilhouette } from '../symbols/furniture/TvSilhouette';
import { findCollidingFurniture } from '../utils/collisionDetection';

interface FurnitureLayerProps {
  readonly items: readonly FurnitureItem[];
  readonly zoom: number;
  readonly panOffset: Point;
  readonly selectedIds: ReadonlySet<string>;
  readonly visible?: boolean;
}

const FURNITURE_COLOR = '#495057';
const FURNITURE_FILL = 'rgba(222, 226, 230, 0.5)';
const SELECTED_COLOR = '#4c6ef5';
const SELECTED_FILL = 'rgba(76, 110, 245, 0.1)';
const COLLISION_COLOR = '#e03131';
const COLLISION_FILL = 'rgba(224, 49, 49, 0.1)';

function toScreen(point: Point, zoom: number, panOffset: Point): { x: number; y: number } {
  return {
    x: point.x * zoom + panOffset.x,
    y: point.y * zoom + panOffset.y,
  };
}

export const FurnitureLayer = memo(function FurnitureLayer({
  items,
  zoom,
  panOffset,
  selectedIds,
  visible = true,
}: FurnitureLayerProps) {
  const collidingIds = useMemo(() => findCollidingFurniture(items), [items]);

  return (
    <Layer listening={false} visible={visible}>
      {items.map((item) => {
        // x,y is the top-left corner; compute center for silhouette rendering
        const centerX = item.x + item.width / 2;
        const centerY = item.y + item.depth / 2;
        const screenCenter = toScreen({ x: centerX, y: centerY }, zoom, panOffset);
        const isSelected = selectedIds.has(item.id);
        const isColliding = collidingIds.has(item.id);
        const widthPx = item.width * zoom;
        const depthPx = item.depth * zoom;

        const color = isColliding ? COLLISION_COLOR : isSelected ? SELECTED_COLOR : FURNITURE_COLOR;
        const fillColor = isColliding ? COLLISION_FILL : isSelected ? SELECTED_FILL : FURNITURE_FILL;

        return (
          <Group key={item.id}>
            {renderFurnitureSilhouette(
              item.type,
              screenCenter.x,
              screenCenter.y,
              widthPx,
              depthPx,
              item.rotation,
              color,
              fillColor,
            )}
            {/* Rotation handle indicator for selected furniture */}
            {isSelected && (
              <RotationHandle
                x={screenCenter.x}
                y={screenCenter.y}
                depthPx={depthPx}
                rotation={item.rotation}
              />
            )}
          </Group>
        );
      })}
    </Layer>
  );
});

interface RotationHandleProps {
  readonly x: number;
  readonly y: number;
  readonly depthPx: number;
  readonly rotation: number;
}

function RotationHandle({ x, y, depthPx, rotation }: RotationHandleProps) {
  const handleOffset = depthPx / 2 + 12;
  const rad = (rotation * Math.PI) / 180;
  const hx = x - Math.sin(rad) * handleOffset;
  const hy = y - Math.cos(rad) * handleOffset;

  return (
    <Group>
      {/* Line from center to handle */}
      <Line
        points={[x, y, hx, hy]}
        stroke={SELECTED_COLOR}
        strokeWidth={1}
        dash={[3, 3]}
        listening={false}
      />
      {/* Handle circle */}
      <Rect
        x={hx - 4}
        y={hy - 4}
        width={8}
        height={8}
        fill={SELECTED_COLOR}
        cornerRadius={4}
        listening={false}
      />
    </Group>
  );
}

function renderFurnitureSilhouette(
  type: string,
  x: number,
  y: number,
  width: number,
  depth: number,
  rotation: number,
  color: string,
  fillColor: string,
): React.ReactNode {
  const props = { x, y, width, depth, rotation, color, fillColor };

  switch (type) {
    case 'BED':
      return <BedSilhouette {...props} />;
    case 'DESK':
      return <DeskSilhouette {...props} />;
    case 'WARDROBE':
      return <WardrobeSilhouette {...props} />;
    case 'SOFA':
      return <SofaSilhouette {...props} />;
    case 'TABLE':
      return <TableSilhouette {...props} />;
    case 'CHAIR':
      return <ChairSilhouette {...props} />;
    case 'SHELF':
    case 'BOOKCASE':
      return <ShelfSilhouette {...props} />;
    case 'NIGHTSTAND':
      return <DeskSilhouette {...props} />;
    case 'DRESSER':
      return <WardrobeSilhouette {...props} />;
    case 'TV':
      return <TvSilhouette {...props} />;
    default:
      // Generic rectangle for OTHER / unknown
      return (
        <Rect
          x={x - width / 2}
          y={y - depth / 2}
          width={width}
          height={depth}
          rotation={rotation}
          stroke={color}
          strokeWidth={1.5}
          fill={fillColor}
          listening={false}
        />
      );
  }
}
