import { memo, useMemo } from 'react';
import { Handle, Position, type NodeProps } from '@xyflow/react';
import type { Module } from '../../../types';
import { MODULE_TYPE_COLORS, MODULE_TYPE_LABELS } from '../../../lib/constants';
import { Badge } from '../../ui/Badge';

export interface DeviceNodeData {
  label: string;
  module?: Module;
  [key: string]: unknown;
}

export const DeviceNode = memo(({ data, selected }: NodeProps) => {
  const nodeData = data as DeviceNodeData;
  const mod = nodeData.module;

  const colors = mod ? MODULE_TYPE_COLORS[mod.type] : null;

  const meta = useMemo(() => {
    try {
      return nodeData.metadata ? JSON.parse(nodeData.metadata as string) : {};
    } catch {
      return {};
    }
  }, [nodeData.metadata]);

  const ipToDisplay = meta.ipAddress || mod?.ipAddress;
  const hasAddress = ipToDisplay || meta.port;

  return (
    <div
      className={`min-w-[160px] max-w-[200px] bg-slate-800 border rounded-lg shadow-lg overflow-hidden transition-all ${
        selected ? 'ring-2 ring-blue-500 border-blue-500' : 'border-slate-600'
      } ${colors ? colors.border : ''}`}
    >
      <Handle type="target" position={Position.Top} className="!bg-slate-400 !border-slate-600" />

      {/* Colored accent strip */}
      {colors && <div className={`h-1 w-full ${colors.bg}`} />}

      <div className="px-3 py-2">
        <div className="flex items-center gap-1.5 mb-1">
          <svg width="12" height="12" viewBox="0 0 18 18" fill="none" className="shrink-0 opacity-60">
            <rect x="1" y="2" width="16" height="3" rx="1" fill="currentColor" />
            <rect x="1" y="7" width="16" height="3" rx="1" fill="currentColor" opacity="0.7" />
            <rect x="1" y="12" width="16" height="3" rx="1" fill="currentColor" opacity="0.4" />
          </svg>
          <span className="text-xs font-semibold text-slate-100 truncate">{nodeData.label}</span>
        </div>
        {mod && (
          <div className="flex flex-wrap gap-1 mt-1">
            <Badge variant="slate" className="text-[10px]">{MODULE_TYPE_LABELS[mod.type]}</Badge>
            {hasAddress && (
              <span className="text-[10px] text-slate-400 font-mono ml-1 mt-0.5">
                {ipToDisplay}{meta.port ? `:${meta.port}` : ''}
              </span>
            )}
          </div>
        )}
        {!mod && (
          <div className="flex flex-col mt-1">
            <span className="text-[10px] text-slate-500">Unlinked device</span>
            {hasAddress && (
              <span className="text-[10px] text-slate-400 font-mono">
                {ipToDisplay}{meta.port ? `:${meta.port}` : ''}
              </span>
            )}
          </div>
        )}
      </div>

      <Handle type="source" position={Position.Bottom} className="!bg-slate-400 !border-slate-600" />
    </div>
  );
});
DeviceNode.displayName = 'DeviceNode';
