import React from 'react';
import type { BoardInstance } from '../../types/board';
import { ArduinoUno } from '../velxio-components/ArduinoUno';
import { ArduinoNano } from '../velxio-components/ArduinoNano';
import { ArduinoMega } from '../velxio-components/ArduinoMega';
// NanoRP2040 (wokwi-nano-rp2040-connect) used to back the 'raspberry-pi-pico'
// boardKind by mistake — kept the import out so future contributors don't
// re-wire it back in. If someone genuinely needs a Nano RP2040 Connect
// board (D2..D13 labels), add a new boardKind 'arduino-nano-rp2040'.
import { RaspberryPi3 } from '../velxio-components/RaspberryPi3';
import { RaspberryPi4 } from '../velxio-components/RaspberryPi4';
import { RaspberryPi5 } from '../velxio-components/RaspberryPi5';
import { Esp32 } from '../velxio-components/Esp32';
import { Attiny85 } from '../velxio-components/Attiny85';
import { PiPicoW } from '../velxio-components/PiPicoW';
import {
  Stm32BluePill,
  Stm32BlackPill,
  Stm32BluePillF103CB,
  Stm32BlackPillF401,
  Stm32F4Discovery,
  Stm32OlimexH405,
  Stm32NetduinoPlus2,
  Stm32Netduino2,
} from '../velxio-components/Stm32BluePill';
import { PinOverlay } from './PinOverlay';

// Board visual dimensions (width × height) for the drag-overlay sizing.
// ESP32 sizes match the wokwi-boards SVG rendered at 5 px/mm.
const BOARD_SIZE: Record<string, { w: number; h: number }> = {
  // wokwi-elements: rendered at 96 dpi — 1mm = 3.7795px
  'arduino-uno': { w: 274, h: 202 }, // 72.58mm × 53.34mm
  'arduino-nano': { w: 170, h: 67 }, // 44.9mm  × 17.8mm
  'arduino-mega': { w: 388, h: 192 }, // 102.66mm × 50.80mm
  // Pi Pico physical board is 51mm × 21mm vertical-narrow. The render
  // uses velxio's <velxio-pi-pico-w>, same Web Component as 'pi-pico-w'
  // because the Pico and Pico W are pin-compatible. Used to render the
  // wokwi-nano-rp2040-connect (168×68) — that was a completely different
  // board with D2-D13 pin labels, so wires in pico examples that
  // referenced GP10/GP18/etc. landed at (0,0). The render now matches
  // the boardKind name.
  'raspberry-pi-pico': { w: 105, h: 264 },
  'raspberry-pi-3': { w: 250, h: 160 }, // RaspberryPi3Element: PI_WIDTH=250 PI_HEIGHT=160
  'raspberry-pi-4': { w: 330, h: 215 }, // RaspberryPi4Element — real board photo (925×602 @ scale)
  'raspberry-pi-5': { w: 330, h: 220 }, // RaspberryPi5Element — real board photo (1024×681 @ scale)
  esp32: { w: 141, h: 265 }, // esp32-devkit-v1: 28.2 × 53 mm
  'esp32-s3': { w: 128, h: 350 }, // esp32-s3-devkitc-1: 25.5 × 70 mm
  'esp32-c3': { w: 127, h: 215 }, // esp32-c3-devkitm-1: 25.4 × 42.9 mm
  'pi-pico-w': { w: 105, h: 264 },
  'esp32-devkit-c-v4': { w: 140, h: 283 },
  'esp32-cam': { w: 136, h: 202 },
  'wemos-lolin32-lite': { w: 128, h: 250 },
  'xiao-esp32-s3': { w: 91, h: 117 },
  'arduino-nano-esp32': { w: 217, h: 90 },
  'xiao-esp32-c3': { w: 91, h: 117 },
  'aitewinrobot-esp32c3-supermini': { w: 90, h: 123 },
  'stm32-bluepill': { w: 114, h: 271 }, // 22.855 × 54.193 mm (wokwi-boards SVG)
  'stm32-blackpill': { w: 103, h: 266 }, // 20.695 × 53.125 mm (wokwi-boards SVG)
  'stm32-bluepill-f103cb': { w: 114, h: 271 }, // reuses Blue Pill SVG
  'stm32-blackpill-f401': { w: 103, h: 266 }, // reuses Black Pill SVG
  // Inline-rendered boards — sizes match Stm32BoardElement.inlineConfig()
  // (INLINE_W=158; h = 24 + rows*13 + 16).
  'stm32-f4-discovery': { w: 158, h: 235 }, // 15 rows per side
  'stm32-olimex-h405': { w: 158, h: 196 }, // 12 rows per side
  'stm32-netduino-plus2': { w: 158, h: 196 }, // 12 rows per side
  'stm32-netduino2': { w: 158, h: 196 }, // 12 rows per side
  attiny85: { w: 160, h: 132 },
};

interface BoardOnCanvasProps {
  board: BoardInstance;
  running: boolean;
  led13?: boolean;
  isActive?: boolean;
  /** When false, the pin overlay is hidden — keeps the canvas uncluttered when
   * the user isn't hovering, isn't selecting, and isn't actively wiring. */
  showPins?: boolean;
  onMouseDown: (e: React.MouseEvent) => void;
  onContextMenu?: (e: React.MouseEvent) => void;
  onMouseEnter?: () => void;
  onMouseLeave?: () => void;
  onPinClick: (componentId: string, pinName: string, x: number, y: number) => void;
  zoom?: number;
}

