'use client'

/**
 * BPMN Workflow Editor
 *
 * Admin interface for:
 * - Creating and editing BPMN 2.0 process diagrams
 * - Deploying processes to Camunda 7
 * - Managing deployed process definitions
 * - Viewing and completing pending tasks
 */

import { useState, useEffect, useRef, useCallback } from 'react'
import AdminLayout from '@/components/admin/AdminLayout'
import SystemInfoSection, { SYSTEM_INFO_CONFIGS } from '@/components/admin/SystemInfoSection'

// Types
interface ProcessDefinition {
  id: string
  key: string
  name: string
  version: number
  deploymentId: string
}

interface Task {
  id: string
  name: string
  processDefinitionId: string
  processInstanceId: string
  assignee?: string
  created: string
}

interface CamundaHealth {
  connected: boolean
  engines?: Array<{ name: string }>
  error?: string
}

// Default empty BPMN diagram
const EMPTY_BPMN = `<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
                  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
                  xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
                  xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
                  id="Definitions_1"
                  targetNamespace="http://bpmn.io/schema/bpmn">
  <bpmn:process id="Process_1" name="Neuer Prozess" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1" name="Start" />
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
      <bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
        <dc:Bounds x="180" y="160" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="186" y="203" width="24" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>`

export default function WorkflowPage() {
  // Refs
  const containerRef = useRef<HTMLDivElement>(null)
  const modelerRef = useRef<any>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)

  // State
  const [isLoading, setIsLoading] = useState(true)
  const [camundaHealth, setCamundaHealth] = useState<CamundaHealth>({ connected: false })
  const [processes, setProcesses] = useState<ProcessDefinition[]>([])
  const [tasks, setTasks] = useState<Task[]>([])
  const [showProcessPanel, setShowProcessPanel] = useState(false)
  const [showTaskPanel, setShowTaskPanel] = useState(false)
  const [elementCount, setElementCount] = useState(0)
  const [toast, setToast] = useState<{ message: string; type: 'success' | 'error' } | null>(null)

  // Show toast notification
  const showToast = useCallback((message: string, type: 'success' | 'error') => {
    setToast({ message, type })
    setTimeout(() => setToast(null), 3000)
  }, [])

  // Check Camunda health
  const checkCamundaHealth = useCallback(async () => {
    try {
      const response = await fetch('/api/bpmn/health')
      const data = await response.json()
      setCamundaHealth(data)
    } catch {
      setCamundaHealth({ connected: false, error: 'Connection failed' })
    }
  }, [])

  // Initialize BPMN modeler
  useEffect(() => {
    let mounted = true

    const initModeler = async () => {
      if (!containerRef.current) return

      try {
        // Dynamic import of bpmn-js (client-side only)
        const BpmnModeler = (await import('bpmn-js/lib/Modeler')).default

        if (!mounted) return

        const modeler = new BpmnModeler({
          container: containerRef.current,
          keyboard: {
            bindTo: document
          }
        })

        modelerRef.current = modeler

        // Load empty diagram
        await modeler.importXML(EMPTY_BPMN)

        // Fit viewport
        const canvas = modeler.get('canvas') as any
        canvas.zoom('fit-viewport')

        // Update element count on changes
        modeler.on('elements.changed', () => {
          if (modelerRef.current) {
            const elementRegistry = modelerRef.current.get('elementRegistry') as any
            setElementCount(elementRegistry.getAll().length)
          }
        })

        // Initial element count
        const elementRegistry = modeler.get('elementRegistry') as any
        setElementCount(elementRegistry.getAll().length)

        setIsLoading(false)
      } catch (err) {
        console.error('Error initializing BPMN modeler:', err)
        showToast('Fehler beim Initialisieren des Editors', 'error')
        setIsLoading(false)
      }
    }

    initModeler()
    checkCamundaHealth()

    return () => {
      mounted = false
      if (modelerRef.current) {
        modelerRef.current.destroy()
      }
    }
  }, [checkCamundaHealth, showToast])

  // Load deployed processes
  const loadProcesses = async () => {
    try {
      const response = await fetch('/api/bpmn/process-definition')
      if (response.ok) {
        const data = await response.json()
        setProcesses(data)
      }
    } catch (err) {
      console.error('Error loading processes:', err)
    }
  }

  // Load pending tasks
  const loadTasks = async () => {
    try {
      const response = await fetch('/api/bpmn/tasks/pending')
      if (response.ok) {
        const data = await response.json()
        setTasks(data)
      }
    } catch (err) {
      console.error('Error loading tasks:', err)
    }
  }

  // Create new diagram
  const handleNew = async () => {
    if (!modelerRef.current) return

    try {
      await modelerRef.current.importXML(EMPTY_BPMN)
      ;(modelerRef.current.get('canvas') as any).zoom('fit-viewport')
      showToast('Neues Diagramm erstellt', 'success')
    } catch (err) {
      showToast('Fehler beim Erstellen', 'error')
    }
  }

  // Open file
  const handleOpen = () => {
    fileInputRef.current?.click()
  }

  // Load file
  const handleFileLoad = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]
    if (!file || !modelerRef.current) return

    try {
      const xml = await file.text()
      await modelerRef.current.importXML(xml)
      ;(modelerRef.current.get('canvas') as any).zoom('fit-viewport')
      showToast(`Datei geladen: ${file.name}`, 'success')
    } catch (err) {
      showToast('Fehler beim Laden der Datei', 'error')
    }

    // Reset input
    event.target.value = ''
  }

  // Save as XML
  const handleSaveXML = async () => {
    if (!modelerRef.current) return

    try {
      const { xml } = await modelerRef.current.saveXML({ format: true })
      downloadFile(xml, 'process.bpmn', 'application/xml')
      showToast('XML exportiert', 'success')
    } catch (err) {
      showToast('Fehler beim Speichern', 'error')
    }
  }

  // Save as SVG
  const handleSaveSVG = async () => {
    if (!modelerRef.current) return

    try {
      const { svg } = await modelerRef.current.saveSVG()
      downloadFile(svg, 'process.svg', 'image/svg+xml')
      showToast('SVG exportiert', 'success')
    } catch (err) {
      showToast('Fehler beim Speichern', 'error')
    }
  }

  // Deploy to Camunda
  const handleDeploy = async () => {
    if (!modelerRef.current) return

    if (!camundaHealth.connected) {
      showToast('Camunda nicht verbunden', 'error')
      return
    }

    try {
      const { xml } = await modelerRef.current.saveXML({ format: true })

      const formData = new FormData()
      formData.append('deployment-name', `BreakPilot-Process-${Date.now()}`)
      formData.append('data', new Blob([xml], { type: 'application/octet-stream' }), 'process.bpmn')

      const response = await fetch('/api/bpmn/deployment/create', {
        method: 'POST',
        body: formData
      })

      if (response.ok) {
        const result = await response.json()
        showToast(`Deployment erfolgreich: ${result.name}`, 'success')
        loadProcesses()
      } else {
        throw new Error('Deployment failed')
      }
    } catch (err) {
      showToast('Deployment fehlgeschlagen', 'error')
    }
  }

  // Load process definition XML
  const handleLoadProcess = async (definitionId: string) => {
    try {
      const response = await fetch(`/api/bpmn/process-definition/${definitionId}/xml`)
      const data = await response.json()

      if (data.bpmn20Xml && modelerRef.current) {
        await modelerRef.current.importXML(data.bpmn20Xml)
        ;(modelerRef.current.get('canvas') as any).zoom('fit-viewport')
        setShowProcessPanel(false)
        showToast('Prozess geladen', 'success')
      }
    } catch (err) {
      showToast('Fehler beim Laden des Prozesses', 'error')
    }
  }

  // Complete task
  const handleCompleteTask = async (taskId: string) => {
    try {
      const response = await fetch(`/api/bpmn/task/${taskId}/complete`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({})
      })

      if (response.ok) {
        showToast('Task abgeschlossen', 'success')
        loadTasks()
      } else {
        throw new Error('Failed to complete task')
      }
    } catch (err) {
      showToast('Fehler beim Abschliessen', 'error')
    }
  }

  // Zoom controls
  const handleZoomIn = () => {
    if (!modelerRef.current) return
    const canvas = modelerRef.current.get('canvas') as any
    canvas.zoom(canvas.zoom() * 1.2)
  }

  const handleZoomOut = () => {
    if (!modelerRef.current) return
    const canvas = modelerRef.current.get('canvas') as any
    canvas.zoom(canvas.zoom() / 1.2)
  }

  const handleZoomFit = () => {
    if (!modelerRef.current) return
    ;(modelerRef.current.get('canvas') as any).zoom('fit-viewport')
  }

  // Download helper
  const downloadFile = (content: string, filename: string, contentType: string) => {
    const blob = new Blob([content], { type: contentType })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = filename
    a.click()
    URL.revokeObjectURL(url)
  }

  return (
    <AdminLayout title="BPMN Workflow Editor" description="Geschaeftsprozesse modellieren und automatisieren">
      {/* Hidden file input */}
      <input
        ref={fileInputRef}
        type="file"
        accept=".bpmn,.xml"
        onChange={handleFileLoad}
        className="hidden"
      />

      {/* Toolbar */}
      <div className="flex flex-wrap items-center gap-3 mb-4 p-3 bg-white rounded-xl border border-slate-200">
        {/* File operations */}
        <div className="flex items-center gap-2">
          <button
            onClick={handleNew}
            className="px-3 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 text-sm font-medium flex items-center gap-2"
          >
            <span>+</span> Neu
          </button>
          <button
            onClick={handleOpen}
            className="px-3 py-2 border border-slate-300 rounded-lg hover:bg-slate-50 text-sm font-medium"
          >
            Oeffnen
          </button>
        </div>

        <div className="w-px h-6 bg-slate-200" />

        {/* Export */}
        <div className="flex items-center gap-2">
          <button
            onClick={handleSaveXML}
            className="px-3 py-2 border border-slate-300 rounded-lg hover:bg-slate-50 text-sm font-medium"
          >
            XML
          </button>
          <button
            onClick={handleSaveSVG}
            className="px-3 py-2 border border-slate-300 rounded-lg hover:bg-slate-50 text-sm font-medium"
          >
            SVG
          </button>
        </div>

        <div className="w-px h-6 bg-slate-200" />

        {/* Camunda */}
        <div className="flex items-center gap-2">
          <button
            onClick={handleDeploy}
            disabled={!camundaHealth.connected}
            className="px-3 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed text-sm font-medium flex items-center gap-2"
          >
            Deployen
          </button>
          <button
            onClick={() => {
              loadProcesses()
              setShowProcessPanel(true)
            }}
            className="px-3 py-2 border border-slate-300 rounded-lg hover:bg-slate-50 text-sm font-medium"
          >
            Prozesse
          </button>
          <button
            onClick={() => {
              loadTasks()
              setShowTaskPanel(!showTaskPanel)
            }}
            className="px-3 py-2 border border-slate-300 rounded-lg hover:bg-slate-50 text-sm font-medium"
          >
            Tasks
          </button>
        </div>

        <div className="w-px h-6 bg-slate-200" />

        {/* Zoom */}
        <div className="flex items-center gap-2">
          <button
            onClick={handleZoomIn}
            className="px-3 py-2 border border-slate-300 rounded-lg hover:bg-slate-50 text-sm"
          >
            +
          </button>
          <button
            onClick={handleZoomOut}
            className="px-3 py-2 border border-slate-300 rounded-lg hover:bg-slate-50 text-sm"
          >
            -
          </button>
          <button
            onClick={handleZoomFit}
            className="px-3 py-2 border border-slate-300 rounded-lg hover:bg-slate-50 text-sm"
          >
            Fit
          </button>
        </div>
      </div>

      {/* Main Canvas */}
      <div className="relative bg-white rounded-xl border border-slate-200 overflow-hidden" style={{ height: 'calc(100vh - 340px)' }}>
        {isLoading && (
          <div className="absolute inset-0 flex items-center justify-center bg-white z-10">
            <div className="text-slate-500">Lade Editor...</div>
          </div>
        )}
        <div ref={containerRef} className="w-full h-full" />

        {/* Status Bar */}
        <div className="absolute bottom-0 left-0 right-0 flex justify-between items-center px-4 py-2 bg-slate-50 border-t border-slate-200 text-xs text-slate-500">
          <div className="flex items-center gap-2">
            <span
              className={`w-2 h-2 rounded-full ${camundaHealth.connected ? 'bg-green-500' : 'bg-red-500'}`}
            />
            <span>Camunda: {camundaHealth.connected ? 'Verbunden' : 'Nicht verbunden'}</span>
          </div>
          <div>Elemente: {elementCount}</div>
        </div>
      </div>

      {/* Task Panel */}
      {showTaskPanel && (
        <div className="mt-4 bg-white rounded-xl border border-slate-200 p-4">
          <div className="flex justify-between items-center mb-4">
            <h3 className="font-semibold text-slate-900">Offene Tasks</h3>
            <span className="px-2 py-1 bg-primary-100 text-primary-700 rounded-full text-xs font-medium">
              {tasks.length}
            </span>
          </div>
          {tasks.length === 0 ? (
            <div className="text-center py-6 text-slate-500">Keine offenen Tasks</div>
          ) : (
            <div className="space-y-2">
              {tasks.map((task) => (
                <div
                  key={task.id}
                  className="flex justify-between items-center p-3 bg-slate-50 rounded-lg"
                >
                  <div>
                    <div className="font-medium text-slate-900">{task.name}</div>
                    <div className="text-xs text-slate-500">{task.processDefinitionId}</div>
                  </div>
                  <button
                    onClick={() => handleCompleteTask(task.id)}
                    className="px-3 py-1.5 bg-primary-600 text-white rounded text-sm hover:bg-primary-700"
                  >
                    Erledigen
                  </button>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Process Panel (Slide-in) */}
      {showProcessPanel && (
        <div className="fixed inset-0 z-50 flex justify-end">
          <div
            className="absolute inset-0 bg-black/50"
            onClick={() => setShowProcessPanel(false)}
          />
          <div className="relative w-80 bg-white h-full shadow-xl overflow-y-auto">
            <div className="sticky top-0 bg-white border-b border-slate-200 p-4 flex justify-between items-center">
              <h3 className="font-semibold text-slate-900">Deployed Processes</h3>
              <button
                onClick={() => setShowProcessPanel(false)}
                className="text-slate-400 hover:text-slate-600"
              >
                X
              </button>
            </div>
            <div className="p-4">
              {processes.length === 0 ? (
                <div className="text-center py-8 text-slate-500">Keine Prozesse deployed</div>
              ) : (
                <div className="space-y-2">
                  {processes.map((process) => (
                    <div
                      key={process.id}
                      onClick={() => handleLoadProcess(process.id)}
                      className="p-3 border border-slate-200 rounded-lg hover:border-primary-300 cursor-pointer"
                    >
                      <div className="font-medium text-slate-900">{process.name || process.key}</div>
                      <div className="text-xs text-slate-500">
                        Version {process.version} | {process.key}
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          </div>
        </div>
      )}

      {/* Toast Notification */}
      {toast && (
        <div
          className={`fixed bottom-6 right-6 px-4 py-3 rounded-lg shadow-lg z-50 ${
            toast.type === 'success'
              ? 'bg-green-600 text-white'
              : 'bg-red-600 text-white'
          }`}
        >
          {toast.message}
        </div>
      )}

      {/* System Info Section */}
      <div className="mt-8 border-t border-slate-200 pt-8">
        <SystemInfoSection config={SYSTEM_INFO_CONFIGS.workflow || {
          title: 'BPMN Workflow Engine',
          description: 'Camunda 7 basierte Prozessautomatisierung',
          version: '7.21.0',
          architecture: {
            layers: [
              {
                name: 'Frontend',
                color: '#3b82f6',
                components: ['bpmn-js Editor', 'React Components']
              },
              {
                name: 'Backend',
                color: '#8b5cf6',
                components: ['FastAPI Proxy', 'REST API']
              },
              {
                name: 'Engine',
                color: '#10b981',
                components: ['Camunda 7', 'Process Executor']
              },
              {
                name: 'Datenbank',
                color: '#f59e0b',
                components: ['PostgreSQL', 'Camunda Schema']
              }
            ]
          },
          features: [
            { name: 'BPMN 2.0 Modellierung', status: 'active' as const, description: 'Visueller Editor mit bpmn-js' },
            { name: 'Process Deployment', status: 'active' as const, description: 'Deploy zu Camunda Engine' },
            { name: 'Task Management', status: 'active' as const, description: 'User Tasks bearbeiten' },
            { name: 'Process History', status: 'planned' as const, description: 'Historische Prozessdaten' }
          ],
          roadmap: [
            {
              title: 'Phase 1: Editor Integration',
              priority: 'high' as const,
              items: ['bpmn-js Editor', 'Camunda Deployment', 'Task Inbox']
            },
            {
              title: 'Phase 2: Consent Workflow',
              priority: 'high' as const,
              items: ['Document Workflow', 'DSB Approval', 'Auto-Publishing']
            },
            {
              title: 'Phase 3: Weitere Prozesse',
              priority: 'medium' as const,
              items: ['GDPR DSR Workflow', 'Exam Correction', 'Onboarding']
            }
          ],
          technicalDetails: [
            { key: 'Engine', value: 'Camunda 7.21.0' },
            { key: 'Editor', value: 'bpmn-js 17.11.1' },
            { key: 'Lizenz', value: 'Apache 2.0' },
            { key: 'Port', value: '8089' }
          ],
          privacyNotes: [
            'Prozessdaten werden lokal in PostgreSQL gespeichert',
            'Keine Daten werden an externe Dienste gesendet',
            'Apache 2.0 Lizenz - kommerziell nutzbar'
          ]
        }} />
      </div>
    </AdminLayout>
  )
}
