/**
 * SDK Backend Client
 *
 * Client for communicating with the SDK Backend (Go service)
 * for RAG search and document generation.
 */

// =============================================================================
// TYPES
// =============================================================================

export interface SearchResult {
  id: string
  content: string
  source: string
  score: number
  metadata?: Record<string, string>
  highlights?: string[]
}

export interface SearchResponse {
  query: string
  topK: number
  results: SearchResult[]
  source: 'qdrant' | 'mock'
}

export interface CorpusStatus {
  status: 'ready' | 'unavailable' | 'indexing'
  collections: string[]
  documents: number
  lastUpdated?: string
}

export interface GenerateRequest {
  tenantId: string
  context: Record<string, unknown>
  template?: string
  language?: 'de' | 'en'
  useRag?: boolean
  ragQuery?: string
  maxTokens?: number
  temperature?: number
}

export interface GenerateResponse {
  content: string
  generatedAt: string
  model: string
  tokensUsed: number
  ragSources?: SearchResult[]
  confidence?: number
}

export interface SDKBackendResponse<T> {
  success: boolean
  data?: T
  error?: string
  code?: string
}

// =============================================================================
// CONFIGURATION
// =============================================================================

const SDK_BACKEND_URL = process.env.NEXT_PUBLIC_SDK_BACKEND_URL || 'http://localhost:8085'
const DEFAULT_TIMEOUT = 60000 // 60 seconds for generation

// =============================================================================
// SDK BACKEND CLIENT
// =============================================================================

export class SDKBackendClient {
  private baseUrl: string
  private timeout: number

  constructor(options: {
    baseUrl?: string
    timeout?: number
  } = {}) {
    this.baseUrl = options.baseUrl || SDK_BACKEND_URL
    this.timeout = options.timeout || DEFAULT_TIMEOUT
  }

  // ---------------------------------------------------------------------------
  // Private Methods
  // ---------------------------------------------------------------------------

  private async fetch<T>(
    path: string,
    options: RequestInit = {}
  ): Promise<T> {
    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), this.timeout)

    try {
      const response = await fetch(`${this.baseUrl}${path}`, {
        ...options,
        signal: controller.signal,
        headers: {
          'Content-Type': 'application/json',
          ...options.headers,
        },
      })

      const data = await response.json() as SDKBackendResponse<T>

      if (!response.ok || !data.success) {
        throw new Error(data.error || `HTTP ${response.status}`)
      }

      return data.data as T
    } finally {
      clearTimeout(timeoutId)
    }
  }

  // ---------------------------------------------------------------------------
  // RAG Search
  // ---------------------------------------------------------------------------

  /**
   * Search the legal corpus using semantic search
   */
  async search(
    query: string,
    options: {
      topK?: number
      collection?: string
      filter?: string
    } = {}
  ): Promise<SearchResponse> {
    const params = new URLSearchParams({
      q: query,
      top_k: String(options.topK || 5),
    })

    if (options.collection) {
      params.set('collection', options.collection)
    }
    if (options.filter) {
      params.set('filter', options.filter)
    }

    return this.fetch<SearchResponse>(`/sdk/v1/rag/search?${params}`)
  }

  /**
   * Get the status of the legal corpus
   */
  async getCorpusStatus(): Promise<CorpusStatus> {
    return this.fetch<CorpusStatus>('/sdk/v1/rag/status')
  }

  /**
   * Index a new document into the corpus
   */
  async indexDocument(
    collection: string,
    id: string,
    content: string,
    metadata?: Record<string, string>
  ): Promise<{ indexed: boolean; id: string }> {
    return this.fetch('/sdk/v1/rag/index', {
      method: 'POST',
      body: JSON.stringify({
        collection,
        id,
        content,
        metadata,
      }),
    })
  }

  // ---------------------------------------------------------------------------
  // Document Generation
  // ---------------------------------------------------------------------------

  /**
   * Generate a Data Protection Impact Assessment (DSFA)
   */
  async generateDSFA(request: GenerateRequest): Promise<GenerateResponse> {
    return this.fetch<GenerateResponse>('/sdk/v1/generate/dsfa', {
      method: 'POST',
      body: JSON.stringify(request),
    })
  }

  /**
   * Generate Technical and Organizational Measures (TOM)
   */
  async generateTOM(request: GenerateRequest): Promise<GenerateResponse> {
    return this.fetch<GenerateResponse>('/sdk/v1/generate/tom', {
      method: 'POST',
      body: JSON.stringify(request),
    })
  }

  /**
   * Generate a Processing Activity Register (VVT)
   */
  async generateVVT(request: GenerateRequest): Promise<GenerateResponse> {
    return this.fetch<GenerateResponse>('/sdk/v1/generate/vvt', {
      method: 'POST',
      body: JSON.stringify(request),
    })
  }

  /**
   * Generate an expert opinion/assessment (Gutachten)
   */
  async generateGutachten(request: GenerateRequest): Promise<GenerateResponse> {
    return this.fetch<GenerateResponse>('/sdk/v1/generate/gutachten', {
      method: 'POST',
      body: JSON.stringify(request),
    })
  }

  // ---------------------------------------------------------------------------
  // Health Check
  // ---------------------------------------------------------------------------

  /**
   * Check if the SDK backend is healthy
   */
  async healthCheck(): Promise<{
    status: string
    timestamp: string
    services: {
      database: boolean
      rag: boolean
      llm: boolean
    }
  }> {
    try {
      const response = await fetch(`${this.baseUrl}/health`, {
        method: 'GET',
      })
      return response.json()
    } catch {
      return {
        status: 'unhealthy',
        timestamp: new Date().toISOString(),
        services: {
          database: false,
          rag: false,
          llm: false,
        },
      }
    }
  }
}

