/**
 * Compliance-Advisor RAG-Suche.
 *
 * Fragt die ai-compliance-sdk (`/sdk/v1/rag/search`) ab statt des frueheren
 * `rag-service:8097` (auf prod nicht erreichbar). Die ai-sdk embeddet die Query
 * mit bge-m3 (prod: ollama-embed) und sucht in den Qdrant-Compliance-Collections
 * — damit profitiert der Advisor vom reicheren Embedding.
 *
 * Fehler je Collection werden geschluckt (graceful: Antwort ohne diesen Treffer).
 * Fundstellen via article_label sind live ab dem Prod-Re-Ingest 2026-06.
 */

const SDK_URL =
  process.env.SDK_API_URL || process.env.SDK_URL || 'http://ai-compliance-sdk:8090'

const DEFAULT_USER = '00000000-0000-0000-0000-000000000001'
const DEFAULT_TENANT =
  process.env.DEFAULT_TENANT_ID || '9282a473-5c95-4b3a-bf78-0ecc0ec71d3e'

// Compliance-relevante Collections (ai-sdk-Whitelist `AllowedCollections`).
export const COMPLIANCE_COLLECTIONS = [
  'bp_compliance_gesetze',
  'bp_compliance_ce',
  'bp_compliance_datenschutz',
  'bp_dsfa_corpus',
  'bp_compliance_recht',
  'bp_legal_templates',
] as const

interface SdkRagResult {
  text?: string
  regulation_code?: string
  regulation_name?: string
  regulation_short?: string
  article_label?: string
  article?: string
  paragraph?: string
  sub?: string
  citation_style?: string
  is_recital?: boolean
  category?: string
  source_url?: string
  score?: number
}

interface ScoredPassage {
  content: string
  source: string
  score: number
}

/** Normalisiert eine ai-sdk-RAG-Antwort auf {content, source, score}. */
export function mapSdkResults(results: SdkRagResult[] | undefined): ScoredPassage[] {
  return (results || [])
    .map((r) => ({
      content: r.text || '',
      // Fundstelle: article_label ist die fertig formatierte, druckbare Quelle aus der
      // Ingestion ("BDSG § 38 Abs. 1"); Fallback baut sie aus den strukturierten Feldern
      // (bzw. alt-ingestierte Chunks ohne Legal-Metadaten). Siehe rag_reingest_spec.md §2/§7.
      source:
        (r.article_label && r.article_label.trim()) ||
        [r.regulation_short || r.regulation_name || r.regulation_code, r.article, r.paragraph, r.sub]
          .filter(Boolean)
          .join(' ') ||
        'Unbekannt',
      score: typeof r.score === 'number' ? r.score : 0,
    }))
    .filter((p) => p.content)
}

async function searchCollection(collection: string, query: string): Promise<ScoredPassage[]> {
  try {
    const res = await fetch(`${SDK_URL}/sdk/v1/rag/search`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-User-ID': DEFAULT_USER,
        'X-Tenant-ID': DEFAULT_TENANT,
      },
      body: JSON.stringify({ query, collection, top_k: 3 }),
      signal: AbortSignal.timeout(10000),
    })
    if (!res.ok) return []
    const data = await res.json()
    return mapSdkResults(data.results)
  } catch {
    return []
  }
}

/**
 * Fragt alle Compliance-Collections parallel ab und liefert die Top-8-Passagen
 * als formatierten Kontextblock (oder '' wenn nichts erreichbar/gefunden).
 */
export async function queryAdvisorRAG(query: string): Promise<string> {
  const settled = await Promise.all(
    COMPLIANCE_COLLECTIONS.map((c) => searchCollection(c, query)),
  )
  const all = settled.flat()
  if (all.length === 0) return ''
  all.sort((a, b) => b.score - a.score)
  return all
    .slice(0, 8)
    .map((r, i) => `[Quelle ${i + 1}: ${r.source}]\n${r.content}`)
    .join('\n\n---\n\n')
}
