import { useState, useCallback, useEffect } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { useNodesState, useEdgesState, addEdge } from 'reactflow'
import { api } from '../utils/api'
import { validateWorkflowGraph } from '../utils/workflowValidation'
import { serializeToWorkflowGraph, deserializeFromWorkflowGraph } from '../utils/workflowSerializer'
import { WorkflowCanvas } from '../components/workflow/WorkflowCanvas'
import { StartNode } from '../components/workflow/nodes/StartNode'
import { EndNode } from '../components/workflow/nodes/EndNode'
import { AnalysisNode } from '../components/workflow/nodes/AnalysisNode'
import { LogicNode } from '../components/workflow/nodes/LogicNode'
import { JoinNode } from '../components/workflow/nodes/JoinNode'
import { QuestionAugmentationPanel } from '../components/workflow/panels/QuestionAugmentationPanel'
import { LogicExpressionEditor } from '../components/workflow/panels/LogicExpressionEditor'
import { FallbackConfig } from '../components/workflow/panels/FallbackConfig'
import { JoinConfig } from '../components/workflow/panels/JoinConfig'
import '../styles/workflowEditor.css'

// Node-Type Mapping
const nodeTypes = {
  start: StartNode,
  end: EndNode,
  analysis: AnalysisNode,
  logic: LogicNode,
  join: JoinNode
}

let nodeIdCounter = 1

