// API Types
export interface StudentKlausur {
  id: string
  klausur_id: string
  student_name: string
  student_id: string | null
  file_path: string | null
  ocr_text: string | null
  status: string
  criteria_scores: Record<string, { score: number; annotations: string[] }>
  gutachten: {
    einleitung: string
    hauptteil: string
    fazit: string
    staerken: string[]
    schwaechen: string[]
  } | null
  raw_points: number
  grade_points: number
  created_at: string
}

export interface Klausur {
  id: string
  title: string
  subject: string
  modus: 'landes_abitur' | 'vorabitur'
  class_id: string | null
  year: number
  semester: string
  erwartungshorizont: Record<string, unknown> | null
  student_count: number
  students: StudentKlausur[]
  created_at: string
  teacher_id: string
}

export interface GradeInfo {
  thresholds: Record<number, number>
  labels: Record<number, string>
  criteria: Record<string, { weight: number; label: string }>
}

// Get auth token from parent window or localStorage
function getAuthToken(): string | null {
  // Try to get from parent window (iframe scenario)
  try {
    if (window.parent !== window) {
      const parentToken = (window.parent as unknown as { authToken?: string }).authToken
      if (parentToken) return parentToken
    }
  } catch {
    // Cross-origin access denied
  }

  // Try localStorage
  return localStorage.getItem('auth_token')
}

// Base API call
async function apiCall<T>(
  endpoint: string,
  options: RequestInit = {}
): Promise<T> {
  const token = getAuthToken()

  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
    ...(options.headers as Record<string, string> || {})
  }

  if (token) {
    headers['Authorization'] = `Bearer ${token}`
  }

  const response = await fetch(`/api/v1${endpoint}`, {
    ...options,
    headers
  })

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

  return response.json()
}

// Klausuren API
export const klausurApi = {
  listKlausuren: (): Promise<Klausur[]> =>
    apiCall('/klausuren'),

  getKlausur: (id: string): Promise<Klausur> =>
    apiCall(`/klausuren/${id}`),

  createKlausur: (data: Partial<Klausur>): Promise<Klausur> =>
    apiCall('/klausuren', {
      method: 'POST',
      body: JSON.stringify(data)
    }),

  updateKlausur: (id: string, data: Partial<Klausur>): Promise<Klausur> =>
    apiCall(`/klausuren/${id}`, {
      method: 'PUT',
      body: JSON.stringify(data)
    }),

  deleteKlausur: (id: string): Promise<{ success: boolean }> =>
    apiCall(`/klausuren/${id}`, { method: 'DELETE' }),

  // Students
  listStudents: (klausurId: string): Promise<StudentKlausur[]> =>
    apiCall(`/klausuren/${klausurId}/students`),

  deleteStudent: (studentId: string): Promise<{ success: boolean }> =>
    apiCall(`/students/${studentId}`, { method: 'DELETE' }),

  // Grading
  updateCriteria: (
    studentId: string,
    criterion: string,
    score: number,
    annotations?: string[]
  ): Promise<StudentKlausur> =>
    apiCall(`/students/${studentId}/criteria`, {
      method: 'PUT',
      body: JSON.stringify({ criterion, score, annotations })
    }),

  updateGutachten: (
    studentId: string,
    gutachten: {
      einleitung: string
      hauptteil: string
      fazit: string
      staerken?: string[]
      schwaechen?: string[]
    }
  ): Promise<StudentKlausur> =>
    apiCall(`/students/${studentId}/gutachten`, {
      method: 'PUT',
      body: JSON.stringify(gutachten)
    }),

  finalizeStudent: (studentId: string): Promise<StudentKlausur> =>
    apiCall(`/students/${studentId}/finalize`, { method: 'POST' }),

  // KI-Gutachten Generation
  generateGutachten: (
    studentId: string,
    options: {
      include_strengths?: boolean
      include_weaknesses?: boolean
      tone?: 'formal' | 'friendly' | 'constructive'
    } = {}
  ): Promise<{
    einleitung: string
    hauptteil: string
    fazit: string
    staerken: string[]
    schwaechen: string[]
    generated_at: string
    is_ki_generated: boolean
    tone: string
  }> =>
    apiCall(`/students/${studentId}/gutachten/generate`, {
      method: 'POST',
      body: JSON.stringify({
        include_strengths: options.include_strengths ?? true,
        include_weaknesses: options.include_weaknesses ?? true,
        tone: options.tone ?? 'formal'
      })
    }),

  // Fairness Analysis
  getFairnessAnalysis: (klausurId: string): Promise<{
    klausur_id: string
    students_count: number
    graded_count: number
    statistics: {
      average_grade: number
      average_raw_points: number
      min_grade: number
      max_grade: number
      spread: number
      standard_deviation: number
    }
    criteria_breakdown: Record<string, { average: number; min: number; max: number; count: number }>
    outliers: Array<{
      student_id: string
      student_name: string
      grade_points: number
      deviation: number
      direction: 'above' | 'below'
    }>
    fairness_score: number
    warnings: string[]
    recommendation: string
  }> =>
    apiCall(`/klausuren/${klausurId}/fairness`),

  // Audit Log
  getStudentAuditLog: (studentId: string): Promise<Array<{
    id: string
    timestamp: string
    user_id: string
    action: string
    entity_type: string
    entity_id: string
    field: string | null
    old_value: string | null
    new_value: string | null
    details: Record<string, unknown> | null
  }>> =>
    apiCall(`/students/${studentId}/audit-log`),

  // Utilities
  getGradeInfo: (): Promise<GradeInfo> =>
    apiCall('/grade-info')
}

