import { memo } from 'react'
import { Position, NodeResizer, type NodeProps } from '@xyflow/react'
import { BaseNode, BaseNodeHeader, BaseNodeHeaderTitle, BaseNodeContent } from '../ui/base-node'
import { BaseHandle } from '../ui/base-handle'
import { NodeStatusIndicator, type NodeStatus } from '../ui/node-status-indicator'
import { NodeTooltip, NodeTooltipTrigger, NodeTooltipContent } from '../ui/node-tooltip'
import { getDeviceRenderConfig } from './deviceRegistry'
import type { DeviceProperties } from '@/types'

export interface DeviceNodeData {
  label: string
  deviceType: string
  category?: string
  properties: DeviceProperties
  [key: string]: unknown
}

function TooltipRow({ label, value }: { label: string; value: string | null | undefined }) {
  if (!value) return null
  return (
    <div className="flex gap-2">
      <span className="text-[10px] uppercase tracking-wider text-muted-foreground">{label}</span>
      <span className="text-xs font-mono text-primary">{value}</span>
    </div>
  )
}

const NODE_DEFAULT = 120  // default square side in px
const NODE_MIN = 80       // minimum square side in px
const NODE_MAX = 280      // maximum square side in px

function DeviceNodeComponent({ data, selected, width, height }: NodeProps) {
  const nodeData = data as unknown as DeviceNodeData
  const { icon: Icon, color } = getDeviceRenderConfig(nodeData.deviceType, nodeData.category)
  const status = (nodeData.properties?.status || 'unknown') as NodeStatus
  const ip = nodeData.properties?.ip
  const props = nodeData.properties || {}

  // Use the shorter dimension so content never overflows a non-square node
  const size = Math.min(width ?? NODE_DEFAULT, height ?? NODE_DEFAULT)
  const scale = size / NODE_DEFAULT

  // Icon: 28px at default, clamped to [14, 72]
  const iconPx = Math.round(Math.max(14, Math.min(72, scale * 28)))
  // Label font: 11px at default, clamped to [9, 20]
  const labelPx = Math.max(9, Math.min(20, Math.round(scale * 11)))
  // IP font: 9px at default, clamped to [8, 16]
  const ipPx = Math.max(8, Math.min(16, Math.round(scale * 9)))

  const hasTooltipContent = props.hostname || props.ip || props.vendor || props.model || props.role || props.notes

  return (
    <>
      <NodeResizer
        isVisible={selected}
        minWidth={NODE_MIN}
        minHeight={NODE_MIN}
        maxWidth={NODE_MAX}
        maxHeight={NODE_MAX}
        keepAspectRatio
        lineStyle={{ borderColor: 'var(--color-accent)', borderWidth: 1 }}
        handleStyle={{ width: 8, height: 8, borderColor: 'var(--color-accent)', background: 'var(--color-card)' }}
      />
      <NodeStatusIndicator status={status}>
        <NodeTooltip>
          <NodeTooltipTrigger>
            <BaseNode className="w-full h-full group flex flex-col items-center justify-center">
              <BaseNodeHeader className="flex-col gap-1 items-center py-2 px-2">
                <Icon size={iconPx} style={{ color }} />
                <BaseNodeHeaderTitle className="text-center leading-tight" style={{ fontSize: labelPx }}>
                  {nodeData.label}
                </BaseNodeHeaderTitle>
              </BaseNodeHeader>
              {ip && (
                <BaseNodeContent className="items-center pt-0 pb-1">
                  <span className="font-mono text-muted-foreground" style={{ fontSize: ipPx }}>{ip}</span>
                </BaseNodeContent>
              )}
              <BaseHandle type="target" position={Position.Top} />
              <BaseHandle type="source" position={Position.Bottom} />
              <BaseHandle type="target" position={Position.Left} id="left" />
              <BaseHandle type="source" position={Position.Right} id="right" />
            </BaseNode>
          </NodeTooltipTrigger>
          {hasTooltipContent && (
            <NodeTooltipContent position={Position.Top}>
              <div className="flex flex-col gap-1 min-w-[140px]">
                <TooltipRow label="Host" value={props.hostname} />
                <TooltipRow label="IP" value={props.ip} />
                {(props.vendor || props.model) && (
                  <TooltipRow label="HW" value={[props.vendor, props.model].filter(Boolean).join(' ')} />
                )}
                <TooltipRow label="Role" value={props.role} />
                {props.notes && (
                  <TooltipRow label="Notes" value={props.notes.length > 100 ? props.notes.slice(0, 100) + '...' : props.notes} />
                )}
              </div>
            </NodeTooltipContent>
          )}
        </NodeTooltip>
      </NodeStatusIndicator>
    </>
  )
}

export const DeviceNode = memo(DeviceNodeComponent)
