/**
 * Korrekturplattform API Service Layer
 *
 * Connects to klausur-service (Port 8086) for all correction-related operations.
 * Uses dynamic host detection for local network compatibility.
 */

import type {
  Klausur,
  StudentWork,
  CriteriaScores,
  Annotation,
  AnnotationPosition,
  AnnotationType,
  FairnessAnalysis,
  EHSuggestion,
  GradeInfo,
  CreateKlausurData,
} from '@/app/korrektur/types'

// Get API base URL dynamically
// On localhost: direct connection to port 8086
// On macmini: use nginx proxy /klausur-api/ to avoid certificate issues
const getApiBase = (): string => {
  if (typeof window === 'undefined') return 'http://localhost:8086'
  const { hostname } = window.location
  // Use nginx proxy on macmini to avoid cross-origin certificate issues
  return hostname === 'localhost' ? 'http://localhost:8086' : '/klausur-api'
}

// Generic fetch wrapper with error handling
async function apiFetch<T>(
  endpoint: string,
  options: RequestInit = {}
): Promise<T> {
  const url = `${getApiBase()}${endpoint}`

  const response = await fetch(url, {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      ...options.headers,
    },
  })

  if (!response.ok) {
    const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }))
    throw new Error(errorData.detail || `HTTP ${response.status}`)
  }

  return response.json()
}

// ============================================================================
// KLAUSUREN API
// ============================================================================

export async function getKlausuren(): Promise<Klausur[]> {
  const data = await apiFetch<{ klausuren: Klausur[] }>('/api/v1/klausuren')
  return data.klausuren || []
}

export async function getKlausur(id: string): Promise<Klausur> {
  return apiFetch<Klausur>(`/api/v1/klausuren/${id}`)
}

export async function createKlausur(data: CreateKlausurData): Promise<Klausur> {
  return apiFetch<Klausur>('/api/v1/klausuren', {
    method: 'POST',
    body: JSON.stringify(data),
  })
}

export async function deleteKlausur(id: string): Promise<void> {
  await apiFetch(`/api/v1/klausuren/${id}`, { method: 'DELETE' })
}

// ============================================================================
// STUDENTS API
// ============================================================================

export async function getStudents(klausurId: string): Promise<StudentWork[]> {
  const data = await apiFetch<{ students: StudentWork[] }>(
    `/api/v1/klausuren/${klausurId}/students`
  )
  return data.students || []
}

export async function getStudent(studentId: string): Promise<StudentWork> {
  return apiFetch<StudentWork>(`/api/v1/students/${studentId}`)
}

export async function uploadStudentWork(
  klausurId: string,
  file: File,
  anonymId: string
): Promise<StudentWork> {
  const formData = new FormData()
  formData.append('file', file)
  formData.append('anonym_id', anonymId)

  const response = await fetch(
    `${getApiBase()}/api/v1/klausuren/${klausurId}/students`,
    {
      method: 'POST',
      body: formData,
    }
  )

  if (!response.ok) {
    const errorData = await response.json().catch(() => ({ detail: 'Upload failed' }))
    throw new Error(errorData.detail || `HTTP ${response.status}`)
  }

  return response.json()
}

export async function deleteStudent(studentId: string): Promise<void> {
  await apiFetch(`/api/v1/students/${studentId}`, { method: 'DELETE' })
}

// ============================================================================
// CRITERIA & GUTACHTEN API
// ============================================================================

export async function updateCriteria(
  studentId: string,
  criteria: CriteriaScores
): Promise<StudentWork> {
  return apiFetch<StudentWork>(`/api/v1/students/${studentId}/criteria`, {
    method: 'PUT',
    body: JSON.stringify({ criteria_scores: criteria }),
  })
}

export async function updateGutachten(
  studentId: string,
  gutachten: string
): Promise<StudentWork> {
  return apiFetch<StudentWork>(`/api/v1/students/${studentId}/gutachten`, {
    method: 'PUT',
    body: JSON.stringify({ gutachten }),
  })
}

export async function generateGutachten(
  studentId: string
): Promise<{ gutachten: string }> {
  return apiFetch<{ gutachten: string }>(
    `/api/v1/students/${studentId}/gutachten/generate`,
    { method: 'POST' }
  )
}

// ============================================================================
// ANNOTATIONS API
// ============================================================================

export async function getAnnotations(studentId: string): Promise<Annotation[]> {
  const data = await apiFetch<{ annotations: Annotation[] }>(
    `/api/v1/students/${studentId}/annotations`
  )
  return data.annotations || []
}

export async function createAnnotation(
  studentId: string,
  annotation: {
    page: number
    position: AnnotationPosition
    type: AnnotationType
    text: string
    severity?: 'minor' | 'major' | 'critical'
    suggestion?: string
    linked_criterion?: string
  }
): Promise<Annotation> {
  return apiFetch<Annotation>(`/api/v1/students/${studentId}/annotations`, {
    method: 'POST',
    body: JSON.stringify(annotation),
  })
}