// =============================================================================
// SINGLETON INSTANCE
// =============================================================================

let clientInstance: SDKBackendClient | null = null

export function getSDKBackendClient(): SDKBackendClient {
  if (!clientInstance) {
    clientInstance = new SDKBackendClient()
  }
  return clientInstance
}

export function resetSDKBackendClient(): void {
  clientInstance = null
}

// =============================================================================
// UTILITY FUNCTIONS
// =============================================================================

/**
 * Check if a query is likely a legal/compliance search
 */
export function isLegalQuery(query: string): boolean {
  const legalKeywords = [
    'dsgvo', 'gdpr', 'datenschutz', 'privacy',
    'ai act', 'ki-gesetz', 'ai-verordnung',
    'nis2', 'cybersicherheit',
    'artikel', 'article', 'art.',
    'verordnung', 'regulation', 'richtlinie', 'directive',
    'gesetz', 'law', 'compliance',
    'dsfa', 'dpia', 'folgenabschätzung',
    'tom', 'maßnahmen', 'measures',
    'vvt', 'verarbeitungsverzeichnis',
  ]

  const normalizedQuery = query.toLowerCase()
  return legalKeywords.some(keyword => normalizedQuery.includes(keyword))
}

/**
 * Extract regulation references from text
 */
export function extractRegulationReferences(text: string): Array<{
  regulation: string
  article: string
  fullReference: string
}> {
  const references: Array<{
    regulation: string
    article: string
    fullReference: string
  }> = []

  // Match patterns like "Art. 5 DSGVO", "Article 6 GDPR", "Art. 35 Abs. 1 DSGVO"
  const patterns = [
    /Art(?:ikel|\.|\s)*(\d+)(?:\s*Abs\.\s*(\d+))?\s*(DSGVO|GDPR|AI\s*Act|NIS2)/gi,
    /Article\s*(\d+)(?:\s*para(?:graph)?\s*(\d+))?\s*(DSGVO|GDPR|AI\s*Act|NIS2)/gi,
  ]

  for (const pattern of patterns) {
    let match
    while ((match = pattern.exec(text)) !== null) {
      references.push({
        regulation: match[3].toUpperCase().replace(/\s+/g, ' '),
        article: match[2] ? `${match[1]} Abs. ${match[2]}` : match[1],
        fullReference: match[0],
      })
    }
  }

  return references
}
