import { h } from 'preact';
import { useState } from 'preact/hooks';
import type { Interface, Widget, SignalRef } from './lib/types';
import TextView from './widgets/TextView';
import TextLabel from './widgets/TextLabel';
import Gauge from './widgets/Gauge';
import BarH from './widgets/BarH';
import BarV from './widgets/BarV';
import Led from './widgets/Led';
import MultiLed from './widgets/MultiLed';
import SetValue from './widgets/SetValue';
import Button from './widgets/Button';
import PlotWidget from './widgets/PlotWidget';
import ImageWidget from './widgets/ImageWidget';
import LinkWidget from './widgets/LinkWidget';
import ContextMenu from './ContextMenu';

const COMPONENTS: Record<string, any> = {
  textview:  TextView,
  textlabel: TextLabel,
  gauge:     Gauge,
  barh:      BarH,
  barv:      BarV,
  led:       Led,
  multiled:  MultiLed,
  setvalue:  SetValue,
  button:    Button,
  plot:      PlotWidget,
  image:     ImageWidget,
  link:      LinkWidget,
};

interface CtxState {
  visible: boolean;
  x: number;
  y: number;
  signal: SignalRef | null;
}

interface Props {
  iface: Interface | null;
  onNavigate?: (interfaceId: string) => void;
  timeRange?: { start: string; end: string } | null;
}

export default function Canvas({ iface, onNavigate, timeRange }: Props) {
  const [ctxMenu, setCtxMenu] = useState<CtxState>({
    visible: false, x: 0, y: 0, signal: null,
  });

  function onCtxMenu(e: MouseEvent, widget: Widget) {
    e.preventDefault();
    e.stopPropagation();
    setCtxMenu({ visible: true, x: e.clientX, y: e.clientY, signal: widget.signals[0] ?? null });
  }

  if (!iface) {
    return (
      <div class="canvas-container">
        <div class="placeholder">
          <p>Select an interface from the left panel, or import one.</p>
        </div>
      </div>
    );
  }

  return (
    <div class="canvas-container">
      <div class="canvas-area" style={`width:${iface.w}px;height:${iface.h}px;`}>
        {iface.widgets.map(widget => {
          const Comp = COMPONENTS[widget.type];
          return Comp
            ? <Comp
                key={widget.id}
                widget={widget}
                onContextMenu={(e: MouseEvent) => onCtxMenu(e, widget)}
                onNavigate={onNavigate}
                timeRange={timeRange}
              />
            : (
              <div
                key={widget.id}
                class="unknown-widget"
                style={`left:${widget.x}px;top:${widget.y}px;width:${widget.w}px;height:${widget.h}px;`}
                title={`Unknown widget type: ${widget.type}`}
                onContextMenu={(e: MouseEvent) => onCtxMenu(e, widget)}
              >
                <span class="unknown-label">{widget.type}</span>
              </div>
            );
        })}
      </div>
      <ContextMenu
        {...ctxMenu}
        onClose={() => setCtxMenu(c => ({ ...c, visible: false }))}
      />
    </div>
  );
}
