import { useCallback, useEffect, useState, useRef } from 'react'
import ReactFlow, {
  Node,
  Edge,
  Controls,
  Background,
  MiniMap,
  useNodesState,
  useEdgesState,
  addEdge,
  Connection,
  MarkerType,
  NodeTypes,
  Panel
} from 'reactflow'
import 'reactflow/dist/style.css'
import { api } from '../services/api'
import { OrganizationalUnit, OrganizationalUnitType } from '@skillmate/shared'
import { Upload } from 'lucide-react'

// Custom Node Component (vorheriger Look, aber mit soliden dezenten Farben)
const OrganizationNode = ({ data }: { data: any }) => {
  const getTypeIcon = (type: OrganizationalUnitType) => {
    const icons = {
      direktion: '🏛️',
      abteilung: '🏢',
      dezernat: '📁',
      sachgebiet: '📋',
      teildezernat: '🔧',
      fuehrungsstelle: '⭐',
      stabsstelle: '🎯',
      sondereinheit: '🛡️'
    }
    return icons[type] || '📄'
  }

  const getAccent = (type: OrganizationalUnitType): string => {
    switch (type) {
      case 'direktion': return '#1E3A8A' // navy
      case 'abteilung': return '#334155' // slate-700
      case 'dezernat': return '#1D4ED8' // blue-700
      case 'sachgebiet': return '#64748B' // slate-500
      case 'teildezernat': return '#64748B' // slate-500
      case 'stabsstelle': return '#374151' // gray-700
      case 'sondereinheit': return '#475569' // slate-600
      default: return '#334155'
    }
  }

  return (
    <div className="bg-white rounded-lg shadow-sm border border-gray-300 w-[300px] text-slate-900">
      <div
        className="p-2 text-white rounded-t-md"
        style={{ backgroundColor: getAccent(data.type) }}
      >
        <div className="flex items-center justify-between">
          <span className="text-base" aria-hidden>{getTypeIcon(data.type)}</span>
          {data.code && (
            <span className="text-[11px] opacity-90 font-mono bg-white/10 px-2 py-0.5 rounded">
              {data.code}
            </span>
          )}
        </div>
      </div>
      <div className="p-3">
        <h4 className="font-semibold text-slate-900 text-sm leading-snug">
          {data.name}
        </h4>
        {data.employeeCount !== undefined && (
          <p className="text-[11px] text-slate-600 mt-1">
            👥 {data.employeeCount} Mitarbeitende
          </p>
        )}
        {data.hasFuehrungsstelle && (
          <span className="inline-block px-2 py-0.5 mt-2 text-[11px] bg-slate-100 text-slate-700 rounded border border-slate-200">
            FüSt
          </span>
        )}
      </div>
    </div>
  )
}

const nodeTypes: NodeTypes = {
  organization: OrganizationNode
}

