import { useState, useCallback } from 'react'
import { databases, DATABASE_ID, COLLECTIONS, ID, isDemoMode } from '../lib/appwrite'
import {
  fetchRoadmapNodes,
  logNodeStatusWorksheet,
  allGoalsDone,
  NODE_KIND,
  NODE_STATUS,
} from '../lib/roadmaps'

export function useRoadmapNodes() {
  const [nodes, setNodes] = useState([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState(null)

  const fetchNodes = useCallback(async (roadmapId) => {
    if (!roadmapId || isDemoMode) return []
    setLoading(true)
    setError(null)
    try {
      const docs = await fetchRoadmapNodes(roadmapId)
      setNodes(docs)
      return docs
    } catch (err) {
      setError(err.message)
      return []
    } finally {
      setLoading(false)
    }
  }, [])

  const createNode = async (roadmapId, { title, column, row, kind }) => {
    if (isDemoMode) return { success: false, error: 'Demo-Modus' }
    try {
      const now = new Date().toISOString()
      const doc = await databases.createDocument(DATABASE_ID, COLLECTIONS.ROADMAP_NODES, ID.unique(), {
        roadmapId,
        title: title || 'Neuer Schritt',
        kind: kind || NODE_KIND.STEP,
        column,
        row,
        status: NODE_STATUS.OPEN,
        createdAt: now,
        updatedAt: now,
      })
      setNodes((prev) => [...prev, doc])
      return { success: true, data: doc }
    } catch (err) {
      return { success: false, error: err.message }
    }
  }

  const updateNode = async (nodeId, data) => {
    if (isDemoMode) return { success: false, error: 'Demo-Modus' }
    try {
      const doc = await databases.updateDocument(DATABASE_ID, COLLECTIONS.ROADMAP_NODES, nodeId, {
        ...data,
        updatedAt: new Date().toISOString(),
      })
      setNodes((prev) => prev.map((n) => (n.$id === nodeId ? doc : n)))
      return { success: true, data: doc }
    } catch (err) {
      return { success: false, error: err.message }
    }
  }

  /** Knoten loeschen inkl. Bereinigung eingehender Kanten bei den Nachfolgern. */
  const deleteNode = async (node) => {
    if (isDemoMode) return { success: false, error: 'Demo-Modus' }
    if (node.kind === NODE_KIND.START) {
      return { success: false, error: 'Der Start-Knoten kann nicht geloescht werden.' }
    }
    if (node.kind === NODE_KIND.GOAL && nodes.filter((n) => n.kind === NODE_KIND.GOAL).length <= 1) {
      return { success: false, error: 'Ein Plan braucht mindestens ein Ziel.' }
    }
    try {
      const successors = nodes.filter((n) => (n.sourceIds || []).includes(node.$id))
      await Promise.all(successors.map((n) =>
        databases.updateDocument(DATABASE_ID, COLLECTIONS.ROADMAP_NODES, n.$id, {
          sourceIds: (n.sourceIds || []).filter((id) => id !== node.$id),
          updatedAt: new Date().toISOString(),
        })
      ))
      await databases.deleteDocument(DATABASE_ID, COLLECTIONS.ROADMAP_NODES, node.$id)
      setNodes((prev) => prev
        .filter((n) => n.$id !== node.$id)
        .map((n) => ((n.sourceIds || []).includes(node.$id)
          ? { ...n, sourceIds: n.sourceIds.filter((id) => id !== node.$id) }
          : n))
      )
      return { success: true }
    } catch (err) {
      return { success: false, error: err.message }
    }
  }

  /** Kante anlegen: immer vorwaerts (Zielspalte > Quellspalte), keine Duplikate. */
  const connectNodes = async (source, target) => {
    if (isDemoMode) return { success: false, error: 'Demo-Modus' }
    if (source.$id === target.$id) return { success: false, error: 'Knoten kann nicht mit sich selbst verbunden werden.' }
    if (target.column <= source.column) {
      return { success: false, error: 'Verbindungen laufen immer vorwaerts (nach rechts).' }
    }
    if ((target.sourceIds || []).includes(source.$id)) {
      return { success: false, error: 'Diese Verbindung existiert bereits.' }
    }
    return updateNode(target.$id, { sourceIds: [...(target.sourceIds || []), source.$id] })
  }

  const disconnectNodes = async (sourceId, target) => {
    return updateNode(target.$id, { sourceIds: (target.sourceIds || []).filter((id) => id !== sourceId) })
  }

  /** Statuswechsel inkl. Worksheet-Log am Projektticket; meldet, ob alle Ziele fertig sind. */
  const setNodeStatus = async (roadmap, node, newStatus, user) => {
    if (isDemoMode) return { success: false, error: 'Demo-Modus' }
    const oldStatus = node.status || NODE_STATUS.OPEN
    if (oldStatus === newStatus) return { success: true, allGoalsDone: false }
    const result = await updateNode(node.$id, { status: newStatus })
    if (!result.success) return result
    try {
      await logNodeStatusWorksheet(roadmap, node, oldStatus, newStatus, user)
    } catch {
      /* Verlaufslog ist optional - Statuswechsel bleibt gueltig */
    }
    const updatedNodes = nodes.map((n) => (n.$id === node.$id ? { ...n, status: newStatus } : n))
    return { success: true, data: result.data, allGoalsDone: allGoalsDone(updatedNodes) }
  }

  return {
    nodes, loading, error, setNodes,
    fetchNodes, createNode, updateNode, deleteNode,
    connectNodes, disconnectNodes, setNodeStatus,
  }
}
