'use client'

import { useMemo } from 'react'
import { type Node, type Edge, MarkerType } from 'reactflow'
import {
  ARCH_SERVICES,
  ARCH_EDGES,
  LAYERS,
  type ArchService,
} from '../architecture-data'
import {
  NODE_WIDTH,
  LANE_Y_START,
  getServicePosition,
  type LayerFilter,
} from '../_layout'

export function useArchGraph({
  layerFilter,
  showDb,
  showRag,
  showApis,
  selectedService,
}: {
  layerFilter: LayerFilter
  showDb: boolean
  showRag: boolean
  showApis: boolean
  selectedService: ArchService | null
}) {
  return useMemo(() => {
    const nodes: Node[] = []
    const edges: Edge[] = []

    const visibleServices =
      layerFilter === 'alle'
        ? ARCH_SERVICES
        : ARCH_SERVICES.filter(s => s.layer === layerFilter)

    const visibleIds = new Set(visibleServices.map(s => s.id))

    // ── Service Nodes ──────────────────────────────────────────────────────
    visibleServices.forEach(service => {
      const layer = LAYERS[service.layer]
      const pos = getServicePosition(service)
      const isSelected = selectedService?.id === service.id

      nodes.push({
        id: service.id,
        type: 'default',
        position: pos,
        data: {
          label: (
            <div className="text-center px-1">
              <div className="font-medium text-xs leading-tight">
                {service.nameShort}
              </div>
              <div className="text-[10px] opacity-70 mt-0.5">
                {service.tech}
              </div>
              {service.port && (
                <div className="text-[9px] opacity-50 mt-0.5">
                  :{service.port}
                </div>
              )}
            </div>
          ),
        },
        style: {
          background: isSelected ? layer.colorBorder : layer.colorBg,
          color: isSelected ? 'white' : layer.colorText,
          border: `2px solid ${layer.colorBorder}`,
          borderRadius: '10px',
          padding: '8px 4px',
          minWidth: `${NODE_WIDTH}px`,
          maxWidth: `${NODE_WIDTH}px`,
          cursor: 'pointer',
          boxShadow: isSelected
            ? `0 0 16px ${layer.colorBorder}`
            : '0 1px 3px rgba(0,0,0,0.08)',
        },
      })
    })

    // ── Connection Edges ───────────────────────────────────────────────────
    ARCH_EDGES.forEach(archEdge => {
      if (visibleIds.has(archEdge.source) && visibleIds.has(archEdge.target)) {
        const isHighlighted =
          selectedService?.id === archEdge.source ||
          selectedService?.id === archEdge.target

        edges.push({
          id: `e-${archEdge.source}-${archEdge.target}`,
          source: archEdge.source,
          target: archEdge.target,
          type: 'smoothstep',
          animated: isHighlighted,
          label: archEdge.label,
          labelStyle: { fontSize: 9, fill: isHighlighted ? '#7c3aed' : '#94a3b8' },
          style: {
            stroke: isHighlighted ? '#7c3aed' : '#94a3b8',
            strokeWidth: isHighlighted ? 2.5 : 1.5,
          },
          markerEnd: {
            type: MarkerType.ArrowClosed,
            color: isHighlighted ? '#7c3aed' : '#94a3b8',
            width: 14,
            height: 14,
          },
        })
      }
    })

    // ── DB Table Nodes ─────────────────────────────────────────────────────
    if (showDb) {
      const dbTablesInUse = new Set<string>()
      visibleServices.forEach(s => s.dbTables.forEach(t => dbTablesInUse.add(t)))

      let dbIdx = 0
      dbTablesInUse.forEach(table => {
        const nodeId = `db-${table}`
        nodes.push({
          id: nodeId,
          type: 'default',
          position: { x: -250, y: LANE_Y_START + dbIdx * 60 },
          data: {
            label: (
              <div className="text-center">
                <div className="font-medium text-[10px] leading-tight">{table}</div>
              </div>
            ),
          },
          style: {
            background: '#f1f5f9',
            color: '#475569',
            border: '1px solid #94a3b8',
            borderRadius: '6px',
            padding: '4px 6px',
            fontSize: '10px',
            minWidth: '140px',
          },
        })

        visibleServices
          .filter(s => s.dbTables.includes(table))
          .forEach(svc => {
            edges.push({
              id: `e-db-${table}-${svc.id}`,
              source: nodeId,
              target: svc.id,
              type: 'straight',
              style: { stroke: '#94a3b8', strokeWidth: 1, strokeDasharray: '6 3' },
            })
          })

        dbIdx++
      })
    }

    // ── RAG Collection Nodes ───────────────────────────────────────────────
    if (showRag) {
      const ragInUse = new Set<string>()
      visibleServices.forEach(s => s.ragCollections.forEach(r => ragInUse.add(r)))

      let ragIdx = 0
      ragInUse.forEach(collection => {
        const nodeId = `rag-${collection}`
        const rightX = 1200

        nodes.push({
          id: nodeId,
          type: 'default',
          position: { x: rightX, y: LANE_Y_START + ragIdx * 60 },
          data: {
            label: (
              <div className="text-center">
                <div className="font-medium text-[10px] leading-tight">
                  {collection.replace('bp_', '')}
                </div>
              </div>
            ),
          },
          style: {
            background: '#dcfce7',
            color: '#166534',
            border: '1px solid #22c55e',
            borderRadius: '6px',
            padding: '4px 6px',
            fontSize: '10px',
            minWidth: '130px',
          },
        })

        visibleServices
          .filter(s => s.ragCollections.includes(collection))
          .forEach(svc => {
            edges.push({
              id: `e-rag-${collection}-${svc.id}`,
              source: nodeId,
              target: svc.id,
              type: 'straight',
              style: { stroke: '#22c55e', strokeWidth: 1, strokeDasharray: '6 3' },
            })
          })

        ragIdx++
      })
    }

    // ── API Endpoint Nodes ─────────────────────────────────────────────────
    if (showApis) {
      visibleServices.forEach(svc => {
        if (svc.apiEndpoints.length === 0) return
        const svcPos = getServicePosition(svc)

        svc.apiEndpoints.forEach((ep, idx) => {
          const nodeId = `api-${svc.id}-${idx}`
          nodes.push({
            id: nodeId,
            type: 'default',
            position: { x: svcPos.x + NODE_WIDTH + 30, y: svcPos.y + idx * 32 },
            data: {
              label: (
                <div className="text-[9px] font-mono leading-tight truncate">{ep}</div>
              ),
            },
            style: {
              background: '#faf5ff',
              color: '#7c3aed',
              border: '1px solid #c4b5fd',
              borderRadius: '4px',
              padding: '2px 6px',
              fontSize: '9px',
              minWidth: '160px',
            },
          })

          edges.push({
            id: `e-api-${svc.id}-${idx}`,
            source: svc.id,
            target: nodeId,
            type: 'straight',
            style: { stroke: '#c4b5fd', strokeWidth: 1 },
          })
        })
      })
    }

    return { nodes, edges }
  }, [layerFilter, showDb, showRag, showApis, selectedService])
}