export default function OrganizationEditor() {
  const [nodes, setNodes, onNodesChange] = useNodesState([])
  const [edges, setEdges, onEdgesChange] = useEdgesState([])
  const [loading, setLoading] = useState(true)
  const [selectedNode, setSelectedNode] = useState<Node | null>(null)
  const [showAddDialog, setShowAddDialog] = useState(false)
  const [showImportDialog, setShowImportDialog] = useState(false)
  const [uploadProgress, setUploadProgress] = useState<string | null>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [clearExisting, setClearExisting] = useState(false)
  const [issues, setIssues] = useState<{ orphans: Set<string> }>({ orphans: new Set() })
  const [preview, setPreview] = useState<any | null>(null)
  const [pendingOverrides, setPendingOverrides] = useState<Record<string, { parentCode?: string; type?: string; name?: string }>>({})
  const [rememberRules, setRememberRules] = useState(true)
  const [selectedFile, setSelectedFile] = useState<File | null>(null)
  const [parentPicker, setParentPicker] = useState<{ open: boolean; target?: string; suggestions: any[] }>({ open: false, target: undefined, suggestions: [] })
  const [formData, setFormData] = useState({
    name: '',
    code: '',
    type: 'dezernat' as OrganizationalUnitType,
    level: 2,
    parentId: '',
    description: ''
  })

  // Load organizational units
  useEffect(() => {
    loadOrganization()
  }, [])

  const loadOrganization = async () => {
    try {
      setLoading(true)
      const response = await api.get('/organization/hierarchy')
      
      if (response.data.success) {
        const units = response.data.data
        const { nodes: flowNodes, edges: flowEdges } = convertToFlowElements(units)
        setNodes(flowNodes)
        setEdges(flowEdges)
        computeIssues(flowNodes)
      }
    } catch (error) {
      console.error('Failed to load organization:', error)
    } finally {
      setLoading(false)
    }
  }

  const convertToFlowElements = (units: any[], parentPosition = { x: 0, y: 0 }, level = 0): { nodes: Node[], edges: Edge[] } => {
    const nodes: Node[] = []
    const edges: Edge[] = []
    const levelHeight = 150
    const nodeWidth = 300

    units.forEach((unit, index) => {
      const nodeId = unit.id
      const xPos = parentPosition.x + index * nodeWidth
      const yPos = level * levelHeight

      // Use persisted positions if available, otherwise compute defaults
      const persistedX = (typeof unit.positionX === 'number'
        ? unit.positionX
        : (unit.positionX != null && !isNaN(Number(unit.positionX)) ? Number(unit.positionX) : undefined))
      const persistedY = (typeof unit.positionY === 'number'
        ? unit.positionY
        : (unit.positionY != null && !isNaN(Number(unit.positionY)) ? Number(unit.positionY) : undefined))

      nodes.push({
        id: nodeId,
        type: 'organization',
        position: { x: persistedX ?? xPos, y: persistedY ?? yPos },
        data: {
          ...unit,
          level
        }
      })

      // Create edge to parent if exists
      if (unit.parentId) {
        edges.push({
          id: `e-${unit.parentId}-${nodeId}`,
          source: unit.parentId,
          target: nodeId,
          type: 'smoothstep',
          animated: false,
          markerEnd: {
            type: MarkerType.ArrowClosed,
            width: 20,
            height: 20,
            color: '#94a3b8'
          },
          style: {
            strokeWidth: 2,
            stroke: '#94a3b8'
          }
        })
      }

      // Process children recursively
      if (unit.children && unit.children.length > 0) {
        const childElements = convertToFlowElements(
          unit.children,
          { x: xPos, y: yPos },
          level + 1
        )
        nodes.push(...childElements.nodes)
        edges.push(...childElements.edges)
      }
    })

    return { nodes, edges }
  }

  const onConnect = useCallback(
    (params: Connection) => {
      setEdges((eds) => addEdge({
        ...params,
        type: 'smoothstep',
        animated: false,
        markerEnd: {
          type: MarkerType.ArrowClosed,
          width: 20,
          height: 20,
          color: '#94a3b8'
        }
      }, eds))
    },
    [setEdges]
  )

  const onNodeClick = useCallback((_: any, node: Node) => {
    setSelectedNode(node)
  }, [])

  const onNodeDragStop = useCallback(async (_: any, node: Node) => {
    try {
      await api.put(`/organization/units/${node.id}`, {
        positionX: node.position.x,
        positionY: node.position.y
      })
    } catch (error) {
      console.error('Failed to update position:', error)
    }
  }, [])

  const handleAddUnit = async () => {
    try {
      // Build payload and attach selected node as parent if present
      const payload: any = {
        name: formData.name,
        code: formData.code || undefined,
        type: formData.type,
        level: selectedNode ? ((selectedNode.data?.level ?? 0) + 1) : formData.level,
        description: formData.description || undefined,
      }
      if (selectedNode?.id) payload.parentId = selectedNode.id

      const response = await api.post('/organization/units', payload)
      if (response.data.success) {
        await loadOrganization()
        setShowAddDialog(false)
        setFormData({
          name: '',
          code: '',
          type: 'dezernat',
          level: 2,
          parentId: '',
          description: ''
        })
      }
    } catch (error) {
      console.error('Failed to add unit:', error)
    }
  }

  const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]
    if (!file) return
    setSelectedFile(file)

    if (file.type !== 'application/pdf') {
      alert('Bitte laden Sie nur PDF-Dateien hoch.')
      return
    }

    const formData = new FormData()
    formData.append('pdf', file)
    formData.append('clearExisting', String(clearExisting))

    setUploadProgress('PDF wird analysiert (Vorschau)...')

    try {
      const response = await api.post('/organization/import-pdf', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        params: { previewOnly: 'true' }
      })

      if (response.data.success) {
        setPreview(response.data.data)
        setUploadProgress(null)
      }
    } catch (error: any) {
      console.error('PDF import failed:', error)
      setUploadProgress(`Fehler: ${error.response?.data?.error?.message || 'Upload fehlgeschlagen'}`)
    }
  }

  const applyImport = async () => {
    try {
      setUploadProgress('Import wird angewendet...')
      const overrides = Object.entries(pendingOverrides).map(([code, v]) => ({ code, ...v }))
      const fd = new FormData()
      if (selectedFile) fd.append('pdf', selectedFile)
      fd.append('clearExisting', String(clearExisting))
      fd.append('overrides', JSON.stringify(overrides))
      fd.append('previewOnly', 'false')
      fd.append('rememberRules', String(rememberRules))
      const response = await api.post('/organization/import-pdf', fd, {
        headers: { 'Content-Type': 'multipart/form-data' }
      })
      if (response.data.success) {
        setUploadProgress('Erfolgreich importiert.')
        await loadOrganization()
        setTimeout(() => {
          setShowImportDialog(false)
          setUploadProgress(null)
          setPreview(null)
          setPendingOverrides({})
        }, 1200)
      }
    } catch (error: any) {
      console.error('Import apply failed:', error)
      setUploadProgress(`Fehler: ${error.response?.data?.error?.message || 'Import fehlgeschlagen'}`)
    }
  }

  const openParentPicker = async (targetCode: string) => {
    try {
      // Build suggestions from preview (preferred) + existing units
      const suggestions: any[] = []
      if (preview?.diff) {
        const push = (u: any) => { if (u && (u.type === 'dezernat' || u.type === 'abteilung' || u.type === 'direktion')) suggestions.push({ code: u.code, name: u.name, type: u.type }) }
        (preview.diff.create || []).forEach(push)
        ;(preview.diff.update || []).forEach((d: any) => { push(d.incoming); push(d.existing) })
      }
      try {
        const res = await api.get('/organization/units')
        if (res.data.success) {
          res.data.data.forEach((u: any) => {
            if (u && (u.type === 'dezernat' || u.type === 'abteilung' || u.type === 'direktion')) suggestions.push({ code: u.code, name: u.name, type: u.type })
          })
        }
      } catch {}
      // de-duplicate by code
      const uniq: Record<string, any> = {}
      suggestions.forEach(s => { uniq[s.code] = uniq[s.code] || s })
      const list = Object.values(uniq)
      setParentPicker({ open: true, target: targetCode, suggestions: list as any[] })
    } catch (e) {
      setParentPicker({ open: true, target: targetCode, suggestions: [] })
    }
  }

  // Compute simple validation issues (orphans)
  const computeIssues = (flowNodes: Node[]) => {
    const ids = new Set(flowNodes.map(n => n.id))
    const orphanIds = new Set<string>()
    flowNodes.forEach(n => {
      const parentId = (n.data?.parentId as string | undefined)
      if (parentId && !ids.has(parentId)) {
        orphanIds.add(n.id)
      }
    })
    setIssues({ orphans: orphanIds })
    // Apply visual styles
    setNodes(ns => ns.map(n => ({
      ...n,
      style: orphanIds.has(n.id) ? { ...(n.style||{}), border: '2px solid #ef4444' } : { ...(n.style||{}), border: '2px solid #e5e7eb' }
    })))
  }

  // Auto layout: Swimlanes by Abteilung (columns), vertical stacking within lanes
  const handleAutoLayout = () => {
    const laneWidth = 420
    const xMargin = 40
    const yGap = 110
    // Zweistufiges Top-Band: Direktion ganz oben, darunter weitere ROOT-Knoten
    const topYDirector = 10
    let topYRootRow = topYDirector + yGap
    // Spaltenstart mit Abstand unterhalb der Top-Row, um Überlappungen zu vermeiden
    // yStart wird nach Messung der tatsächlichen Kartenhöhen berechnet
    let yStart = topYRootRow + yGap

    const newNodes: Node[] = nodes.map(n => ({ ...n, position: { ...n.position } }))
    const byId: Record<string, Node> = {}
    newNodes.forEach(n => { byId[n.id] = n })

    // Hilfsfunktion: tatsächliche Höhe einer Node messen (Fallback 130px)
    const getNodeHeight = (id: string): number => {
      const el = document.querySelector(`[data-id="${id}"]`) as HTMLElement | null
      if (el) {
        const rect = el.getBoundingClientRect()
        // Mindestens 100, damit sehr kleine Wrapper nicht zu nahe rücken
        return Math.max(100, Math.ceil(rect.height))
      }
      return 130
    }

    const getLaneKey = (n: Node): string => {
      const code: string = n.data?.code || ''
      const type: string = n.data?.type || ''
      if (type === 'direktion') return 'ROOT'
      if (type === 'abteilung') {
        const m = code.match(/Abt\s+(ZA|\d)/i)
        return m ? m[1].toUpperCase() : 'UNK'
      }
      if (type === 'dezernat') {
        if (/ZA/i.test(code)) return 'ZA'
        const m = code.match(/Dez\s+(\d+)/i)
        return m ? m[1].charAt(0) : 'UNK'
      }
      if (type === 'sachgebiet' || type === 'teildezernat') {
        if (/ZA/i.test(code)) return 'ZA'
        const m = code.match(/\s(\d+)\./)
        return m ? m[1].charAt(0) : 'UNK'
      }
      if (type === 'stabsstelle' || type === 'sondereinheit' || type === 'fuehrungsstelle') {
        return 'ROOT'
      }
      // fallback: derive from parent's lane
      const parentId = n.data?.parentId
      if (parentId && byId[parentId]) return getLaneKey(byId[parentId])
      return 'UNK'
    }

    const lanesMap = new Map<string, Node[]>()
    newNodes.forEach(n => {
      const lane = getLaneKey(n)
      if (!lanesMap.has(lane)) lanesMap.set(lane, [])
      lanesMap.get(lane)!.push(n)
    })

    // Sort lanes: 1..6, ZA, ROOT, UNK
    const laneOrder = Array.from(lanesMap.keys()).sort((a, b) => {
      const rank = (k: string) => (k === 'ROOT' ? 99 : (k === 'UNK' ? 98 : (k === 'ZA' ? 7 : parseInt(k, 10))))
      return rank(a) - rank(b)
    })

    // Helper to sort Dez/SG numerically within lane
    const dezOrder = (a: Node, b: Node) => {
      const parseDez = (n: Node) => {
        const c: string = n.data?.code || ''
        if (/ZA/i.test(c)) {
          const m = c.match(/Dez\s+ZA\s*(\d+)/i)
          return 100 + (m ? parseInt(m[1] || '0', 10) : 0)
        }
        const m = c.match(/Dez\s+(\d+)/i)
        return m ? parseInt(m[1], 10) : 0
      }
      return parseDez(a) - parseDez(b)
    }
    const childOrder = (a: Node, b: Node) => {
      const pa = (a.data?.code || '').match(/(\d+)\.(\d+)/)
      const pb = (b.data?.code || '').match(/(\d+)\.(\d+)/)
      const va = pa ? (parseInt(pa[1],10)*100 + parseInt(pa[2],10)) : 0
      const vb = pb ? (parseInt(pb[1],10)*100 + parseInt(pb[2],10)) : 0
      return va - vb
    }

    // Position Direktion und ROOT-ähnliche Knoten als Top-Zeilen
    const rootNodes = lanesMap.get('ROOT') || []
    let globalMinX = xMargin
    const lanesForWidth = laneOrder.filter(k => k !== 'ROOT' && k !== 'UNK')
    const laneCount = Math.max(1, lanesForWidth.length)
    const totalWidth = (laneCount - 1) * laneWidth
    const cardHalfWidth = 150 // angenommene halbe Kartenbreite

    // 1) Direktion zentriert ganz oben
    const directorIndex = rootNodes.findIndex(n => (String(n.data?.type).toLowerCase() === 'direktion') || String(n.data?.code).toUpperCase() === 'DIR')
    let placedIndices = new Set<number>()
    let directorRowHeight = 0
    if (directorIndex >= 0) {
      const centerX = xMargin + totalWidth / 2 - cardHalfWidth
      const x = Math.max(xMargin, centerX)
      rootNodes[directorIndex].position = { x, y: topYDirector }
      placedIndices.add(directorIndex)
      directorRowHeight = getNodeHeight(rootNodes[directorIndex].id)
    }
    // After measuring director, set dynamic Y for the second root row
    if (directorRowHeight) {
      topYRootRow = topYDirector + directorRowHeight + yGap
    }

    // 2) Übrige ROOT-Knoten in einer zweiten Top-Reihe gleichmäßig verteilen
    const others: Node[] = rootNodes.filter((_, idx) => !placedIndices.has(idx))
    let rootRowHeight = 0
    if (others.length === 1) {
      const x = Math.max(xMargin, xMargin + totalWidth / 2 - cardHalfWidth)
      others[0].position = { x, y: topYRootRow }
      rootRowHeight = getNodeHeight(others[0].id)
    } else if (others.length > 1) {
      const step = others.length > 1 ? (totalWidth / (others.length - 1)) : 0
      others.forEach((n, i) => {
        const xi = xMargin + i * step - cardHalfWidth
        n.position = { x: Math.max(xMargin, xi), y: topYRootRow }
        rootRowHeight = Math.max(rootRowHeight, getNodeHeight(n.id))
      })
    }

    // Optional: Leitungsstab-Kinder direkt unter dem Leitungsstab blockweise platzieren
    const lStabNode = rootNodes.find(n => (String((n.data||{}).code).toUpperCase() === 'LSTAB') || (/leitungsstab/i.test(String((n.data||{}).name))))
    let lStabBlockBottom = 0
    if (lStabNode) {
      const children = newNodes
        .filter(n => (n.data?.parentId === lStabNode.id) && (n.data?.type === 'sachgebiet' || n.data?.type === 'teildezernat'))
        .sort((a, b) => {
          const pa = String(a.data?.code || '').match(/LStab\s+(\d+)/i)
          const pb = String(b.data?.code || '').match(/LStab\s+(\d+)/i)
          const va = pa ? parseInt(pa[1], 10) : 0
          const vb = pb ? parseInt(pb[1], 10) : 0
          return va - vb
        })
      if (children.length) {
        let yC = (lStabNode.position?.y || topYRootRow) + getNodeHeight(lStabNode.id) + yGap
        const xC = (lStabNode.position?.x || xMargin) + 40
        children.forEach(c => {
          c.position = { x: xC, y: yC }
          yC += getNodeHeight(c.id) + yGap
        })
        lStabBlockBottom = yC
      }
    }

    // Spaltenstart abhängig von den tatsächlichen Höhen berechnen (inkl. Leitungsstab-Block)
    const baseTop = topYDirector + (directorRowHeight || 0) + (directorRowHeight ? yGap : 0)
    const secondRow = rootRowHeight ? (rootRowHeight + yGap) : 0
    const lStabExtra = lStabBlockBottom ? (lStabBlockBottom - (topYRootRow)) + 16 : 0
    yStart = baseTop + Math.max(secondRow, lStabExtra)

    // Arrange lanes
    let laneIndex = 0
    laneOrder.forEach(key => {
      if (key === 'ROOT' || key === 'UNK') return
      const laneNodes = lanesMap.get(key) || []
      const xBase = xMargin + laneIndex * laneWidth
      globalMinX = Math.min(globalMinX, xBase)

      // Find the Abteilung node for this lane (if any)
      const abteilung = laneNodes.find(n => n.data?.type === 'abteilung')
      let yCursor = yStart
      if (abteilung) {
        abteilung.position = { x: xBase, y: yCursor }
        yCursor += getNodeHeight(abteilung.id) + yGap
      }

      // Place Dezernate
      const dezernate = laneNodes.filter(n => n.data?.type === 'dezernat').sort(dezOrder)
      dezernate.forEach(dez => {
        dez.position = { x: xBase, y: yCursor }
        yCursor += getNodeHeight(dez.id) + yGap
        // children SG/TD under this dez vertically
        const children = laneNodes.filter(n => (n.data?.type === 'sachgebiet' || n.data?.type === 'teildezernat') && n.data?.parentId === dez.id).sort(childOrder)
        children.forEach((c) => {
          c.position = { x: xBase + 40, y: yCursor }
          yCursor += getNodeHeight(c.id) + yGap
        })
        // small gap after each dezernat block
        yCursor += 12
      })

      // Any remaining nodes (fallback)
      laneNodes.filter(n => !['abteilung','dezernat','sachgebiet','teildezernat'].includes(n.data?.type || '')).forEach(n => {
        n.position = { x: xBase, y: yCursor }
        yCursor += getNodeHeight(n.id) + yGap
      })

      laneIndex += 1
    })

    setNodes(newNodes)
  }

  // Reparenting: select source then target
  

  if (loading) {
    return (
      <div className="flex items-center justify-center h-screen">
        <div className="text-lg">Lade Organigramm...</div>
      </div>
    )
  }

  return (
    <div className="h-screen w-full">
      <ReactFlow
        nodes={nodes}
        edges={edges}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        onConnect={onConnect}
        onNodeClick={onNodeClick}
        onNodeDragStop={onNodeDragStop}
        nodeTypes={nodeTypes}
        fitView
        attributionPosition="bottom-left"
      >
        <Controls />
        <MiniMap 
          nodeColor={(node) => {
            const type = (node.data as any)?.type as OrganizationalUnitType | undefined
            const map: Record<string, string> = {
              direktion: '#1E3A8A',
              abteilung: '#334155',
              dezernat: '#1D4ED8',
              sachgebiet: '#64748B',
              teildezernat: '#64748B',
              stabsstelle: '#374151',
              sondereinheit: '#475569'
            }
            return (type && map[type]) || '#94a3b8'
          }}
        />
        <Background variant="dots" gap={12} size={1} />
        
        <Panel position="top-left" className="bg-white p-4 rounded-lg shadow-lg">
          <h2 className="text-xl font-bold mb-4">LKA NRW Organigramm</h2>
          <div className="space-y-2">
            <button
              onClick={() => setShowAddDialog(true)}
              className="w-full px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
            >
              + Einheit hinzufügen
            </button>
            <button
              onClick={() => setShowImportDialog(true)}
              className="w-full px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700 flex items-center justify-center gap-2"
            >
              <Upload size={16} />
              PDF importieren
            </button>
            <button
              onClick={handleAutoLayout}
              className="w-full px-4 py-2 bg-purple-600 text-white rounded hover:bg-purple-700"
            >
              Auto anordnen
            </button>
            
          </div>
        </Panel>

        <Panel position="top-right" className="bg-white p-4 rounded-lg shadow-lg max-w-sm">
          {selectedNode ? (
            <>
              <h3 className="font-bold mb-2">{selectedNode.data.name}</h3>
              {selectedNode.data.code && (
                <p className="text-sm text-gray-600">Code: {selectedNode.data.code}</p>
              )}
              <p className="text-sm text-gray-600">Typ: {selectedNode.data.type}</p>
              <p className="text-sm text-gray-600">Ebene: {selectedNode.data.level}</p>
              {issues.orphans.has(selectedNode.id) && (
                <p className="text-xs text-red-600 mt-1">Warnung: Parent fehlt (Waisen-Knoten)</p>
              )}
              {selectedNode.data.description && (
                <p className="text-sm mt-2">{selectedNode.data.description}</p>
              )}
            </>
          ) : (
            <p className="text-gray-500">Klicken Sie auf eine Einheit für Details</p>
          )}
        </Panel>
      </ReactFlow>

      {/* Import PDF Dialog */}
      {showImportDialog && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
          <div className="bg-white rounded-lg p-6 max-w-2xl w-full">
            <h2 className="text-xl font-bold mb-4">PDF Organigramm importieren</h2>
            
            {!preview ? (
              <div className="space-y-4">
                <div className="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center">
                  <Upload className="mx-auto h-12 w-12 text-gray-400 mb-4" />
                  <p className="text-sm text-gray-600 mb-4">
                    Laden Sie ein PDF hoch. Es wird zunächst nur eine Vorschau (Diff) berechnet.
                  </p>
                  <label className="flex items-center justify-center gap-2 text-sm mb-4">
                    <input type="checkbox" checked={clearExisting} onChange={(e)=>setClearExisting(e.target.checked)} />
                    Bestehende Einheiten löschen
                  </label>
                  
                  <input
                    ref={fileInputRef}
                    type="file"
                    accept=".pdf,application/pdf"
                    onChange={handleFileUpload}
                    className="hidden"
                  />
                  
                  <button
                    onClick={() => fileInputRef.current?.click()}
                    className="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700"
                    disabled={!!uploadProgress}
                  >
                    PDF auswählen
                  </button>
                </div>
                
                {uploadProgress && (
                  <div className="p-3 bg-blue-50 text-blue-700 rounded">
                    {uploadProgress}
                  </div>
                )}
              </div>
            ) : (
              <div className="space-y-4">
                <div className="grid grid-cols-3 gap-4">
                  <div className="p-3 border rounded">
                    <h3 className="font-semibold mb-2">Neu</h3>
                    <p className="text-sm text-gray-500 mb-2">{preview.counts?.create} Einheiten</p>
                    <div className="max-h-40 overflow-auto text-sm">
                      {preview.diff?.create?.slice(0,50).map((u: any)=> (
                        <div key={u.code}>{u.code} – {u.name}</div>
                      ))}
                    </div>
                  </div>
                  <div className="p-3 border rounded">
                    <h3 className="font-semibold mb-2">Änderungen</h3>
                    <p className="text-sm text-gray-500 mb-2">{preview.counts?.update} Einheiten</p>
                    <div className="max-h-40 overflow-auto text-sm">
                      {preview.diff?.update?.slice(0,50).map((d: any)=> (
                        <div key={d.incoming.code}>{d.incoming.code} – {d.existing.name} → {d.incoming.name}</div>
                      ))}
                    </div>
                  </div>
                  <div className="p-3 border rounded">
                    <h3 className="font-semibold mb-2">Waisen (Parent fehlt)</h3>
                    <p className="text-sm text-gray-500 mb-2">{preview.counts?.orphans} Einheiten</p>
                  <div className="max-h-40 overflow-auto text-sm space-y-2">
                      {preview.diff?.orphans?.map((u: any)=> (
                        <div key={u.code} className="flex items-center gap-2">
                          <div className="flex-1 truncate" title={`${u.code} – ${u.name}`}>{u.code} – {u.name}</div>
                          <input 
                            placeholder="Parent-Code (z.B. Dez 11 / Abt 1)"
                            className="border rounded px-2 py-1 text-xs w-48"
                            value={pendingOverrides[u.code]?.parentCode || ''}
                            onChange={(e)=> setPendingOverrides(prev => ({...prev, [u.code]: { ...(prev[u.code]||{}), parentCode: e.target.value }}))}
                          />
                          <button
                            onClick={() => openParentPicker(u.code)}
                            className="px-2 py-1 text-xs bg-slate-100 rounded border"
                            title="Parent auswählen"
                          >
                            …
                          </button>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
                <label className="flex items-center gap-2 text-sm">
                  <input type="checkbox" checked={rememberRules} onChange={(e)=>setRememberRules(e.target.checked)} />
                  Zuordnungen als Regeln speichern (für künftige Importe)
                </label>
                {uploadProgress && (
                  <div className="p-3 bg-blue-50 text-blue-700 rounded">{uploadProgress}</div>
                )}
              </div>
            )}

            <div className="flex justify-end gap-2 mt-6">
              <button
                onClick={() => {
                  setShowImportDialog(false)
                  setUploadProgress(null)
                  setPreview(null)
                  setPendingOverrides({})
                }}
                className="px-4 py-2 text-gray-600 hover:text-gray-800"
              >
                Schließen
              </button>
              {preview && (
                <button
                  onClick={applyImport}
                  className="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700"
                >
                  Import anwenden
                </button>
              )}
            </div>
          </div>
        </div>
      )}

      {/* Parent Picker Modal */}
      {parentPicker.open && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
          <div className="bg-white rounded-lg p-4 max-w-lg w-full">
            <h3 className="font-semibold mb-3">Parent auswählen für {parentPicker.target}</h3>
            <div className="max-h-80 overflow-auto border rounded">
              {(parentPicker.suggestions || []).map((s: any) => (
                <button
                  key={s.code}
                  onClick={() => {
                    if (parentPicker.target) {
                      setPendingOverrides(prev => ({ ...prev, [parentPicker.target!]: { ...(prev[parentPicker.target!]||{}), parentCode: s.code } }))
                    }
                    setParentPicker({ open: false, target: undefined, suggestions: [] })
                  }}
                  className="w-full text-left px-3 py-2 hover:bg-slate-100 border-b last:border-b-0"
                >
                  <span className="font-mono text-xs mr-2">{s.code}</span>
                  <span>{s.name}</span>
                </button>
              ))}
            </div>
            <div className="flex justify-end mt-3">
              <button onClick={() => setParentPicker({ open: false, target: undefined, suggestions: [] })} className="px-3 py-1 text-slate-600 hover:text-slate-800">Abbrechen</button>
            </div>
          </div>
        </div>
      )}

      {/* Add Unit Dialog */}
      {showAddDialog && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
          <div className="bg-white rounded-lg p-6 max-w-md w-full">
            <h2 className="text-xl font-bold mb-4">Neue Einheit hinzufügen</h2>
            
            <div className="space-y-4">
              <div>
                <label className="block text-sm font-medium mb-1">Name *</label>
                <input
                  type="text"
                  value={formData.name}
                  onChange={(e) => setFormData({ ...formData, name: e.target.value })}
                  className="w-full px-3 py-2 border rounded"
                  required
                />
              </div>

              {selectedNode && (
                <div className="text-xs text-gray-600">
                  Wird unterhalb von: <span className="font-semibold">{selectedNode.data?.name}</span> eingefügt
                </div>
              )}

              <div>
                <label className="block text-sm font-medium mb-1">Code *</label>
                <input
                  type="text"
                  value={formData.code}
                  onChange={(e) => setFormData({ ...formData, code: e.target.value })}
                  className="w-full px-3 py-2 border rounded"
                  placeholder="z.B. ZA 1"
                  required
                />
              </div>

              <div>
                <label className="block text-sm font-medium mb-1">Typ *</label>
                <select
                  value={formData.type}
                  onChange={(e) => setFormData({ ...formData, type: e.target.value as OrganizationalUnitType })}
                  className="w-full px-3 py-2 border rounded"
                >
                  <option value="direktion">Direktion</option>
                  <option value="abteilung">Abteilung</option>
                  <option value="dezernat">Dezernat</option>
                  <option value="sachgebiet">Sachgebiet</option>
                  <option value="teildezernat">Teildezernat</option>
                  <option value="stabsstelle">Stabsstelle</option>
                  <option value="sondereinheit">Sondereinheit</option>
                  <option value="fuehrungsstelle">Führungsstelle</option>
                </select>
              </div>

              <div>
                <label className="block text-sm font-medium mb-1">Ebene *</label>
                <input
                  type="number"
                  value={formData.level}
                  onChange={(e) => setFormData({ ...formData, level: parseInt(e.target.value) })}
                  className="w-full px-3 py-2 border rounded"
                  min="0"
                  max="10"
                />
              </div>

              <div>
                <label className="block text-sm font-medium mb-1">Beschreibung</label>
                <textarea
                  value={formData.description}
                  onChange={(e) => setFormData({ ...formData, description: e.target.value })}
                  className="w-full px-3 py-2 border rounded"
                  rows={3}
                />
              </div>
            </div>

            <div className="flex justify-end gap-2 mt-6">
              <button
                onClick={() => setShowAddDialog(false)}
                className="px-4 py-2 text-gray-600 hover:text-gray-800"
              >
                Abbrechen
              </button>
              <button
                onClick={handleAddUnit}
                className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
              >
                Hinzufügen
              </button>
            </div>
          </div>
        </div>
      )}

      
    </div>
  )
}
