import { useState, useCallback, useRef } from 'react'
import { editorAIApi } from '@/api/editorAI'
import { analytics } from '@/lib/analytics'
import type {
  AIActionType,
  EditorAIChatMessage,
  AISuggestion,
  ContextMenuPosition,
} from '@/types'

interface UseEditorAIOptions {
  flowType: 'troubleshooting' | 'procedural'
  treeId?: string | null
  /** Returns the live flow structure from the editor for AI context */
  getFlowContext?: () => Record<string, unknown> | null
  /** Called when the AI response contains a working_tree update */
  onFlowUpdate?: (workingTree: Record<string, unknown>, metadata?: Record<string, unknown> | null) => void
}

export function useEditorAI({ flowType, treeId, getFlowContext, onFlowUpdate }: UseEditorAIOptions) {
  const [isOpen, setIsOpen] = useState(false)
  const [focalNodeId, setFocalNodeId] = useState<string | null>(null)
  const [contextMenu, setContextMenu] = useState<{
    position: ContextMenuPosition
    nodeId: string
  } | null>(null)
  const [sessionId, setSessionId] = useState<string | null>(null)
  const [messages, setMessages] = useState<EditorAIChatMessage[]>([])
  const [input, setInput] = useState('')
  const [isLoading, setIsLoading] = useState(false)
  const [suggestions, setSuggestions] = useState<AISuggestion[]>([])

  const pendingActionRef = useRef<AIActionType>('open_chat')

  const ensureSession = useCallback(async () => {
    if (sessionId) return sessionId
    try {
      const result = await editorAIApi.startSession(flowType, treeId || undefined)
      setSessionId(result.session_id)
      if (result.greeting) {
        setMessages((prev) => [
          ...prev,
          {
            role: 'assistant' as const,
            content: result.greeting,
            timestamp: new Date().toISOString(),
          },
        ])
      }
      return result.session_id
    } catch {
      return null
    }
  }, [sessionId, flowType, treeId])

  const openPanel = useCallback((nodeId?: string, actionType?: AIActionType) => {
    setIsOpen(true)
    if (nodeId) setFocalNodeId(nodeId)
    if (actionType) pendingActionRef.current = actionType
  }, [])

  const closePanel = useCallback(() => {
    setIsOpen(false)
    setContextMenu(null)
  }, [])

  const openContextMenu = useCallback((e: React.MouseEvent, nodeId: string) => {
    e.preventDefault()
    e.stopPropagation()
    setContextMenu({ position: { x: e.clientX, y: e.clientY }, nodeId })
  }, [])

  const closeContextMenu = useCallback(() => {
    setContextMenu(null)
  }, [])

  const sendMessage = useCallback(async () => {
    if (!input.trim() || isLoading) return

    const currentInput = input
    const currentAction = pendingActionRef.current
    const currentFocalNodeId = focalNodeId

    const userMessage: EditorAIChatMessage = {
      role: 'user',
      content: currentInput,
      timestamp: new Date().toISOString(),
      action_type: currentAction,
    }
    setMessages((prev) => [...prev, userMessage])
    setInput('')
    setIsLoading(true)

    try {
      const sid = await ensureSession()
      if (!sid) return

      const result = await editorAIApi.sendMessage({
        sessionId: sid,
        content: currentInput,
        actionType: currentAction,
        focalNodeId: currentFocalNodeId,
        flowContext: getFlowContext?.() || null,
      })
      analytics.aiFeatureUsed({ feature: 'flow_assist' })

      setMessages((prev) => [
        ...prev,
        {
          role: 'assistant',
          content: result.content,
          timestamp: new Date().toISOString(),
        },
      ])

      // Apply AI-generated flow structure to the editor
      if (result.working_tree && onFlowUpdate) {
        onFlowUpdate(result.working_tree, result.tree_metadata || null)
      }
    } catch {
      setMessages((prev) => [
        ...prev,
        {
          role: 'assistant',
          content: 'Sorry, something went wrong. Please try again.',
          timestamp: new Date().toISOString(),
        },
      ])
    } finally {
      setIsLoading(false)
      pendingActionRef.current = 'open_chat'
    }
  }, [input, isLoading, ensureSession, focalNodeId, getFlowContext, onFlowUpdate])

  const triggerAction = useCallback(
    (nodeId: string, actionType: AIActionType, prompt: string) => {
      setFocalNodeId(nodeId)
      pendingActionRef.current = actionType
      setInput(prompt)
      setIsOpen(true)
    },
    []
  )

  return {
    isOpen,
    openPanel,
    closePanel,
    focalNodeId,
    setFocalNodeId,
    contextMenu,
    openContextMenu,
    closeContextMenu,
    messages,
    input,
    setInput,
    sendMessage,
    isLoading,
    suggestions,
    setSuggestions,
    triggerAction,
  }
}