export async function updateAnnotation(
  annotationId: string,
  updates: Partial<{
    text: string
    severity: 'minor' | 'major' | 'critical'
    suggestion: string
  }>
): Promise<Annotation> {
  return apiFetch<Annotation>(`/api/v1/annotations/${annotationId}`, {
    method: 'PUT',
    body: JSON.stringify(updates),
  })
}

export async function deleteAnnotation(annotationId: string): Promise<void> {
  await apiFetch(`/api/v1/annotations/${annotationId}`, { method: 'DELETE' })
}

// ============================================================================
// EH/RAG API (500+ NiBiS Dokumente)
// ============================================================================

export async function getEHSuggestions(
  studentId: string,
  criterion?: string
): Promise<EHSuggestion[]> {
  const data = await apiFetch<{ suggestions: EHSuggestion[] }>(
    `/api/v1/students/${studentId}/eh-suggestions`,
    {
      method: 'POST',
      body: JSON.stringify({ criterion }),
    }
  )
  return data.suggestions || []
}

export async function queryRAG(
  query: string,
  topK: number = 5
): Promise<{ results: Array<{ text: string; score: number; metadata: any }> }> {
  return apiFetch('/api/v1/eh/rag-query', {
    method: 'POST',
    body: JSON.stringify({ query, top_k: topK }),
  })
}

export async function uploadEH(file: File): Promise<{ id: string; name: string }> {
  const formData = new FormData()
  formData.append('file', file)

  const response = await fetch(
    `${getApiBase()}/api/v1/eh/upload`,
    {
      method: 'POST',
      body: formData,
    }
  )

  if (!response.ok) {
    const errorData = await response.json().catch(() => ({ detail: 'EH Upload failed' }))
    throw new Error(errorData.detail || `HTTP ${response.status}`)
  }

  return response.json()
}

// ============================================================================
// FAIRNESS & EXPORT API
// ============================================================================

export async function getFairnessAnalysis(
  klausurId: string
): Promise<FairnessAnalysis> {
  return apiFetch<FairnessAnalysis>(`/api/v1/klausuren/${klausurId}/fairness`)
}

export async function getGradeInfo(): Promise<GradeInfo> {
  return apiFetch<GradeInfo>('/api/v1/grade-info')
}

// Export endpoints return file downloads
export function getGutachtenExportUrl(studentId: string): string {
  return `${getApiBase()}/api/v1/students/${studentId}/export/gutachten`
}

export function getAnnotationsExportUrl(studentId: string): string {
  return `${getApiBase()}/api/v1/students/${studentId}/export/annotations`
}

export function getOverviewExportUrl(klausurId: string): string {
  return `${getApiBase()}/api/v1/klausuren/${klausurId}/export/overview`
}

export function getAllGutachtenExportUrl(klausurId: string): string {
  return `${getApiBase()}/api/v1/klausuren/${klausurId}/export/all-gutachten`
}

// Get student file URL (PDF/Image)
export function getStudentFileUrl(studentId: string): string {
  return `${getApiBase()}/api/v1/students/${studentId}/file`
}

// ============================================================================
// ARCHIV API (NiBiS Zentralabitur Documents)
// ============================================================================

export interface ArchivDokument {
  id: string
  title: string
  subject: string
  niveau: string
  year: number
  task_number?: number
  doc_type: string
  variant?: string
  bundesland: string
  minio_path?: string
  preview_url?: string
}

export interface ArchivSearchResponse {
  total: number
  documents: ArchivDokument[]
  filters: {
    subjects: string[]
    years: number[]
    niveaus: string[]
    doc_types: string[]
  }
}

export interface ArchivFilters {
  subject?: string
  year?: number
  bundesland?: string
  niveau?: string
  doc_type?: string
  search?: string
  limit?: number
  offset?: number
}

export async function getArchivDocuments(filters: ArchivFilters = {}): Promise<ArchivSearchResponse> {
  const params = new URLSearchParams()

  if (filters.subject && filters.subject !== 'Alle') params.append('subject', filters.subject)
  if (filters.year) params.append('year', filters.year.toString())
  if (filters.bundesland && filters.bundesland !== 'Alle') params.append('bundesland', filters.bundesland)
  if (filters.niveau && filters.niveau !== 'Alle') params.append('niveau', filters.niveau)
  if (filters.doc_type && filters.doc_type !== 'Alle') params.append('doc_type', filters.doc_type)
  if (filters.search) params.append('search', filters.search)
  if (filters.limit) params.append('limit', filters.limit.toString())
  if (filters.offset) params.append('offset', filters.offset.toString())

  const queryString = params.toString()
  const endpoint = `/api/v1/archiv${queryString ? `?${queryString}` : ''}`

  return apiFetch<ArchivSearchResponse>(endpoint)
}