export const BoardOnCanvas = ({
  board,
  running,
  led13 = false,
  isActive = false,
  showPins = true,
  onMouseDown,
  onContextMenu,
  onMouseEnter,
  onMouseLeave,
  onPinClick,
  zoom = 1,
}: BoardOnCanvasProps) => {
  const { id, boardKind, x, y } = board;
  const size = BOARD_SIZE[boardKind] ?? { w: 300, h: 200 };

  // Status dot color: green=running, amber=compiled, gray=idle
  const statusColor = board.running ? '#22c55e' : board.compiledProgram ? '#f59e0b' : '#6b7280';

  const boardEl = (() => {
    switch (boardKind) {
      case 'arduino-uno':
        return <ArduinoUno id={id} x={x} y={y} led13={led13} />;
      case 'arduino-nano':
        return <ArduinoNano id={id} x={x} y={y} led13={led13} />;
      case 'arduino-mega':
        return <ArduinoMega id={id} x={x} y={y} led13={led13} />;
      // 'raspberry-pi-pico' used to render <NanoRP2040> (a wokwi-nano-
      // rp2040-connect element with D2-D13 pin labels). That was a
      // misnaming bug — the Nano RP2040 Connect is a different board.
      // Use the same Pico Web Component as 'pi-pico-w' so the pins are
      // labeled GP0..GP28, 3V3, VBUS, etc. — matching the FQBN
      // (rp2040:rp2040:rpipico) and every Pi-Pico sketch's #defines.
      case 'raspberry-pi-pico':
      case 'pi-pico-w':
        return <PiPicoW id={id} x={x} y={y} />;
      case 'raspberry-pi-3':
        return <RaspberryPi3 id={id} x={x} y={y} />;
      case 'raspberry-pi-4':
        return <RaspberryPi4 id={id} x={x} y={y} />;
      case 'raspberry-pi-5':
        return <RaspberryPi5 id={id} x={x} y={y} />;
      case 'esp32':
      case 'esp32-devkit-c-v4':
      case 'esp32-cam':
      case 'wemos-lolin32-lite':
      case 'esp32-s3':
      case 'xiao-esp32-s3':
      case 'arduino-nano-esp32':
      case 'esp32-c3':
      case 'xiao-esp32-c3':
      case 'aitewinrobot-esp32c3-supermini':
        return <Esp32 id={id} x={x} y={y} boardKind={boardKind} />;
      case 'stm32-bluepill':
        return <Stm32BluePill id={id} x={x} y={y} />;
      case 'stm32-blackpill':
        return <Stm32BlackPill id={id} x={x} y={y} />;
      case 'stm32-bluepill-f103cb':
        return <Stm32BluePillF103CB id={id} x={x} y={y} />;
      case 'stm32-blackpill-f401':
        return <Stm32BlackPillF401 id={id} x={x} y={y} />;
      case 'stm32-f4-discovery':
        return <Stm32F4Discovery id={id} x={x} y={y} />;
      case 'stm32-olimex-h405':
        return <Stm32OlimexH405 id={id} x={x} y={y} />;
      case 'stm32-netduino-plus2':
        return <Stm32NetduinoPlus2 id={id} x={x} y={y} />;
      case 'stm32-netduino2':
        return <Stm32Netduino2 id={id} x={x} y={y} />;
      case 'attiny85':
        return <Attiny85 id={id} x={x} y={y} led1={led13} />;
    }
  })();

  return (
    <>
      {boardEl}

      {/* Active board highlight ring */}
      {isActive && (
        <div
          style={{
            position: 'absolute',
            left: x - 3,
            top: y - 3,
            width: size.w + 6,
            height: size.h + 6,
            border: '2px solid #007acc',
            borderRadius: 6,
            pointerEvents: 'none',
            zIndex: 2,
          }}
        />
      )}

      {/* Status dot — top-right corner */}
      <div
        style={{
          position: 'absolute',
          left: x + size.w - 10,
          top: y - 6,
          width: 12,
          height: 12,
          borderRadius: '50%',
          background: statusColor,
          border: '2px solid #1e1e1e',
          pointerEvents: 'none',
          zIndex: 10,
          transition: 'background 0.3s',
        }}
        title={board.running ? 'Running' : board.compiledProgram ? 'Compiled' : 'Idle'}
      />

      {/* Drag overlay — hidden during simulation */}
      {!running && (
        <div
          data-board-overlay="true"
          data-board-id={id}
          style={{
            position: 'absolute',
            left: x,
            top: y,
            width: size.w,
            height: size.h,
            cursor: 'move',
            zIndex: 1,
          }}
          onMouseDown={(e) => {
            e.stopPropagation();
            onMouseDown(e);
          }}
          onContextMenu={onContextMenu}
          onMouseEnter={onMouseEnter}
          onMouseLeave={onMouseLeave}
        />
      )}

      {/* Pin overlay for wire connections */}
      <PinOverlay
        componentId={id}
        componentX={x}
        componentY={y}
        onPinClick={onPinClick}
        showPins={showPins}
        wrapperOffsetX={0}
        wrapperOffsetY={0}
        zoom={zoom}
      />
    </>
  );
};