// File upload (special handling for multipart)
export async function uploadStudentWork(
  klausurId: string,
  studentName: string,
  file: File
): Promise<StudentKlausur> {
  const token = getAuthToken()

  const formData = new FormData()
  formData.append('file', file)
  formData.append('student_name', studentName)

  const headers: Record<string, string> = {}
  if (token) {
    headers['Authorization'] = `Bearer ${token}`
  }

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

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

  return response.json()
}

// =============================================
// BYOEH (Erwartungshorizont) Types & API
// =============================================

export interface Erwartungshorizont {
  id: string
  tenant_id: string
  teacher_id: string
  title: string
  subject: string
  niveau: 'eA' | 'gA'
  year: number
  aufgaben_nummer: string | null
  status: 'pending_rights' | 'processing' | 'indexed' | 'error'
  chunk_count: number
  rights_confirmed: boolean
  rights_confirmed_at: string | null
  indexed_at: string | null
  file_size_bytes: number
  original_filename: string
  training_allowed: boolean
  created_at: string
  deleted_at: string | null
}

export interface EHRAGResult {
  context: string
  sources: Array<{
    text: string
    eh_id: string
    eh_title: string
    chunk_index: number
    score: number
    reranked?: boolean
  }>
  query: string
  search_info?: {
    retrieval_time_ms?: number
    rerank_time_ms?: number
    total_time_ms?: number
    reranked?: boolean
    rerank_applied?: boolean
    hybrid_search_applied?: boolean
    embedding_model?: string
    total_candidates?: number
    original_count?: number
  }
}

export interface EHAuditEntry {
  id: string
  eh_id: string | null
  tenant_id: string
  user_id: string
  action: string
  details: Record<string, unknown> | null
  created_at: string
}

export interface EHKeyShare {
  id: string
  eh_id: string
  user_id: string
  passphrase_hint: string
  granted_by: string
  granted_at: string
  role: 'second_examiner' | 'third_examiner' | 'supervisor' | 'department_head'
  klausur_id: string | null
  active: boolean
}

export interface EHKlausurLink {
  id: string
  eh_id: string
  klausur_id: string
  linked_by: string
  linked_at: string
}

export interface SharedEHInfo {
  eh: Erwartungshorizont
  share: EHKeyShare
}

export interface LinkedEHInfo {
  eh: Erwartungshorizont
  link: EHKlausurLink
  is_owner: boolean
  share: EHKeyShare | null
}