export default function WorkflowEditorPage() {
  const navigate = useNavigate()
  const { id } = useParams() // prompt_id wenn vorhanden

  // State
  const [nodes, setNodes, onNodesChange] = useNodesState([])
  const [edges, setEdges, onEdgesChange] = useEdgesState([])
  const [selectedNodeId, setSelectedNodeId] = useState(null)
  const selectedNode = selectedNodeId ? nodes.find(n => n.id === selectedNodeId) : null
  const [currentPrompt, setCurrentPrompt] = useState(null)
  const [workflowName, setWorkflowName] = useState('Neuer Workflow')
  const [workflowDescription, setWorkflowDescription] = useState('')
  const [validationErrors, setValidationErrors] = useState([])
  const [validationWarnings, setValidationWarnings] = useState([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState(null)
  const [availablePrompts, setAvailablePrompts] = useState([])

  // Load available basis prompts for Analysis nodes
  useEffect(() => {
    async function loadPrompts() {
      try {
        const prompts = await api.listAdminPrompts()
        // Filter nur type='base' Prompts
        const basisPrompts = prompts.filter(p => p.type === 'base')
        setAvailablePrompts(basisPrompts)
      } catch (e) {
        console.error('Failed to load prompts:', e)
      }
    }
    loadPrompts()
  }, [])

  // Load workflow wenn ID vorhanden
  useEffect(() => {
    if (id && id !== 'new') {
      console.log('🔍 useEffect: Loading workflow with ID:', id)
      loadWorkflow(id)  // UUID as string, no parseInt!
    }
  }, [id])

  // Auto-Validation
  useEffect(() => {
    const { errors, warnings } = validateWorkflowGraph(nodes, edges)
    setValidationErrors(errors)
    setValidationWarnings(warnings)
  }, [nodes, edges])

  // ── Handlers ──────────────────────────────────────────────────────────────

  const onConnect = useCallback(
    (params) => setEdges((eds) => addEdge(params, eds)),
    [setEdges]
  )

  const onNodeClick = useCallback((event, node) => {
    setSelectedNodeId(node.id)
  }, [])

  const handleAddNode = (nodeType) => {
    const newNode = {
      id: `node_${nodeIdCounter++}`,
      type: nodeType,
      position: { x: 250, y: 100 + nodes.length * 100 },
      data: {
        label: `${nodeType.charAt(0).toUpperCase() + nodeType.slice(1)} ${nodeIdCounter - 1}`
      }
    }

    setNodes((nds) => [...nds, newNode])
  }

  const handleNodeUpdate = (nodeId, updates) => {
    console.log('🔧 handleNodeUpdate:', { nodeId, updates })
    setNodes((nds) => {
      const updated = nds.map((n) => (n.id === nodeId ? { ...n, data: { ...n.data, ...updates } } : n))
      console.log('📝 Nodes after update:', updated.find(n => n.id === nodeId))
      return updated
    })
  }

  const handleDeleteNode = () => {
    if (!selectedNode) return

    setNodes((nds) => nds.filter((n) => n.id !== selectedNode.id))
    setEdges((eds) => eds.filter((e) => e.source !== selectedNode.id && e.target !== selectedNode.id))
    setSelectedNodeId(null)
  }

  const handleSave = async () => {
    console.log('💾 handleSave called')
    try {
      setLoading(true)
      setError(null)

      // Validierung
      const { errors, isValid } = validateWorkflowGraph(nodes, edges)
      if (!isValid) {
        setError(`Validierung fehlgeschlagen: ${errors.length} Fehler gefunden`)
        return
      }

      // Serialisieren
      const graph_data = serializeToWorkflowGraph(nodes, edges, {
        created_at: currentPrompt?.created_at,
        version: '1.0'
      })
      console.log('📊 Serialized graph_data:', graph_data)

      if (currentPrompt) {
        // Update existing
        console.log('📝 Updating existing workflow:', currentPrompt.id)
        await api.updateUnifiedPrompt(currentPrompt.id, {
          type: 'workflow',
          name: workflowName,
          description: workflowDescription,
          graph_data
        })
        alert('Workflow gespeichert!')
      } else {
        // Create new
        console.log('✨ Creating new workflow')
        const result = await api.createUnifiedPrompt({
          type: 'workflow',
          name: workflowName,
          description: workflowDescription,
          graph_data
        })
        console.log('✅ Workflow created:', result)
        setCurrentPrompt({ id: result.id, name: workflowName })
        alert('Workflow erstellt!')
        console.log('🚀 Navigating to:', `/workflow-editor/${result.id}`)
        navigate(`/workflow-editor/${result.id}`)
      }
    } catch (e) {
      console.error('❌ handleSave error:', e)
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }

  const loadWorkflow = async (promptId) => {
    console.log('📦 loadWorkflow called with:', promptId)
    try {
      setLoading(true)
      setError(null)

      const prompt = await api.getPrompt(promptId)
      console.log('✅ Prompt loaded:', prompt)
      console.log('📊 graph_data:', prompt.graph_data)

      if (prompt.type !== 'workflow') {
        throw new Error('Nicht ein Workflow')
      }

      // Deserialisieren
      const { nodes: loadedNodes, edges: loadedEdges } = deserializeFromWorkflowGraph(prompt.graph_data)
      console.log('🎯 Deserialized:', { nodes: loadedNodes, edges: loadedEdges })

      setNodes(loadedNodes)
      setEdges(loadedEdges)
      setCurrentPrompt(prompt)
      setWorkflowName(prompt.name)
      setWorkflowDescription(prompt.description || '')

      // nodeIdCounter aktualisieren
      const maxId = Math.max(
        ...loadedNodes.map((n) => parseInt(n.id.replace('node_', '')) || 0),
        0
      )
      nodeIdCounter = maxId + 1
      console.log('✅ Workflow loaded successfully, nodes:', loadedNodes.length, 'edges:', loadedEdges.length)
    } catch (e) {
      console.error('❌ loadWorkflow error:', e)
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }

  const handleValidate = () => {
    const { errors, warnings } = validateWorkflowGraph(nodes, edges)
    setValidationErrors(errors)
    setValidationWarnings(warnings)

    if (errors.length === 0) {
      alert(`✅ Workflow ist valide!\n\n${warnings.length} Warnungen`)
    } else {
      alert(`❌ Validierung fehlgeschlagen!\n\n${errors.length} Fehler, ${warnings.length} Warnungen`)
    }
  }

  const handleNew = () => {
    if (confirm('Neuen Workflow erstellen? Ungespeicherte Änderungen gehen verloren.')) {
      setNodes([])
      setEdges([])
      setCurrentPrompt(null)
      setWorkflowName('Neuer Workflow')
      setWorkflowDescription('')
      setSelectedNodeId(null)
      navigate('/workflow-editor/new')
    }
  }

  const handleDelete = async () => {
    if (!currentPrompt) return

    if (!confirm(`Workflow "${workflowName}" wirklich löschen?`)) return

    try {
      setLoading(true)
      await api.deletePrompt(currentPrompt.id)
      alert('Workflow gelöscht')
      navigate('/admin/prompts')
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }

  // ── Render ────────────────────────────────────────────────────────────────

  return (
    <div className="workflow-editor">
      {/* Toolbar */}
      <div className="workflow-toolbar">
        <button className="btn-secondary" onClick={() => navigate('/admin/prompts')}>
          ← Zurück
        </button>

        <input
          type="text"
          value={workflowName}
          onChange={(e) => setWorkflowName(e.target.value)}
          placeholder="Workflow-Name"
          style={{ flex: 1, padding: '8px', borderRadius: '4px', border: '1px solid var(--border)' }}
        />

        <button className="btn-secondary" onClick={handleNew}>
          Neu
        </button>
        <button className="btn-secondary" onClick={handleValidate}>
          Validieren {validationErrors.length > 0 ? `(${validationErrors.length} ⚠️)` : ''}
        </button>
        <button
          className="btn-primary"
          onClick={handleSave}
          disabled={loading}
          title={validationErrors.length > 0
            ? `Speichern blockiert: ${validationErrors.length} Validierungsfehler`
            : 'Workflow in Datenbank speichern'}
        >
          {loading ? 'Speichern...' : validationErrors.length > 0 ? '🔒 Speichern' : '💾 Speichern'}
        </button>
        {currentPrompt && (
          <button className="btn-secondary" onClick={handleDelete} disabled={loading}>
            Löschen
          </button>
        )}
      </div>

      {error && (
        <div style={{ padding: '12px', background: 'var(--danger)', color: 'white', borderRadius: '4px', marginBottom: '8px' }}>
          ❌ {error}
          {validationErrors.length > 0 && (
            <div style={{ marginTop: 8, fontSize: 12 }}>
              Tipp: Behebe die Validierungsfehler unten, um speichern zu können.
            </div>
          )}
        </div>
      )}

      {/* Main Content */}
      <div className="workflow-content">
        {/* Sidebar */}
        <div className="workflow-sidebar" style={{ display: selectedNode ? 'none' : 'block' }}>
          <div className="sidebar-section">
            <h3>Workflow-Knoten</h3>
            <div className="node-palette">
              <button className="node-palette-button" onClick={() => handleAddNode('start')}>
                <span className="icon">🚀</span> Start
              </button>
              <button className="node-palette-button" onClick={() => handleAddNode('analysis')}>
                <span className="icon">🤖</span> Analyse
              </button>
              <button className="node-palette-button" onClick={() => handleAddNode('logic')}>
                <span className="icon">⚡</span> Logik
              </button>
              <button className="node-palette-button" onClick={() => handleAddNode('join')}>
                <span className="icon">🔀</span> Join
              </button>
              <button className="node-palette-button" onClick={() => handleAddNode('end')}>
                <span className="icon">🏁</span> Ende
              </button>
            </div>
          </div>

          {selectedNode && (
            <div className="sidebar-section">
              <h3>Aktionen</h3>
              <button className="btn-secondary btn-full" onClick={handleDeleteNode}>
                🗑️ Node löschen
              </button>
            </div>
          )}

          <div className="sidebar-section">
            <h3>Info</h3>
            <div style={{ fontSize: '12px', color: 'var(--text3)' }}>
              <div>Nodes: {nodes.length}</div>
              <div>Edges: {edges.length}</div>
              <div>Errors: {validationErrors.length}</div>
              <div>Warnings: {validationWarnings.length}</div>
            </div>
          </div>
        </div>

        {/* Canvas */}
        <div className="workflow-canvas-container">
          <WorkflowCanvas
            nodes={nodes}
            edges={edges}
            nodeTypes={nodeTypes}
            onNodesChange={onNodesChange}
            onEdgesChange={onEdgesChange}
            onConnect={onConnect}
            onNodeClick={onNodeClick}
          />
        </div>

        {/* Config Panel */}
        {selectedNode && (
          <div className="workflow-config-panel">
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
              <h2 style={{ margin: 0 }}>Node-Konfiguration</h2>
              <button
                onClick={() => setSelectedNodeId(null)}
                style={{
                  background: 'none',
                  border: 'none',
                  fontSize: 24,
                  cursor: 'pointer',
                  color: 'var(--text3)',
                  padding: 4,
                  lineHeight: 1
                }}
                title="Schließen"
              >
                ×
              </button>
            </div>

            {/* Basis-Konfiguration */}
            <div className="config-section">
              <label>Node-Name</label>
              <input
                type="text"
                value={selectedNode.data.label || ''}
                onChange={(e) => handleNodeUpdate(selectedNode.id, { label: e.target.value })}
                placeholder="z.B. Gewichtsanalyse"
                style={{
                  width: '100%',
                  padding: '8px',
                  borderRadius: '4px',
                  border: '1px solid var(--border)',
                  background: 'var(--surface)',
                  color: 'var(--text1)',
                  fontSize: '14px'
                }}
              />
              <div style={{ marginTop: 4, fontSize: 11, color: 'var(--text3)' }}>
                Änderungen werden automatisch übernommen
              </div>
            </div>

            {/* Type-spezifische Konfiguration */}
            {selectedNode.type === 'analysis' && (
              <>
                <div className="config-section">
                  <label>KI-Prompt auswählen</label>
                  <select
                    value={selectedNode.data.prompt_id ? String(selectedNode.data.prompt_id) : ''}
                    onChange={(e) => {
                      const promptId = e.target.value
                      console.log('🎯 Prompt selected:', promptId, 'Type:', typeof promptId)
                      const selectedPrompt = availablePrompts.find(p => String(p.id) === promptId)
                      console.log('📋 Selected prompt object:', selectedPrompt)
                      handleNodeUpdate(selectedNode.id, {
                        prompt_id: promptId || null,  // UUID as string, no parseInt!
                        prompt_name: selectedPrompt?.name || null
                      })
                    }}
                    style={{
                      width: '100%',
                      padding: '8px',
                      borderRadius: '4px',
                      border: '1px solid var(--border)',
                      background: 'var(--surface)',
                      color: 'var(--text1)'
                    }}
                  >
                    <option value="">-- Basis-Prompt wählen --</option>
                    {availablePrompts.map(prompt => (
                      <option key={prompt.id} value={String(prompt.id)}>
                        {prompt.name}
                      </option>
                    ))}
                  </select>
                  {selectedNode.data.prompt_id && (
                    <div style={{ marginTop: 8, fontSize: 12, color: 'var(--text3)' }}>
                      Prompt ID: {selectedNode.data.prompt_id} ({selectedNode.data.prompt_name || 'unbekannt'})
                    </div>
                  )}
                </div>

                <QuestionAugmentationPanel node={selectedNode} onChange={handleNodeUpdate} />
                <FallbackConfig node={selectedNode} edges={edges} nodes={nodes} onChange={handleNodeUpdate} />
              </>
            )}

            {selectedNode.type === 'logic' && (
              <>
                <LogicExpressionEditor
                  node={selectedNode}
                  nodes={nodes}
                  edges={edges}
                  onChange={handleNodeUpdate}
                />
                <FallbackConfig node={selectedNode} edges={edges} nodes={nodes} onChange={handleNodeUpdate} />
              </>
            )}

            {selectedNode.type === 'join' && (
              <JoinConfig node={selectedNode} onChange={handleNodeUpdate} />
            )}
          </div>
        )}
      </div>

      {/* Validation Panel */}
      {(validationErrors.length > 0 || validationWarnings.length > 0) && (
        <div className="validation-panel">
          {validationErrors.map((err, i) => (
            <div key={i} className="validation-error" onClick={() => {
              if (err.nodeId) {
                setSelectedNodeId(err.nodeId)
              }
            }}>
              ❌ {err.message}
            </div>
          ))}

          {validationWarnings.map((warn, i) => (
            <div key={i} className="validation-warning" onClick={() => {
              if (warn.nodeId) {
                setSelectedNodeId(warn.nodeId)
              }
            }}>
              ⚠️ {warn.message}
            </div>
          ))}

          {validationErrors.length === 0 && validationWarnings.length > 0 && (
            <div className="validation-success">
              ✅ Workflow ist valide ({validationWarnings.length} Warnungen)
            </div>
          )}
        </div>
      )}
    </div>
  )
}
