'use client'

/**
 * Screen Flow - State management hook
 */

import { useCallback, useState, useMemo, useEffect } from 'react'
import { Node, Edge, useNodesState, useEdgesState, MarkerType } from 'reactflow'

import type { ScreenDefinition, FlowType } from './types'
import {
  STUDIO_SCREENS, ADMIN_SCREENS,
  STUDIO_CONNECTIONS, ADMIN_CONNECTIONS,
  STUDIO_COLORS, ADMIN_COLORS,
  STUDIO_LABELS, ADMIN_LABELS,
} from './data'
import { findConnectedNodes, getNodePosition } from './helpers'

export function useScreenFlow() {
  const [flowType, setFlowType] = useState<FlowType>('admin')
  const [selectedCategory, setSelectedCategory] = useState<string | null>(null)
  const [selectedNode, setSelectedNode] = useState<string | null>(null)
  const [previewScreen, setPreviewScreen] = useState<ScreenDefinition | null>(null)

  // Derived data based on flow type
  const screens = flowType === 'studio' ? STUDIO_SCREENS : ADMIN_SCREENS
  const connections = flowType === 'studio' ? STUDIO_CONNECTIONS : ADMIN_CONNECTIONS
  const colors = flowType === 'studio' ? STUDIO_COLORS : ADMIN_COLORS
  const labels = flowType === 'studio' ? STUDIO_LABELS : ADMIN_LABELS
  const baseUrl = flowType === 'studio' ? 'http://macmini:8000' : 'http://macmini:3002'

  // BFS connected nodes
  const connectedNodes = useMemo(() => {
    if (!selectedNode) return new Set<string>()
    return findConnectedNodes(selectedNode, connections, 'children')
  }, [selectedNode, connections])

  // Build ReactFlow nodes
  const initialNodes = useMemo((): Node[] => {
    return screens.map((screen) => {
      const catColors = colors[screen.category] || { bg: '#f1f5f9', border: '#94a3b8', text: '#475569' }
      const position = getNodePosition(screen.id, screen.category, screens, flowType)

      let opacity = 1
      if (selectedNode) {
        opacity = connectedNodes.has(screen.id) ? 1 : 0.2
      } else if (selectedCategory) {
        opacity = screen.category === selectedCategory ? 1 : 0.2
      }

      const isSelected = selectedNode === screen.id

      return {
        id: screen.id,
        type: 'default',
        position,
        data: {
          label: (
            <div className="text-center p-1">
              <div className="text-lg mb-1">{screen.icon}</div>
              <div className="font-medium text-xs leading-tight">{screen.name}</div>
            </div>
          ),
        },
        style: {
          background: isSelected ? catColors.border : catColors.bg,
          color: isSelected ? 'white' : catColors.text,
          border: `2px solid ${catColors.border}`,
          borderRadius: '12px',
          padding: '6px',
          minWidth: '110px',
          opacity,
          cursor: 'pointer',
          boxShadow: isSelected ? `0 0 20px ${catColors.border}` : 'none',
        },
      }
    })
  }, [screens, colors, flowType, selectedCategory, selectedNode, connectedNodes])

  // Build ReactFlow edges
  const initialEdges = useMemo((): Edge[] => {
    return connections.map((conn, index) => {
      const isHighlighted = selectedNode && (conn.source === selectedNode || conn.target === selectedNode)
      const isInSubtree = selectedNode && connectedNodes.has(conn.source) && connectedNodes.has(conn.target)

      return {
        id: `e-${conn.source}-${conn.target}-${index}`,
        source: conn.source,
        target: conn.target,
        label: conn.label,
        type: 'smoothstep',
        animated: isHighlighted || false,
        style: {
          stroke: isHighlighted ? '#3b82f6' : (isInSubtree ? '#94a3b8' : '#e2e8f0'),
          strokeWidth: isHighlighted ? 3 : 1.5,
          opacity: selectedNode ? (isInSubtree ? 1 : 0.15) : 1,
        },
        labelStyle: { fontSize: 9, fill: '#64748b' },
        labelBgStyle: { fill: '#f8fafc' },
        markerEnd: { type: MarkerType.ArrowClosed, color: isHighlighted ? '#3b82f6' : '#94a3b8', width: 15, height: 15 },
      }
    })
  }, [connections, selectedNode, connectedNodes])

  const [nodes, setNodes, onNodesChange] = useNodesState([])
  const [edges, setEdges, onEdgesChange] = useEdgesState([])

  // Sync memoized nodes/edges into ReactFlow state
  useEffect(() => {
    setNodes(initialNodes)
    setEdges(initialEdges)
  }, [initialNodes, initialEdges, setNodes, setEdges])

  // Reset on flow type change
  const handleFlowTypeChange = useCallback((newType: FlowType) => {
    setFlowType(newType)
    setSelectedNode(null)
    setSelectedCategory(null)
    setPreviewScreen(null)
  }, [])

  // Node click: select or open on double-click
  const onNodeClick = useCallback((_event: React.MouseEvent, node: Node) => {
    const screen = screens.find(s => s.id === node.id)

    if (selectedNode === node.id) {
      if (screen?.url) {
        window.open(`${baseUrl}${screen.url}`, '_blank')
      }
      return
    }

    setSelectedNode(node.id)
    setSelectedCategory(null)
    if (screen) {
      setPreviewScreen(screen)
    }
  }, [screens, baseUrl, selectedNode])

  // Background click: deselect
  const onPaneClick = useCallback(() => {
    setSelectedNode(null)
    setPreviewScreen(null)
  }, [])

  const stats = {
    totalScreens: screens.length,
    totalConnections: connections.length,
    connectedCount: connectedNodes.size,
  }

  const categories = Object.keys(labels)

  const connectedScreens = selectedNode
    ? screens.filter(s => connectedNodes.has(s.id))
    : []

  return {
    flowType,
    selectedCategory,
    setSelectedCategory,
    selectedNode,
    setSelectedNode,
    previewScreen,
    setPreviewScreen,
    screens,
    colors,
    labels,
    baseUrl,
    connectedNodes,
    nodes,
    edges,
    onNodesChange,
    onEdgesChange,
    handleFlowTypeChange,
    onNodeClick,
    onPaneClick,
    stats,
    categories,
    connectedScreens,
  }
}