// Invitation types for Invite/Accept/Revoke flow
export interface EHShareInvitation {
  id: string
  eh_id: string
  inviter_id: string
  invitee_id: string
  invitee_email: string
  role: 'second_examiner' | 'third_examiner' | 'supervisor' | 'department_head' | 'fachvorsitz'
  klausur_id: string | null
  message: string | null
  status: 'pending' | 'accepted' | 'declined' | 'expired' | 'revoked'
  expires_at: string
  created_at: string
  accepted_at: string | null
  declined_at: string | null
}

export interface PendingInvitationInfo {
  invitation: EHShareInvitation
  eh: {
    id: string
    title: string
    subject: string
    niveau: string
    year: number
  } | null
}

export interface SentInvitationInfo {
  invitation: EHShareInvitation
  eh: {
    id: string
    title: string
    subject: string
  } | null
}

export interface EHAccessChain {
  eh_id: string
  eh_title: string
  owner: {
    user_id: string
    role: string
  }
  active_shares: EHKeyShare[]
  pending_invitations: EHShareInvitation[]
  revoked_shares: EHKeyShare[]
}

// Erwartungshorizont API
export const ehApi = {
  // List all EH for current teacher
  listEH: (params?: { subject?: string; year?: number }): Promise<Erwartungshorizont[]> => {
    const query = new URLSearchParams()
    if (params?.subject) query.append('subject', params.subject)
    if (params?.year) query.append('year', params.year.toString())
    const queryStr = query.toString()
    return apiCall(`/eh${queryStr ? `?${queryStr}` : ''}`)
  },

  // Get single EH by ID
  getEH: (id: string): Promise<Erwartungshorizont> =>
    apiCall(`/eh/${id}`),

  // Upload encrypted EH (special handling for FormData)
  uploadEH: async (formData: FormData): Promise<Erwartungshorizont> => {
    const token = getAuthToken()
    const headers: Record<string, string> = {}
    if (token) {
      headers['Authorization'] = `Bearer ${token}`
    }

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

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

    return response.json()
  },

  // Delete EH (soft delete)
  deleteEH: (id: string): Promise<{ status: string; id: string }> =>
    apiCall(`/eh/${id}`, { method: 'DELETE' }),

  // Index EH for RAG (requires passphrase)
  indexEH: (id: string, passphrase: string): Promise<{ status: string; id: string; chunk_count: number }> =>
    apiCall(`/eh/${id}/index`, {
      method: 'POST',
      body: JSON.stringify({ passphrase })
    }),

  // RAG query against EH
  ragQuery: (params: {
    query_text: string
    passphrase: string
    subject?: string
    limit?: number
    rerank?: boolean
  }): Promise<EHRAGResult> =>
    apiCall('/eh/rag-query', {
      method: 'POST',
      body: JSON.stringify({
        query_text: params.query_text,
        passphrase: params.passphrase,
        subject: params.subject,
        limit: params.limit ?? 5,
        rerank: params.rerank ?? false
      })
    }),

  // Get audit log
  getAuditLog: (ehId?: string, limit?: number): Promise<EHAuditEntry[]> => {
    const query = new URLSearchParams()
    if (ehId) query.append('eh_id', ehId)
    if (limit) query.append('limit', limit.toString())
    const queryStr = query.toString()
    return apiCall(`/eh/audit-log${queryStr ? `?${queryStr}` : ''}`)
  },

  // Get rights confirmation text
  getRightsText: (): Promise<{ text: string; version: string }> =>
    apiCall('/eh/rights-text'),

  // Get Qdrant status (admin only)
  getQdrantStatus: (): Promise<{
    name: string
    vectors_count: number
    points_count: number
    status: string
  }> =>
    apiCall('/eh/qdrant-status'),

  // =============================================
  // KEY SHARING
  // =============================================

  // Share EH with another examiner
  shareEH: (
    ehId: string,
    params: {
      user_id: string
      role: 'second_examiner' | 'third_examiner' | 'supervisor' | 'department_head'
      encrypted_passphrase: string
      passphrase_hint?: string
      klausur_id?: string
    }
  ): Promise<{
    status: string
    share_id: string
    eh_id: string
    shared_with: string
    role: string
  }> =>
    apiCall(`/eh/${ehId}/share`, {
      method: 'POST',
      body: JSON.stringify(params)
    }),

  // List shares for an EH (owner only)
  listShares: (ehId: string): Promise<EHKeyShare[]> =>
    apiCall(`/eh/${ehId}/shares`),

  // Revoke a share
  revokeShare: (ehId: string, shareId: string): Promise<{ status: string; share_id: string }> =>
    apiCall(`/eh/${ehId}/shares/${shareId}`, { method: 'DELETE' }),

  // Get EH shared with current user
  getSharedWithMe: (): Promise<SharedEHInfo[]> =>
    apiCall('/eh/shared-with-me'),

  // Link EH to a Klausur
  linkToKlausur: (ehId: string, klausurId: string): Promise<{
    status: string
    link_id: string
    eh_id: string
    klausur_id: string
  }> =>
    apiCall(`/eh/${ehId}/link-klausur`, {
      method: 'POST',
      body: JSON.stringify({ klausur_id: klausurId })
    }),

  // Unlink EH from a Klausur
  unlinkFromKlausur: (ehId: string, klausurId: string): Promise<{
    status: string
    eh_id: string
    klausur_id: string
  }> =>
    apiCall(`/eh/${ehId}/link-klausur/${klausurId}`, { method: 'DELETE' }),

  // =============================================
  // INVITATION FLOW (Invite / Accept / Revoke)
  // =============================================

  // Send invitation to share EH
  inviteToEH: (
    ehId: string,
    params: {
      invitee_email: string
      invitee_id?: string
      role: 'second_examiner' | 'third_examiner' | 'supervisor' | 'department_head' | 'fachvorsitz'
      klausur_id?: string
      message?: string
      expires_in_days?: number
    }
  ): Promise<{
    status: string
    invitation_id: string
    eh_id: string
    invitee_email: string
    role: string
    expires_at: string
    eh_title: string
  }> =>
    apiCall(`/eh/${ehId}/invite`, {
      method: 'POST',
      body: JSON.stringify(params)
    }),

  // Get pending invitations for current user
  getPendingInvitations: (): Promise<PendingInvitationInfo[]> =>
    apiCall('/eh/invitations/pending'),

  // Get sent invitations (as inviter)
  getSentInvitations: (): Promise<SentInvitationInfo[]> =>
    apiCall('/eh/invitations/sent'),

  // Accept an invitation
  acceptInvitation: (
    invitationId: string,
    encryptedPassphrase: string
  ): Promise<{
    status: string
    share_id: string
    eh_id: string
    role: string
    klausur_id: string | null
  }> =>
    apiCall(`/eh/invitations/${invitationId}/accept`, {
      method: 'POST',
      body: JSON.stringify({ encrypted_passphrase: encryptedPassphrase })
    }),

  // Decline an invitation
  declineInvitation: (invitationId: string): Promise<{
    status: string
    invitation_id: string
    eh_id: string
  }> =>
    apiCall(`/eh/invitations/${invitationId}/decline`, { method: 'POST' }),

  // Revoke an invitation (as inviter)
  revokeInvitation: (invitationId: string): Promise<{
    status: string
    invitation_id: string
    eh_id: string
  }> =>
    apiCall(`/eh/invitations/${invitationId}`, { method: 'DELETE' }),

  // Get the complete access chain for an EH
  getAccessChain: (ehId: string): Promise<EHAccessChain> =>
    apiCall(`/eh/${ehId}/access-chain`)
}

// Get linked EH for a Klausur (separate from ehApi for clarity)
export const klausurEHApi = {
  // Get all EH linked to a Klausur that the user has access to
  getLinkedEH: (klausurId: string): Promise<LinkedEHInfo[]> =>
    apiCall(`/klausuren/${klausurId}/linked-eh`)
}
