import { useCallback } from 'react'
import { Trash2 } from 'lucide-react'
import { cn } from '@/lib/utils'
import type { DeviceProperties, DiagramEdge } from '@/types'
import type { Node, Edge } from '@xyflow/react'
import type { DeviceNodeData } from '../nodes/DeviceNode'

interface PropertiesPanelProps {
  selectedNode: Node | null
  selectedEdge: Edge | null
  onNodeUpdate: (nodeId: string, data: Partial<DeviceNodeData>) => void
  onEdgeUpdate: (edgeId: string, data: Partial<DiagramEdge>) => void
  onDeleteNode: (nodeId: string) => void
  onDeleteEdge: (edgeId: string) => void
}

const STATUS_OPTIONS = ['unknown', 'online', 'offline', 'degraded'] as const
const CONNECTION_TYPE_OPTIONS = ['ethernet', 'fiber', 'wifi', 'vpn', 'vlan', 'wan'] as const

function FieldLabel({ children }: { children: React.ReactNode }) {
  return (
    <label className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
      {children}
    </label>
  )
}

function FieldInput({ value, onChange, placeholder, mono }: {
  value: string
  onChange: (val: string) => void
  placeholder?: string
  mono?: boolean
}) {
  return (
    <input
      type="text"
      value={value}
      onChange={e => onChange(e.target.value)}
      placeholder={placeholder}
      className={cn(
        'w-full rounded border border-default bg-input px-2 py-1.5 text-xs text-primary placeholder:text-muted-foreground focus:border-accent focus:outline-none',
        mono && 'font-mono',
      )}
    />
  )
}