export async function getArchivDocument(docId: string): Promise<ArchivDokument & { text_preview?: string }> {
  return apiFetch<ArchivDokument & { text_preview?: string }>(`/api/v1/archiv/${docId}`)
}

export async function getArchivDocumentUrl(docId: string, expires: number = 3600): Promise<{ url: string; expires_in: number; filename: string }> {
  return apiFetch<{ url: string; expires_in: number; filename: string }>(`/api/v1/archiv/${docId}/url?expires=${expires}`)
}

export async function searchArchivSemantic(
  query: string,
  options: { year?: number; subject?: string; niveau?: string; limit?: number } = {}
): Promise<Array<{
  id: string
  score: number
  text: string
  year: number
  subject: string
  niveau: string
  task_number?: number
  doc_type: string
}>> {
  const params = new URLSearchParams({ query })

  if (options.year) params.append('year', options.year.toString())
  if (options.subject) params.append('subject', options.subject)
  if (options.niveau) params.append('niveau', options.niveau)
  if (options.limit) params.append('limit', options.limit.toString())

  return apiFetch(`/api/v1/archiv/search/semantic?${params.toString()}`)
}

export async function getArchivSuggestions(query: string): Promise<Array<{ label: string; type: string }>> {
  return apiFetch<Array<{ label: string; type: string }>>(`/api/v1/archiv/suggest?query=${encodeURIComponent(query)}`)
}

export async function getArchivStats(): Promise<{
  total_documents: number
  total_chunks: number
  by_year: Record<string, number>
  by_subject: Record<string, number>
  by_niveau: Record<string, number>
}> {
  return apiFetch('/api/v1/archiv/stats')
}

// ============================================================================
// STATS API (for Dashboard)
// ============================================================================

export interface KorrekturStats {
  totalKlausuren: number
  totalStudents: number
  openCorrections: number
  completedThisWeek: number
  averageGrade: number
  timeSavedHours: number
}

export async function getKorrekturStats(): Promise<KorrekturStats> {
  try {
    const klausuren = await getKlausuren()

    let totalStudents = 0
    let openCorrections = 0
    let completedCount = 0
    let gradeSum = 0
    let gradedCount = 0

    for (const klausur of klausuren) {
      totalStudents += klausur.student_count || 0
      completedCount += klausur.completed_count || 0
      openCorrections += (klausur.student_count || 0) - (klausur.completed_count || 0)
    }

    // Get average from all klausuren
    for (const klausur of klausuren) {
      if (klausur.status === 'completed' || klausur.status === 'in_progress') {
        try {
          const fairness = await getFairnessAnalysis(klausur.id)
          if (fairness.average_grade > 0) {
            gradeSum += fairness.average_grade
            gradedCount++
          }
        } catch {
          // Skip if fairness analysis not available
        }
      }
    }

    const averageGrade = gradedCount > 0 ? gradeSum / gradedCount : 0
    // Estimate time saved: ~30 minutes per correction with AI assistance
    const timeSavedHours = Math.round(completedCount * 0.5)

    return {
      totalKlausuren: klausuren.length,
      totalStudents,
      openCorrections,
      completedThisWeek: completedCount, // Simplified, would need date filtering
      averageGrade: Math.round(averageGrade * 10) / 10,
      timeSavedHours,
    }
  } catch {
    return {
      totalKlausuren: 0,
      totalStudents: 0,
      openCorrections: 0,
      completedThisWeek: 0,
      averageGrade: 0,
      timeSavedHours: 0,
    }
  }
}

// Export all functions as a namespace
export const korrekturApi = {
  // Klausuren
  getKlausuren,
  getKlausur,
  createKlausur,
  deleteKlausur,

  // Students
  getStudents,
  getStudent,
  uploadStudentWork,
  deleteStudent,

  // Criteria & Gutachten
  updateCriteria,
  updateGutachten,
  generateGutachten,

  // Annotations
  getAnnotations,
  createAnnotation,
  updateAnnotation,
  deleteAnnotation,

  // EH/RAG
  getEHSuggestions,
  queryRAG,
  uploadEH,

  // Fairness & Export
  getFairnessAnalysis,
  getGradeInfo,
  getGutachtenExportUrl,
  getAnnotationsExportUrl,
  getOverviewExportUrl,
  getAllGutachtenExportUrl,
  getStudentFileUrl,

  // Archiv (NiBiS)
  getArchivDocuments,
  getArchivDocument,
  getArchivDocumentUrl,
  searchArchivSemantic,
  getArchivSuggestions,
  getArchivStats,

  // Stats
  getKorrekturStats,
}
