import { Group, Circle, Line, Rect, Text, Arc } from 'react-konva';
import type { ProjectedElectrical } from '../utils/projectionMapping';
import { projectionToPixel } from '../utils/projectionMapping';
import { DEFAULT_OUTLET_WIDTH, DEFAULT_OUTLET_HEIGHT } from '@house-plan-maker/shared';
import { getWallLightStyle, getOutletDirection } from '../symbols/electrical';
import { useCanvasColors } from '../utils/canvasThemeColors';

interface ProjectionElectricalProps {
  readonly projected: ProjectedElectrical;
  readonly wallHeight: number;
  readonly scale: number;
  readonly padding: number;
  readonly isSelected: boolean;
  readonly isDragging?: boolean;
  readonly dragFromFloor?: number;
  readonly dragAlongWall?: number;
  /** Physical width of a single outlet face plate (meters). */
  readonly outletWidth?: number;
  /** Physical height of a single outlet face plate (meters). */
  readonly outletHeight?: number;
  readonly onClick: () => void;
  readonly onDragStart?: (itemId: string, evt: MouseEvent) => void;
}

const SYMBOL_SIZE = 12;

/** Render a wall-mounted electrical item in wall elevation view. */
export function ProjectionElectrical({
  projected,
  wallHeight,
  scale,
  padding,
  isSelected,
  isDragging = false,
  dragFromFloor,
  dragAlongWall,
  outletWidth = DEFAULT_OUTLET_WIDTH,
  outletHeight = DEFAULT_OUTLET_HEIGHT,
  onClick,
  onDragStart,
}: ProjectionElectricalProps) {
  const colors = useCanvasColors();
  const { position, item } = projected;

  const displayFromFloor = isDragging && dragFromFloor != null ? dragFromFloor : position.fromFloor;
  const displayAlongWall = isDragging && dragAlongWall != null ? dragAlongWall : position.alongWall;

  const center = projectionToPixel(
    displayAlongWall,
    displayFromFloor,
    wallHeight,
    scale,
    padding,
  );

  const strokeColor = isSelected ? colors.selectedStroke : colors.electricalStroke;
  const fillColor = isSelected ? colors.selectedFill : colors.electricalFill;
  const half = SYMBOL_SIZE / 2;

  return (
    <Group
      onClick={onClick}
      onMouseDown={(e) => {
        if (onDragStart && e.evt.button === 0) {
          onDragStart(item.id, e.evt);
        }
      }}
      style={{ cursor: onDragStart ? 'grab' : 'default' }}
    >
      {/* Drag ghost outline */}
      {isDragging && (
        <Rect
          x={center.x - half - 2}
          y={center.y - half - 2}
          width={SYMBOL_SIZE + 4}
          height={SYMBOL_SIZE + 4}
          stroke={colors.selectedStroke}
          strokeWidth={1}
          dash={[3, 3]}
          fill="transparent"
        />
      )}
      {item.type === 'OUTLET' && (() => {
        const safeCount = Math.max(1, Math.round(item.count));
        const direction = getOutletDirection(item.metadata);
        const isVertical = direction === 'vertical';
        // Convert physical outlet dims to projection-pixel dims.
        const wPx = outletWidth * scale;
        const hPx = outletHeight * scale;
        // Anchor offset to bounding-box center, in projection pixels.
        // Horizontal axis = along-wall (positive right), vertical axis = up the wall.
        // In screen coords +y is down, so vertical='top' anchor means center is BELOW (positive y).
        //
        // When the projection axis is flipped (the canonical direction
        // runs opposite to the wall's stored start→end), we mirror the
        // horizontal anchor so "left" still refers to the same physical
        // side of the wall in both 3D and projection views. Without this
        // an outlet anchored "left" on a flipped wall would appear on
        // opposite sides of the two views.
        const anchor = item.positionAnchor;
        const mirroredHorizontal = projected.axisFlipped
          ? anchor.horizontal === 'left'
            ? 'right'
            : anchor.horizontal === 'right'
              ? 'left'
              : 'middle'
          : anchor.horizontal;
        // Bounding box of the full outlet group depends on layout direction.
        const totalW = isVertical ? wPx : safeCount * wPx;
        const totalH = isVertical ? safeCount * hPx : hPx;
        const offX =
          mirroredHorizontal === 'left' ? totalW / 2 : mirroredHorizontal === 'right' ? -totalW / 2 : 0;
        const offY =
          anchor.vertical === 'top' ? totalH / 2 : anchor.vertical === 'bottom' ? -totalH / 2 : 0;
        const cx = center.x + offX;
        const cy = center.y + offY;
        const groupLeft = cx - totalW / 2;
        const groupTop = cy - totalH / 2;
        const cellMin = Math.min(wPx, hPx);
        const faceR = cellMin * 0.32;
        const prongL = cellMin * 0.18;
        const prongG = cellMin * 0.12;
        return (
          <>
            {Array.from({ length: safeCount }).map((_, i) => {
              const cellLeft = isVertical ? groupLeft : groupLeft + i * wPx;
              const cellTop = isVertical ? groupTop + i * hPx : groupTop;
              const cellCx = cellLeft + wPx / 2;
              const cellCy = cellTop + hPx / 2;
              return (
                <Group key={i}>
                  <Rect
                    x={cellLeft}
                    y={cellTop}
                    width={wPx}
                    height={hPx}
                    cornerRadius={Math.max(1, cellMin * 0.12)}
                    fill={fillColor}
                    stroke={strokeColor}
                    strokeWidth={1.25}
                  />
                  <Circle
                    x={cellCx}
                    y={cellCy}
                    radius={faceR}
                    stroke={strokeColor}
                    strokeWidth={1.25}
                    fill="transparent"
                  />
                  <Line
                    points={[cellCx - prongG, cellCy - prongL, cellCx - prongG, cellCy + prongL]}
                    stroke={strokeColor}
                    strokeWidth={1.25}
                  />
                  <Line
                    points={[cellCx + prongG, cellCy - prongL, cellCx + prongG, cellCy + prongL]}
                    stroke={strokeColor}
                    strokeWidth={1.25}
                  />
                </Group>
              );
            })}
          </>
        );
      })()}
      {item.type === 'SWITCH' && (
        <>
          {/* IEC switch symbol: circle with diagonal line */}
          <Circle
            x={center.x}
            y={center.y}
            radius={half}
            fill={fillColor}
            stroke={strokeColor}
            strokeWidth={1.5}
          />
          <Line
            points={[
              center.x - half + 2,
              center.y + half - 2,
              center.x + half - 2,
              center.y - half + 2,
            ]}
            stroke={strokeColor}
            strokeWidth={1.5}
          />
        </>
      )}
      {item.type === 'LIGHT_WALL' && (() => {
        const wallLightStyle = getWallLightStyle(item.metadata);
        if (wallLightStyle === 'pendant-globe') {
          // Pendant globe: gooseneck line + hanging cord + circle globe
          const armTop = center.y - half * 1.8;
          const cordBottom = center.y + half * 0.6;
          return (
            <>
              {/* Wall mount dot */}
              <Circle x={center.x} y={center.y} radius={3} fill="#b8860b" stroke={strokeColor} strokeWidth={1} />
              {/* Gooseneck arm going up */}
              <Line points={[center.x, center.y, center.x, armTop]} stroke="#b8860b" strokeWidth={1.5} />
              {/* Arm curving outward */}
              <Line points={[center.x, armTop, center.x + half * 0.8, armTop]} stroke="#b8860b" strokeWidth={1.5} />
              {/* Cord hanging down */}
              <Line points={[center.x + half * 0.8, armTop, center.x + half * 0.8, cordBottom]} stroke="#d4c090" strokeWidth={1} />
              {/* Glass globe */}
              <Circle
                x={center.x + half * 0.8}
                y={cordBottom + half * 0.5}
                radius={half * 0.7}
                fill="rgba(254, 249, 195, 0.4)"
                stroke="#eab308"
                strokeWidth={1}
              />
            </>
          );
        }
        if (wallLightStyle === 'sconce-up') {
          // Sconce up: trapezoid pointing up
          return (
            <>
              <Line
                points={[
                  center.x - half * 0.8, center.y + half * 0.5,
                  center.x - half * 0.4, center.y - half,
                  center.x + half * 0.4, center.y - half,
                  center.x + half * 0.8, center.y + half * 0.5,
                ]}
                closed
                fill="#fef9c3"
                stroke={strokeColor}
                strokeWidth={1.5}
              />
              {/* Light rays upward */}
              <Line points={[center.x, center.y - half, center.x, center.y - half * 1.8]} stroke="#eab308" strokeWidth={1} />
              <Line points={[center.x - half * 0.3, center.y - half, center.x - half * 0.5, center.y - half * 1.6]} stroke="#eab308" strokeWidth={1} />
              <Line points={[center.x + half * 0.3, center.y - half, center.x + half * 0.5, center.y - half * 1.6]} stroke="#eab308" strokeWidth={1} />
            </>
          );
        }
        if (wallLightStyle === 'sconce-down') {
          // Sconce down: trapezoid pointing down
          return (
            <>
              <Line
                points={[
                  center.x - half * 0.8, center.y - half * 0.5,
                  center.x - half * 0.4, center.y + half,
                  center.x + half * 0.4, center.y + half,
                  center.x + half * 0.8, center.y - half * 0.5,
                ]}
                closed
                fill="#fef9c3"
                stroke={strokeColor}
                strokeWidth={1.5}
              />
              {/* Light rays downward */}
              <Line points={[center.x, center.y + half, center.x, center.y + half * 1.8]} stroke="#eab308" strokeWidth={1} />
              <Line points={[center.x - half * 0.3, center.y + half, center.x - half * 0.5, center.y + half * 1.6]} stroke="#eab308" strokeWidth={1} />
              <Line points={[center.x + half * 0.3, center.y + half, center.x + half * 0.5, center.y + half * 1.6]} stroke="#eab308" strokeWidth={1} />
            </>
          );
        }
        // Classic: original circle with light rays
        return (
          <>
            <Circle
              x={center.x}
              y={center.y}
              radius={half}
              fill="#fef9c3"
              stroke={strokeColor}
              strokeWidth={1.5}
            />
            <Line
              points={[
                center.x - half, center.y,
                center.x - half * 1.3, center.y + half * 0.8,
              ]}
              stroke="#eab308"
              strokeWidth={1}
            />
            <Line
              points={[
                center.x + half, center.y,
                center.x + half * 1.3, center.y + half * 0.8,
              ]}
              stroke="#eab308"
              strokeWidth={1}
            />
          </>
        );
      })()}
      {item.type === 'WALL_CABLE' && (
        <>
          {/* Wall plate circle */}
          <Circle
            x={center.x}
            y={center.y}
            radius={half * 0.7}
            fill={fillColor}
            stroke={strokeColor}
            strokeWidth={1.5}
          />
          {/* Cable stub hanging down */}
          <Line
            points={[center.x, center.y + half * 0.7, center.x, center.y + half * 1.6]}
            stroke="#555555"
            strokeWidth={2}
          />
        </>
      )}
      {/* Fallback for other wall-mounted types */}
      {item.type !== 'OUTLET' && item.type !== 'SWITCH' && item.type !== 'LIGHT_WALL' && item.type !== 'WALL_CABLE' && (
        <Rect
          x={center.x - half}
          y={center.y - half}
          width={SYMBOL_SIZE}
          height={SYMBOL_SIZE}
          fill={fillColor}
          stroke={strokeColor}
          strokeWidth={1.5}
        />
      )}
      {/* Type label below symbol — uses the user's custom label if set,
          otherwise falls back to the short type code. */}
      <Text
        x={center.x - 30}
        y={center.y + half + 2}
        width={60}
        text={
          item.label && item.label.trim().length > 0
            ? item.label
            : item.type === 'OUTLET'
              ? 'OUT'
              : item.type === 'SWITCH'
                ? 'SW'
                : item.type === 'WALL_CABLE'
                  ? 'CBL'
                  : 'WL'
        }
        align="center"
        fontSize={8}
        fill={colors.electricalLabel}
      />
    </Group>
  );
}