export function PropertiesPanel({
  selectedNode,
  selectedEdge,
  onNodeUpdate,
  onEdgeUpdate,
  onDeleteNode,
  onDeleteEdge,
}: PropertiesPanelProps) {
  const handlePropertyChange = useCallback((field: keyof DeviceProperties, value: string) => {
    if (!selectedNode) return
    const nodeData = selectedNode.data as unknown as DeviceNodeData
    onNodeUpdate(selectedNode.id, {
      properties: { ...nodeData.properties, [field]: value },
    } as Partial<DeviceNodeData>)
  }, [selectedNode, onNodeUpdate])

  const handleLabelChange = useCallback((value: string) => {
    if (!selectedNode) return
    onNodeUpdate(selectedNode.id, { label: value } as Partial<DeviceNodeData>)
  }, [selectedNode, onNodeUpdate])

  if (!selectedNode && !selectedEdge) {
    return (
      <div className="flex h-full w-[260px] flex-col items-center justify-center border-l border-default bg-sidebar px-4">
        <p className="text-center text-xs text-muted-foreground">
          Select a device or connection to edit its properties
        </p>
      </div>
    )
  }

  if (selectedEdge) {
    const edgeData = (selectedEdge.data || {}) as Record<string, unknown>
    const connectionType = (edgeData.connectionType as string) || 'ethernet'
    const isCustomType = !CONNECTION_TYPE_OPTIONS.includes(connectionType as typeof CONNECTION_TYPE_OPTIONS[number])

    return (
      <div className="flex h-full w-[260px] flex-col border-l border-default bg-sidebar">
        <div className="border-b border-default px-3 py-2">
          <h3 className="text-xs font-semibold text-heading">Connection</h3>
        </div>
        <div className="flex flex-1 flex-col gap-3 overflow-y-auto p-3">
          <div className="flex flex-col gap-1">
            <FieldLabel>Label</FieldLabel>
            <FieldInput
              value={(selectedEdge.label as string) || ''}
              onChange={val => onEdgeUpdate(selectedEdge.id, { label: val || null })}
              placeholder="Connection label"
            />
          </div>
          <div className="flex flex-col gap-1">
            <FieldLabel>Connection Type</FieldLabel>
            <select
              value={isCustomType ? '__custom__' : connectionType}
              onChange={e => {
                const val = e.target.value
                if (val !== '__custom__') {
                  onEdgeUpdate(selectedEdge.id, { connectionType: val })
                }
              }}
              className="w-full rounded border border-default bg-input px-2 py-1.5 text-xs text-primary focus:border-accent focus:outline-none"
            >
              {CONNECTION_TYPE_OPTIONS.map(opt => (
                <option key={opt} value={opt}>{opt.charAt(0).toUpperCase() + opt.slice(1)}</option>
              ))}
              <option value="__custom__">Custom...</option>
            </select>
            {isCustomType && (
              <FieldInput
                value={connectionType}
                onChange={val => onEdgeUpdate(selectedEdge.id, { connectionType: val })}
                placeholder="Custom type name"
              />
            )}
          </div>
          <div className="flex flex-col gap-1">
            <FieldLabel>Speed</FieldLabel>
            <FieldInput
              value={(edgeData.speed as string) || ''}
              onChange={val => onEdgeUpdate(selectedEdge.id, { speed: val || null })}
              placeholder="e.g. 1 Gbps"
            />
          </div>
          <div className="flex flex-col gap-1">
            <FieldLabel>Notes</FieldLabel>
            <FieldInput
              value={(edgeData.notes as string) || ''}
              onChange={val => onEdgeUpdate(selectedEdge.id, { notes: val || null })}
              placeholder="Port info, cable type..."
              mono
            />
          </div>
        </div>
        <div className="border-t border-default p-3">
          <button
            onClick={() => onDeleteEdge(selectedEdge.id)}
            className="flex w-full items-center justify-center gap-1.5 rounded border border-red-500/30 px-2 py-1.5 text-xs text-red-400 hover:bg-red-500/10"
          >
            <Trash2 size={12} />
            Delete Connection
          </button>
        </div>
      </div>
    )
  }

  const nodeData = selectedNode!.data as unknown as DeviceNodeData
  const props = nodeData.properties || {} as DeviceProperties

  return (
    <div className="flex h-full w-[260px] flex-col border-l border-default bg-sidebar">
      <div className="border-b border-default px-3 py-2">
        <h3 className="text-xs font-semibold text-heading">Device Properties</h3>
      </div>
      <div className="flex flex-1 flex-col gap-3 overflow-y-auto p-3">
        <div className="flex flex-col gap-1">
          <FieldLabel>Label</FieldLabel>
          <FieldInput value={nodeData.label} onChange={handleLabelChange} placeholder="Device name" />
        </div>
        <div className="flex flex-col gap-1">
          <FieldLabel>Hostname</FieldLabel>
          <FieldInput value={props.hostname || ''} onChange={v => handlePropertyChange('hostname', v)} placeholder="e.g. core-rtr-01" mono />
        </div>
        <div className="flex flex-col gap-1">
          <FieldLabel>IP Address</FieldLabel>
          <FieldInput value={props.ip || ''} onChange={v => handlePropertyChange('ip', v)} placeholder="e.g. 10.0.0.1" mono />
        </div>
        <div className="flex flex-col gap-1">
          <FieldLabel>Subnet</FieldLabel>
          <FieldInput value={props.subnet || ''} onChange={v => handlePropertyChange('subnet', v)} placeholder="e.g. 10.0.0.0/24" mono />
        </div>
        <div className="flex flex-col gap-1">
          <FieldLabel>Vendor</FieldLabel>
          <FieldInput value={props.vendor || ''} onChange={v => handlePropertyChange('vendor', v)} placeholder="e.g. Cisco" />
        </div>
        <div className="flex flex-col gap-1">
          <FieldLabel>Model</FieldLabel>
          <FieldInput value={props.model || ''} onChange={v => handlePropertyChange('model', v)} placeholder="e.g. ISR 4331" />
        </div>
        <div className="flex flex-col gap-1">
          <FieldLabel>Role</FieldLabel>
          <FieldInput value={props.role || ''} onChange={v => handlePropertyChange('role', v)} placeholder="e.g. Core gateway" />
        </div>
        <div className="flex flex-col gap-1">
          <FieldLabel>VLAN</FieldLabel>
          <FieldInput value={props.vlan || ''} onChange={v => handlePropertyChange('vlan', v)} placeholder="e.g. 10" />
        </div>
        <div className="flex flex-col gap-1">
          <FieldLabel>Status</FieldLabel>
          <select
            value={props.status || 'unknown'}
            onChange={e => handlePropertyChange('status', e.target.value)}
            className="w-full rounded border border-default bg-input px-2 py-1.5 text-xs text-primary focus:border-accent focus:outline-none"
          >
            {STATUS_OPTIONS.map(opt => (
              <option key={opt} value={opt}>{opt.charAt(0).toUpperCase() + opt.slice(1)}</option>
            ))}
          </select>
        </div>
        <div className="flex flex-col gap-1">
          <FieldLabel>Notes</FieldLabel>
          <textarea
            value={props.notes || ''}
            onChange={e => handlePropertyChange('notes', e.target.value)}
            placeholder="Additional notes..."
            rows={3}
            className="w-full resize-none rounded border border-default bg-input px-2 py-1.5 text-xs text-primary placeholder:text-muted-foreground focus:border-accent focus:outline-none"
          />
        </div>
      </div>
      <div className="border-t border-default p-3">
        <button
          onClick={() => onDeleteNode(selectedNode!.id)}
          className="flex w-full items-center justify-center gap-1.5 rounded border border-red-500/30 px-2 py-1.5 text-xs text-red-400 hover:bg-red-500/10"
        >
          <Trash2 size={12} />
          Delete Device
        </button>
      </div>
    </div>
  )
}
