import { useEffect, useRef, useCallback } from 'react'
import BpmnViewer from 'bpmn-js/lib/Viewer'

export type BpmnElementCategory = 'activity' | 'gateway' | 'other'

const ACTIVITY_TYPES = new Set([
  'bpmn:Task', 'bpmn:UserTask', 'bpmn:ServiceTask', 'bpmn:ScriptTask',
  'bpmn:ManualTask', 'bpmn:BusinessRuleTask', 'bpmn:SubProcess',
])

const GATEWAY_TYPES = new Set([
  'bpmn:ExclusiveGateway', 'bpmn:ParallelGateway',
  'bpmn:InclusiveGateway', 'bpmn:EventBasedGateway',
])

function classifyElement(type: string): BpmnElementCategory {
  if (ACTIVITY_TYPES.has(type)) return 'activity'
  if (GATEWAY_TYPES.has(type)) return 'gateway'
  return 'other'
}

// SVG inline del ícono Bot de Lucide (12×12 px, color ámbar #f59e0b).
// Copiado de lucide.dev/icons/bot — robot con antena, cuerpo rectangular y ojos.
const BOT_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M12 8V4H8"/>
  <rect width="16" height="12" x="4" y="8" rx="2"/>
  <path d="M2 14h2"/>
  <path d="M20 14h2"/>
  <path d="M15 13v2"/>
  <path d="M9 13v2"/>
</svg>`

// HTML del badge de automatización.
// Fondo #fffbeb (amber-50): identidad cromática con el ícono Bot ámbar,
// contrasta con el fondo blanco de los nodos BPMN.
function makeBadgeHtml(): string {
  return `<div title="Actividad marcada como automatizable" style="
    width:20px;height:20px;
    border-radius:50%;
    background:#fffbeb;
    border:1px solid #e2e8f0;
    box-shadow:0 1px 3px rgba(0,0,0,0.12);
    display:flex;align-items:center;justify-content:center;
    cursor:default;
    pointer-events:none;
  ">${BOT_SVG}</div>`
}

// Identificador del tipo de overlay para poder remover solo los nuestros.
const OVERLAY_TYPE = 'automation-indicator'

interface BpmnCanvasProps {
  xml: string
  onElementClick?: (elementId: string, elementName: string, category: BpmnElementCategory) => void
  selectedElementId?: string | null
  automatableElementIds?: string[]  // IDs de actividades marcadas como automatizables
  className?: string
}

export function BpmnCanvas({
  xml,
  onElementClick,
  selectedElementId,
  automatableElementIds = [],
  className,
}: BpmnCanvasProps) {
  const containerRef = useRef<HTMLDivElement>(null)
  const viewerRef = useRef<InstanceType<typeof BpmnViewer> | null>(null)
  const isImportedRef = useRef(false)

  // ─── Inicializar viewer ────────────────────────────────────────────────────
  useEffect(() => {
    if (!containerRef.current) return
    const viewer = new BpmnViewer({ container: containerRef.current })
    viewerRef.current = viewer
    return () => {
      isImportedRef.current = false
      viewer.destroy()
      viewerRef.current = null
    }
  }, [])

  // ─── Sincronizar overlays de automatización ───────────────────────────────
  const syncAutomationOverlays = useCallback(() => {
    const viewer = viewerRef.current
    if (!viewer || !isImportedRef.current) return

    const overlays = viewer.get('overlays') as any
    const reg = viewer.get('elementRegistry') as any

    // Remover overlays anteriores del tipo propio antes de re-agregar
    overlays.remove({ type: OVERLAY_TYPE })

    for (const elementId of automatableElementIds) {
      try {
        // Leer el ancho real del elemento para posicionar el badge en la
        // esquina superior derecha con overlap: left = width - 12 pone el
        // borde derecho del badge 8px fuera del borde derecho del nodo.
        // (right: -8 en la API tiene semántica distinta: left = -right + width
        //  con -8 daría left = 8 + width, enteramente fuera del nodo.)
        const el = reg?.get(elementId)
        const width = el?.width ?? 100
        overlays.add(elementId, OVERLAY_TYPE, {
          position: { top: -8, left: width - 12 },
          html: makeBadgeHtml(),
        })
      } catch {
        // El elemento puede no existir en el diagrama actual — ignorar
      }
    }
  }, [automatableElementIds])

  // ─── Importar XML ──────────────────────────────────────────────────────────
  useEffect(() => {
    const viewer = viewerRef.current
    if (!viewer || !xml) return
    isImportedRef.current = false
    viewer.importXML(xml).then(({ warnings }) => {
      if (warnings.length) console.warn('bpmn-js warnings:', warnings)
      const canvas = viewer.get('canvas') as any
      canvas.zoom('fit-viewport', 'auto')
      isImportedRef.current = true
      syncAutomationOverlays()
    }).catch((err: Error) => console.error('Error cargando BPMN:', err))
  }, [xml, syncAutomationOverlays])

  // ─── Re-sincronizar overlays cuando cambia la lista de automatizables ─────
  useEffect(() => {
    syncAutomationOverlays()
  }, [syncAutomationOverlays])

  // ─── Click handler ─────────────────────────────────────────────────────────
  useEffect(() => {
    const viewer = viewerRef.current
    if (!viewer || !onElementClick) return
    const eventBus = viewer.get('eventBus') as any

    const handler = (event: any) => {
      const el = event.element
      if (!el) return
      const category = classifyElement(el.type)
      if (category === 'other') return
      onElementClick(el.id, el.businessObject?.name ?? el.id, category)
    }

    eventBus.on('element.click', handler)
    return () => eventBus.off('element.click', handler)
  }, [onElementClick])

  // ─── Highlight del elemento seleccionado ──────────────────────────────────
  useEffect(() => {
    const viewer = viewerRef.current
    if (!viewer) return
    const canvas = viewer.get('canvas') as any
    const reg = viewer.get('elementRegistry') as any
    reg.forEach((el: any) => canvas.removeMarker(el.id, 'bpmn-selected'))
    if (selectedElementId) {
      try { canvas.addMarker(selectedElementId, 'bpmn-selected') } catch { /* ignorar */ }
    }
  }, [selectedElementId])

  return <div ref={containerRef} className={className} style={{ width: '100%', height: '100%' }} />
}
