'use client'

/**
 * useDraftingEngine - React Hook fuer die Drafting Engine
 *
 * Managed: currentMode, activeDocumentType, draftSessions, validationState
 * Handled: State-Projection, API-Calls, Streaming
 * Provides: sendMessage(), requestDraft(), validateDraft(), acceptDraft()
 */

import { useState, useCallback, useRef } from 'react'
import { useSDK } from '../context'
import { stateProjector } from './state-projector'
import { intentClassifier } from './intent-classifier'
import { constraintEnforcer } from './constraint-enforcer'
import type {
  AgentMode,
  DraftSession,
  DraftRevision,
  DraftingChatMessage,
  ValidationResult,
  ConstraintCheckResult,
  DraftContext,
  GapContext,
  ValidationContext,
} from './types'
import type { ScopeDocumentType } from '../compliance-scope-types'

export interface DraftingEngineState {
  currentMode: AgentMode
  activeDocumentType: ScopeDocumentType | null
  messages: DraftingChatMessage[]
  isTyping: boolean
  currentDraft: DraftRevision | null
  validationResult: ValidationResult | null
  constraintCheck: ConstraintCheckResult | null
  error: string | null
}

export interface DraftingEngineActions {
  setMode: (mode: AgentMode) => void
  setDocumentType: (type: ScopeDocumentType) => void
  sendMessage: (content: string) => Promise<void>
  requestDraft: (instructions?: string) => Promise<void>
  validateDraft: () => Promise<void>
  acceptDraft: () => void
  stopGeneration: () => void
  clearMessages: () => void
}

