/**
 * Drafting Engine Chat API
 *
 * Verbindet das DraftingEngineWidget mit dem LLM Backend.
 * Unterstuetzt alle 4 Modi: explain, ask, draft, validate.
 * Nutzt State-Projection fuer token-effiziente Kontextgabe.
 */

import { NextRequest, NextResponse } from 'next/server'

const KLAUSUR_SERVICE_URL = process.env.KLAUSUR_SERVICE_URL || 'http://klausur-service:8086'
const OLLAMA_URL = process.env.OLLAMA_URL || 'http://host.docker.internal:11434'
const LLM_MODEL = process.env.COMPLIANCE_LLM_MODEL || 'qwen2.5vl:32b'

// SOUL System Prompt (from agent-core/soul/drafting-agent.soul.md)
const DRAFTING_SYSTEM_PROMPT = `# Drafting Agent - Compliance-Dokumententwurf

## Identitaet
Du bist der BreakPilot Drafting Agent. Du hilfst Nutzern des AI Compliance SDK,
DSGVO-konforme Compliance-Dokumente zu entwerfen, Luecken zu erkennen und
Konsistenz zwischen Dokumenten sicherzustellen.

## Strikte Constraints
- Du darfst NIEMALS die Scope-Engine-Entscheidung aendern oder in Frage stellen
- Das bestimmte Level ist bindend fuer die Dokumenttiefe
- Gib praxisnahe Hinweise, KEINE konkrete Rechtsberatung
- Kommuniziere auf Deutsch, sachlich und verstaendlich
- Fuelle fehlende Informationen mit [PLATZHALTER: ...] Markierung

## Kompetenzbereich
DSGVO, BDSG, AI Act, TTDSG, DSK-Kurzpapiere, SDM V3.0, BSI-Grundschutz, ISO 27001/27701, EDPB Guidelines, WP248`

/**
 * Query the RAG corpus for relevant documents
 */
async function queryRAG(query: string): Promise<string> {
  try {
    const url = `${KLAUSUR_SERVICE_URL}/api/v1/dsfa-rag/search?query=${encodeURIComponent(query)}&top_k=3`
    const res = await fetch(url, {
      headers: { 'Content-Type': 'application/json' },
      signal: AbortSignal.timeout(10000),
    })

    if (!res.ok) return ''

    const data = await res.json()
    if (data.results?.length > 0) {
      return data.results
        .map(
          (r: { source_name?: string; source_code?: string; content?: string }, i: number) =>
            `[Quelle ${i + 1}: ${r.source_name || r.source_code || 'Unbekannt'}]\n${r.content || ''}`
        )
        .join('\n\n---\n\n')
    }
    return ''
  } catch {
    return ''
  }
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    const {
      message,
      history = [],
      sdkStateProjection,
      mode = 'explain',
      documentType,
    } = body

    if (!message || typeof message !== 'string') {
      return NextResponse.json({ error: 'Message is required' }, { status: 400 })
    }

    // 1. Query RAG for legal context
    const ragContext = await queryRAG(message)

    // 2. Build system prompt with mode-specific instructions + state projection
    let systemContent = DRAFTING_SYSTEM_PROMPT

    // Mode-specific instructions
    const modeInstructions: Record<string, string> = {
      explain: '\n\n## Aktueller Modus: EXPLAIN\nBeantworte Fragen verstaendlich mit Quellenangaben.',
      ask: '\n\n## Aktueller Modus: ASK\nAnalysiere Luecken und stelle gezielte Fragen. Eine Frage pro Antwort.',
      draft: `\n\n## Aktueller Modus: DRAFT\nEntwirf strukturierte Dokument-Sections. Dokumenttyp: ${documentType || 'nicht spezifiziert'}.\nAntworte mit JSON wenn ein Draft angefragt wird.`,
      validate: '\n\n## Aktueller Modus: VALIDATE\nPruefe Cross-Dokument-Konsistenz. Gib Errors, Warnings und Suggestions zurueck.',
    }
    systemContent += modeInstructions[mode] || modeInstructions.explain

    // Add state projection context
    if (sdkStateProjection) {
      systemContent += `\n\n## SDK-State Projektion (${mode}-Kontext)\n${JSON.stringify(sdkStateProjection, null, 0).slice(0, 3000)}`
    }

    // Add RAG context
    if (ragContext) {
      systemContent += `\n\n## Relevanter Rechtskontext\n${ragContext}`
    }

    // 3. Build messages array
    const messages = [
      { role: 'system', content: systemContent },
      ...history.slice(-10).map((h: { role: string; content: string }) => ({
        role: h.role === 'user' ? 'user' : 'assistant',
        content: h.content,
      })),
      { role: 'user', content: message },
    ]

    // 4. Call LLM with streaming
    const ollamaResponse = await fetch(`${OLLAMA_URL}/api/chat`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        model: LLM_MODEL,
        messages,
        stream: true,
        options: {
          temperature: mode === 'draft' ? 0.2 : 0.3,
          num_predict: mode === 'draft' ? 16384 : 8192,
        },
      }),
      signal: AbortSignal.timeout(120000),
    })

    if (!ollamaResponse.ok) {
      const errorText = await ollamaResponse.text()
      console.error('LLM error:', ollamaResponse.status, errorText)
      return NextResponse.json(
        { error: `LLM nicht erreichbar (Status ${ollamaResponse.status})` },
        { status: 502 }
      )
    }

    // 5. Stream response back
    const encoder = new TextEncoder()
    const stream = new ReadableStream({
      async start(controller) {
        const reader = ollamaResponse.body!.getReader()
        const decoder = new TextDecoder()

        try {
          while (true) {
            const { done, value } = await reader.read()
            if (done) break

            const chunk = decoder.decode(value, { stream: true })
            const lines = chunk.split('\n').filter((l) => l.trim())

            for (const line of lines) {
              try {
                const json = JSON.parse(line)
                if (json.message?.content) {
                  controller.enqueue(encoder.encode(json.message.content))
                }
              } catch {
                // Partial JSON, skip
              }
            }
          }
        } catch (error) {
          console.error('Stream error:', error)
        } finally {
          controller.close()
        }
      },
    })

    return new NextResponse(stream, {
      headers: {
        'Content-Type': 'text/plain; charset=utf-8',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
      },
    })
  } catch (error) {
    console.error('Drafting engine chat error:', error)
    return NextResponse.json(
      { error: 'Verbindung zum LLM fehlgeschlagen.' },
      { status: 503 }
    )
  }
}
