'use client'

/**
 * DataFlowDiagram - Visual representation of module dependencies
 *
 * Shows how backend services, modules, and frontend pages are connected.
 * Uses SVG for rendering connections.
 */

import { useState, useRef, useEffect } from 'react'
import {
  MODULE_REGISTRY,
  type BackendModule
} from '@/lib/module-registry'
import { DataFlowDiagramDetails, SERVICE_COLORS, STATUS_COLORS } from './DataFlowDiagramDetails'

interface NodePosition {
  x: number
  y: number
  width: number
  height: number
}

interface ServiceGroup {
  name: string
  port: number
  modules: BackendModule[]
}

export function DataFlowDiagram() {
  const [selectedModule, setSelectedModule] = useState<string | null>(null)
  const [hoveredModule, setHoveredModule] = useState<string | null>(null)
  const [showLegend, setShowLegend] = useState(true)
  const containerRef = useRef<HTMLDivElement>(null)

  // Group modules by backend service
  const serviceGroups: ServiceGroup[] = []
  const seenServices = new Set<string>()

  MODULE_REGISTRY.forEach(module => {
    if (!seenServices.has(module.backend.service)) {
      seenServices.add(module.backend.service)
      serviceGroups.push({
        name: module.backend.service,
        port: module.backend.port,
        modules: MODULE_REGISTRY.filter(m => m.backend.service === module.backend.service)
      })
    }
  })

  // Calculate positions
  const serviceWidth = 280
  const serviceSpacing = 40
  const moduleHeight = 60
  const moduleSpacing = 10
  const headerHeight = 50
  const padding = 20

  const totalWidth = serviceGroups.length * serviceWidth + (serviceGroups.length - 1) * serviceSpacing + padding * 2
  const maxModulesInService = Math.max(...serviceGroups.map(s => s.modules.length))
  const totalHeight = headerHeight + maxModulesInService * (moduleHeight + moduleSpacing) + padding * 2 + 100

  // Get connections between modules (dependencies)
  const connections: { from: string; to: string }[] = []
  MODULE_REGISTRY.forEach(module => {
    if (module.dependencies) {
      module.dependencies.forEach(dep => {
        connections.push({ from: module.id, to: dep })
      })
    }
  })

  // Get module position
  const getModulePosition = (moduleId: string): NodePosition | null => {
    let serviceIndex = 0
    for (const service of serviceGroups) {
      const moduleIndex = service.modules.findIndex(m => m.id === moduleId)
      if (moduleIndex !== -1) {
        return {
          x: padding + serviceIndex * (serviceWidth + serviceSpacing) + serviceWidth / 2,
          y: headerHeight + moduleIndex * (moduleHeight + moduleSpacing) + moduleHeight / 2 + 40,
          width: serviceWidth - 40,
          height: moduleHeight
        }
      }
      serviceIndex++
    }
    return null
  }

  // Check if module is related to selected/hovered module
  const isRelated = (moduleId: string): boolean => {
    const target = selectedModule || hoveredModule
    if (!target) return false

    // Direct match
    if (moduleId === target) return true

    // Check dependencies
    const targetModule = MODULE_REGISTRY.find(m => m.id === target)
    if (targetModule?.dependencies?.includes(moduleId)) return true

    // Check reverse dependencies
    const module = MODULE_REGISTRY.find(m => m.id === moduleId)
    if (module?.dependencies?.includes(target)) return true

    return false
  }

  return (
    <div className="space-y-4">
      {/* Controls */}
      <div className="flex items-center justify-between">
        <h3 className="text-lg font-semibold text-slate-900">Datenfluss-Diagramm</h3>
        <div className="flex items-center gap-4">
          <button
            onClick={() => setShowLegend(!showLegend)}
            className="text-sm text-slate-600 hover:text-slate-900"
          >
            {showLegend ? 'Legende ausblenden' : 'Legende anzeigen'}
          </button>
          {selectedModule && (
            <button
              onClick={() => setSelectedModule(null)}
              className="px-3 py-1 bg-purple-100 text-purple-700 rounded-full text-sm"
            >
              Auswahl aufheben
            </button>
          )}
        </div>
      </div>

      {/* Legend */}
      {showLegend && (
        <div className="bg-white rounded-xl shadow-sm border p-4 flex flex-wrap items-center gap-6">
          <span className="text-sm font-medium text-slate-700">Services:</span>
          {Object.entries(SERVICE_COLORS).map(([service, color]) => (
            <div key={service} className="flex items-center gap-2">
              <div className="w-3 h-3 rounded" style={{ backgroundColor: color }} />
              <span className="text-sm text-slate-600">{service}</span>
            </div>
          ))}
          <span className="text-sm font-medium text-slate-700 ml-4">Status:</span>
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-full bg-green-500" />
            <span className="text-sm text-slate-600">Verbunden</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-full bg-yellow-500" />
            <span className="text-sm text-slate-600">Teilweise</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-full bg-red-500" />
            <span className="text-sm text-slate-600">Nicht verbunden</span>
          </div>
        </div>
      )}

      {/* Diagram */}
      <div
        ref={containerRef}
        className="bg-white rounded-xl shadow-sm border overflow-x-auto"
      >
        <svg
          width={totalWidth}
          height={totalHeight}
          className="min-w-full"
        >
          <defs>
            {/* Arrow marker */}
            <marker
              id="arrowhead"
              markerWidth="10"
              markerHeight="7"
              refX="9"
              refY="3.5"
              orient="auto"
            >
              <polygon points="0 0, 10 3.5, 0 7" fill="#a78bfa" />
            </marker>
            <marker
              id="arrowhead-highlight"
              markerWidth="10"
              markerHeight="7"
              refX="9"
              refY="3.5"
              orient="auto"
            >
              <polygon points="0 0, 10 3.5, 0 7" fill="#8b5cf6" />
            </marker>
          </defs>

          {/* Background Grid */}
          <pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
            <path d="M 20 0 L 0 0 0 20" fill="none" stroke="#f1f5f9" strokeWidth="1"/>
          </pattern>
          <rect width="100%" height="100%" fill="url(#grid)" />

          {/* Service Groups */}
          {serviceGroups.map((service, serviceIdx) => {
            const x = padding + serviceIdx * (serviceWidth + serviceSpacing)
            const serviceColor = SERVICE_COLORS[service.name] || '#6b7280'

            return (
              <g key={service.name}>
                {/* Service Container */}
                <rect
                  x={x}
                  y={padding}
                  width={serviceWidth}
                  height={totalHeight - padding * 2}
                  fill={`${serviceColor}10`}
                  stroke={serviceColor}
                  strokeWidth="2"
                  rx="12"
                />

                {/* Service Header */}
                <rect
                  x={x}
                  y={padding}
                  width={serviceWidth}
                  height={headerHeight}
                  fill={serviceColor}
                  rx="12"
                />
                <rect
                  x={x}
                  y={padding + headerHeight - 12}
                  width={serviceWidth}
                  height={12}
                  fill={serviceColor}
                />
                <text
                  x={x + serviceWidth / 2}
                  y={padding + headerHeight / 2 + 5}
                  textAnchor="middle"
                  fill="white"
                  fontSize="14"
                  fontWeight="600"
                >
                  {service.name}
                </text>
                <text
                  x={x + serviceWidth / 2}
                  y={padding + headerHeight - 8}
                  textAnchor="middle"
                  fill="rgba(255,255,255,0.7)"
                  fontSize="11"
                >
                  Port {service.port}
                </text>

                {/* Modules */}
                {service.modules.map((module, moduleIdx) => {
                  const moduleX = x + 20
                  const moduleY = padding + headerHeight + 20 + moduleIdx * (moduleHeight + moduleSpacing)
                  const isSelected = selectedModule === module.id
                  const isHovered = hoveredModule === module.id
                  const related = isRelated(module.id)
                  const statusColor = STATUS_COLORS[module.frontend.status]

                  const opacity = (selectedModule || hoveredModule)
                    ? (related ? 1 : 0.3)
                    : 1

                  return (
                    <g
                      key={module.id}
                      onClick={() => setSelectedModule(isSelected ? null : module.id)}
                      onMouseEnter={() => setHoveredModule(module.id)}
                      onMouseLeave={() => setHoveredModule(null)}
                      style={{ cursor: 'pointer', opacity }}
                      className="transition-opacity duration-200"
                    >
                      {/* Module Box */}
                      <rect
                        x={moduleX}
                        y={moduleY}
                        width={serviceWidth - 40}
                        height={moduleHeight}
                        fill="white"
                        stroke={isSelected || isHovered ? serviceColor : '#e2e8f0'}
                        strokeWidth={isSelected || isHovered ? 2 : 1}
                        rx="8"
                        filter={isSelected ? 'drop-shadow(0 4px 6px rgba(0,0,0,0.1))' : undefined}
                      />

                      {/* Status Indicator */}
                      <circle
                        cx={moduleX + 16}
                        cy={moduleY + moduleHeight / 2}
                        r="5"
                        fill={statusColor}
                      />

                      {/* Module Name */}
                      <text
                        x={moduleX + 30}
                        y={moduleY + 24}
                        fill="#1e293b"
                        fontSize="12"
                        fontWeight="500"
                      >
                        {module.name.length > 25 ? module.name.slice(0, 25) + '...' : module.name}
                      </text>

                      {/* Module ID */}
                      <text
                        x={moduleX + 30}
                        y={moduleY + 42}
                        fill="#94a3b8"
                        fontSize="10"
                      >
                        {module.id}
                      </text>

                      {/* Priority Badge */}
                      <rect
                        x={moduleX + serviceWidth - 90}
                        y={moduleY + 20}
                        width={40}
                        height={18}
                        fill={
                          module.priority === 'critical' ? '#fef2f2' :
                          module.priority === 'high' ? '#fff7ed' :
                          module.priority === 'medium' ? '#fefce8' :
                          '#f1f5f9'
                        }
                        rx="4"
                      />
                      <text
                        x={moduleX + serviceWidth - 70}
                        y={moduleY + 33}
                        textAnchor="middle"
                        fill={
                          module.priority === 'critical' ? '#dc2626' :
                          module.priority === 'high' ? '#ea580c' :
                          module.priority === 'medium' ? '#ca8a04' :
                          '#64748b'
                        }
                        fontSize="9"
                        fontWeight="500"
                      >
                        {module.priority.toUpperCase()}
                      </text>

                      {/* Dependency indicator */}
                      {module.dependencies && module.dependencies.length > 0 && (
                        <g>
                          <circle
                            cx={moduleX + serviceWidth - 55}
                            cy={moduleY + moduleHeight - 12}
                            r="8"
                            fill="#f3e8ff"
                          />
                          <text
                            x={moduleX + serviceWidth - 55}
                            y={moduleY + moduleHeight - 8}
                            textAnchor="middle"
                            fill="#8b5cf6"
                            fontSize="9"
                            fontWeight="600"
                          >
                            {module.dependencies.length}
                          </text>
                        </g>
                      )}
                    </g>
                  )
                })}
              </g>
            )
          })}

          {/* Connections (Dependencies) */}
          {connections.map((conn, idx) => {
            const fromPos = getModulePosition(conn.from)
            const toPos = getModulePosition(conn.to)

            if (!fromPos || !toPos) return null

            const isHighlighted = (selectedModule || hoveredModule) &&
              (conn.from === (selectedModule || hoveredModule) || conn.to === (selectedModule || hoveredModule))

            const opacity = (selectedModule || hoveredModule)
              ? (isHighlighted ? 1 : 0.1)
              : 0.4

            // Calculate curved path
            const startX = fromPos.x
            const startY = fromPos.y
            const endX = toPos.x
            const endY = toPos.y

            const midX = (startX + endX) / 2
            const controlOffset = Math.abs(startX - endX) * 0.3

            const path = startX < endX
              ? `M ${startX + fromPos.width / 2} ${startY}
                 C ${startX + fromPos.width / 2 + controlOffset} ${startY},
                   ${endX - toPos.width / 2 - controlOffset} ${endY},
                   ${endX - toPos.width / 2} ${endY}`
              : `M ${startX - fromPos.width / 2} ${startY}
                 C ${startX - fromPos.width / 2 - controlOffset} ${startY},
                   ${endX + toPos.width / 2 + controlOffset} ${endY},
                   ${endX + toPos.width / 2} ${endY}`

            return (
              <path
                key={idx}
                d={path}
                fill="none"
                stroke={isHighlighted ? '#8b5cf6' : '#a78bfa'}
                strokeWidth={isHighlighted ? 2 : 1.5}
                strokeDasharray={isHighlighted ? undefined : '4 2'}
                markerEnd={isHighlighted ? 'url(#arrowhead-highlight)' : 'url(#arrowhead)'}
                opacity={opacity}
                className="transition-opacity duration-200"
              />
            )
          })}

          {/* Frontend Layer (Bottom) */}
          <g>
            <rect
              x={padding}
              y={totalHeight - 80}
              width={totalWidth - padding * 2}
              height={60}
              fill="#f8fafc"
              stroke="#e2e8f0"
              strokeWidth="1"
              rx="8"
            />
            <text
              x={totalWidth / 2}
              y={totalHeight - 55}
              textAnchor="middle"
              fill="#64748b"
              fontSize="12"
              fontWeight="500"
            >
              Admin v2 Frontend (Next.js - Port 3002)
            </text>
            <text
              x={totalWidth / 2}
              y={totalHeight - 35}
              textAnchor="middle"
              fill="#94a3b8"
              fontSize="11"
            >
              /compliance | /ai | /infrastructure | /education | /communication | /development
            </text>
          </g>
        </svg>
      </div>

      {/* Selected Module Details */}
      {selectedModule && (
        <DataFlowDiagramDetails
          selectedModule={selectedModule}
          onSelectModule={setSelectedModule}
        />
      )}
    </div>
  )
}