export function useDraftingEngine(): DraftingEngineState & DraftingEngineActions {
  const { state, dispatch } = useSDK()
  const abortControllerRef = useRef<AbortController | null>(null)

  const [currentMode, setCurrentMode] = useState<AgentMode>('explain')
  const [activeDocumentType, setActiveDocumentType] = useState<ScopeDocumentType | null>(null)
  const [messages, setMessages] = useState<DraftingChatMessage[]>([])
  const [isTyping, setIsTyping] = useState(false)
  const [currentDraft, setCurrentDraft] = useState<DraftRevision | null>(null)
  const [validationResult, setValidationResult] = useState<ValidationResult | null>(null)
  const [constraintCheck, setConstraintCheck] = useState<ConstraintCheckResult | null>(null)
  const [error, setError] = useState<string | null>(null)

  // Get state projection based on mode
  const getProjection = useCallback(() => {
    switch (currentMode) {
      case 'draft':
        return activeDocumentType
          ? stateProjector.projectForDraft(state, activeDocumentType)
          : null
      case 'ask':
        return stateProjector.projectForAsk(state)
      case 'validate':
        return activeDocumentType
          ? stateProjector.projectForValidate(state, [activeDocumentType])
          : stateProjector.projectForValidate(state, ['vvt', 'tom', 'lf'])
      default:
        return activeDocumentType
          ? stateProjector.projectForDraft(state, activeDocumentType)
          : null
    }
  }, [state, currentMode, activeDocumentType])

  const setMode = useCallback((mode: AgentMode) => {
    setCurrentMode(mode)
  }, [])

  const setDocumentType = useCallback((type: ScopeDocumentType) => {
    setActiveDocumentType(type)
  }, [])

  const sendMessage = useCallback(async (content: string) => {
    if (!content.trim() || isTyping) return
    setError(null)

    // Auto-detect mode if needed
    const classification = intentClassifier.classify(content)
    if (classification.confidence > 0.7 && classification.mode !== currentMode) {
      setCurrentMode(classification.mode)
    }
    if (classification.detectedDocumentType && !activeDocumentType) {
      setActiveDocumentType(classification.detectedDocumentType)
    }

    const userMessage: DraftingChatMessage = {
      role: 'user',
      content: content.trim(),
    }
    setMessages(prev => [...prev, userMessage])
    setIsTyping(true)

    abortControllerRef.current = new AbortController()

    try {
      const projection = getProjection()
      const response = await fetch('/api/sdk/drafting-engine/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          message: content.trim(),
          history: messages.map(m => ({ role: m.role, content: m.content })),
          sdkStateProjection: projection,
          mode: currentMode,
          documentType: activeDocumentType,
        }),
        signal: abortControllerRef.current.signal,
      })

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({ error: 'Unbekannter Fehler' }))
        throw new Error(errorData.error || `Server-Fehler (${response.status})`)
      }

      const agentMessageId = `msg-${Date.now()}-agent`
      setMessages(prev => [...prev, {
        role: 'assistant',
        content: '',
        metadata: { mode: currentMode, documentType: activeDocumentType ?? undefined },
      }])

      // Stream response
      const reader = response.body!.getReader()
      const decoder = new TextDecoder()
      let accumulated = ''

      while (true) {
        const { done, value } = await reader.read()
        if (done) break
        accumulated += decoder.decode(value, { stream: true })
        const text = accumulated
        setMessages(prev =>
          prev.map((m, i) => i === prev.length - 1 ? { ...m, content: text } : m)
        )
      }

      setIsTyping(false)
    } catch (err) {
      if ((err as Error).name === 'AbortError') {
        setIsTyping(false)
        return
      }
      setError((err as Error).message)
      setMessages(prev => [...prev, {
        role: 'assistant',
        content: `Fehler: ${(err as Error).message}`,
      }])
      setIsTyping(false)
    }
  }, [isTyping, messages, currentMode, activeDocumentType, getProjection])

  const requestDraft = useCallback(async (instructions?: string) => {
    if (!activeDocumentType) {
      setError('Bitte waehlen Sie zuerst einen Dokumenttyp.')
      return
    }
    setError(null)
    setIsTyping(true)

    try {
      const draftContext = stateProjector.projectForDraft(state, activeDocumentType)

      const response = await fetch('/api/sdk/drafting-engine/draft', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          documentType: activeDocumentType,
          draftContext,
          instructions,
          existingDraft: currentDraft,
        }),
      })

      const result = await response.json()

      if (!response.ok) {
        throw new Error(result.error || 'Draft-Generierung fehlgeschlagen')
      }

      setCurrentDraft(result.draft)
      setConstraintCheck(result.constraintCheck)

      setMessages(prev => [...prev, {
        role: 'assistant',
        content: `Draft fuer ${activeDocumentType} erstellt (${result.draft.sections.length} Sections). Oeffnen Sie den Editor zur Bearbeitung.`,
        metadata: { mode: 'draft', documentType: activeDocumentType, hasDraft: true },
      }])

      setIsTyping(false)
    } catch (err) {
      setError((err as Error).message)
      setIsTyping(false)
    }
  }, [activeDocumentType, state, currentDraft])

  const validateDraft = useCallback(async () => {
    setError(null)
    setIsTyping(true)

    try {
      const docTypes: ScopeDocumentType[] = activeDocumentType
        ? [activeDocumentType]
        : ['vvt', 'tom', 'lf']
      const validationContext = stateProjector.projectForValidate(state, docTypes)

      const response = await fetch('/api/sdk/drafting-engine/validate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          documentType: activeDocumentType || 'vvt',
          draftContent: currentDraft?.content || '',
          validationContext,
        }),
      })

      const result = await response.json()

      if (!response.ok) {
        throw new Error(result.error || 'Validierung fehlgeschlagen')
      }

      setValidationResult(result)

      const summary = result.passed
        ? `Validierung bestanden. ${result.warnings.length} Warnungen, ${result.suggestions.length} Vorschlaege.`
        : `Validierung fehlgeschlagen. ${result.errors.length} Fehler, ${result.warnings.length} Warnungen.`

      setMessages(prev => [...prev, {
        role: 'assistant',
        content: summary,
        metadata: { mode: 'validate', hasValidation: true },
      }])

      setIsTyping(false)
    } catch (err) {
      setError((err as Error).message)
      setIsTyping(false)
    }
  }, [activeDocumentType, state, currentDraft])

  const acceptDraft = useCallback(() => {
    if (!currentDraft || !activeDocumentType) return

    // Dispatch the draft data into SDK state
    switch (activeDocumentType) {
      case 'vvt':
        dispatch({
          type: 'ADD_PROCESSING_ACTIVITY',
          payload: {
            id: `draft-vvt-${Date.now()}`,
            name: currentDraft.sections.find(s => s.schemaField === 'name')?.content || 'Neuer VVT-Eintrag',
            ...Object.fromEntries(
              currentDraft.sections
                .filter(s => s.schemaField)
                .map(s => [s.schemaField!, s.content])
            ),
          },
        })
        break
      case 'tom':
        dispatch({
          type: 'ADD_TOM',
          payload: {
            id: `draft-tom-${Date.now()}`,
            name: 'TOM-Entwurf',
            ...Object.fromEntries(
              currentDraft.sections
                .filter(s => s.schemaField)
                .map(s => [s.schemaField!, s.content])
            ),
          },
        })
        break
      default:
        dispatch({
          type: 'ADD_DOCUMENT',
          payload: {
            id: `draft-${activeDocumentType}-${Date.now()}`,
            type: activeDocumentType,
            content: currentDraft.content,
            sections: currentDraft.sections,
          },
        })
    }

    setMessages(prev => [...prev, {
      role: 'assistant',
      content: `Draft wurde in den SDK-State uebernommen.`,
    }])
    setCurrentDraft(null)
  }, [currentDraft, activeDocumentType, dispatch])

  const stopGeneration = useCallback(() => {
    abortControllerRef.current?.abort()
    setIsTyping(false)
  }, [])

  const clearMessages = useCallback(() => {
    setMessages([])
    setCurrentDraft(null)
    setValidationResult(null)
    setConstraintCheck(null)
    setError(null)
  }, [])

  return {
    currentMode,
    activeDocumentType,
    messages,
    isTyping,
    currentDraft,
    validationResult,
    constraintCheck,
    error,
    setMode,
    setDocumentType,
    sendMessage,
    requestDraft,
    validateDraft,
    acceptDraft,
    stopGeneration,
    clearMessages,
  }
}
