/**
 * Training Engine API Client
 * Communicates with the Go backend via Next.js API proxy at /api/sdk/v1/training/*
 */

import type {
  ModuleListResponse,
  AssignmentListResponse,
  MatrixResponse,
  AuditLogResponse,
  EscalationResponse,
  DeadlineListResponse,
  TrainingModule,
  TrainingAssignment,
  ModuleContent,
  QuizQuestion,
  QuizAttempt,
  QuizSubmitResponse,
  TrainingStats,
  TrainingMedia,
} from './types'

const BASE_URL = '/api/sdk/v1/training'

async function apiFetch<T>(path: string, options?: RequestInit): Promise<T> {
  const res = await fetch(`${BASE_URL}${path}`, {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      'X-Tenant-ID': typeof window !== 'undefined'
        ? (localStorage.getItem('bp-tenant-id') || 'default')
        : 'default',
      ...options?.headers,
    },
  })

  if (!res.ok) {
    const error = await res.json().catch(() => ({ error: res.statusText }))
    throw new Error(error.error || `API Error: ${res.status}`)
  }

  return res.json()
}

// =============================================================================
// MODULES
// =============================================================================

export async function getModules(filters?: {
  regulation_area?: string
  frequency_type?: string
  search?: string
}): Promise<ModuleListResponse> {
  const params = new URLSearchParams()
  if (filters?.regulation_area) params.set('regulation_area', filters.regulation_area)
  if (filters?.frequency_type) params.set('frequency_type', filters.frequency_type)
  if (filters?.search) params.set('search', filters.search)
  const qs = params.toString()
  return apiFetch<ModuleListResponse>(`/modules${qs ? `?${qs}` : ''}`)
}

export async function getModule(id: string): Promise<{
  module: TrainingModule
  content: ModuleContent | null
  questions: QuizQuestion[]
}> {
  return apiFetch(`/modules/${id}`)
}

export async function createModule(data: {
  module_code: string
  title: string
  description?: string
  regulation_area: string
  frequency_type: string
  duration_minutes?: number
  pass_threshold?: number
}): Promise<TrainingModule> {
  return apiFetch<TrainingModule>('/modules', {
    method: 'POST',
    body: JSON.stringify(data),
  })
}

export async function updateModule(id: string, data: Record<string, unknown>): Promise<TrainingModule> {
  return apiFetch<TrainingModule>(`/modules/${id}`, {
    method: 'PUT',
    body: JSON.stringify(data),
  })
}

export async function deleteModule(id: string): Promise<void> {
  return apiFetch(`/modules/${id}`, { method: 'DELETE' })
}

// =============================================================================
// MATRIX
// =============================================================================

export async function getMatrix(): Promise<MatrixResponse> {
  return apiFetch<MatrixResponse>('/matrix')
}

export async function getMatrixForRole(role: string): Promise<{
  role: string
  label: string
  entries: Array<{ module_id: string; module_code: string; module_title: string; is_mandatory: boolean; priority: number }>
  total: number
}> {
  return apiFetch(`/matrix/${role}`)
}

export async function setMatrixEntry(data: {
  role_code: string
  module_id: string
  is_mandatory: boolean
  priority: number
}): Promise<unknown> {
  return apiFetch('/matrix', {
    method: 'POST',
    body: JSON.stringify(data),
  })
}

export async function deleteMatrixEntry(role: string, moduleId: string): Promise<unknown> {
  return apiFetch(`/matrix/${role}/${moduleId}`, { method: 'DELETE' })
}

// =============================================================================
// ASSIGNMENTS
// =============================================================================

export async function computeAssignments(data: {
  user_id: string
  user_name: string
  user_email: string
  roles: string[]
  trigger?: string
}): Promise<{ assignments: TrainingAssignment[]; created: number }> {
  return apiFetch('/assignments/compute', {
    method: 'POST',
    body: JSON.stringify(data),
  })
}

export async function getAssignments(filters?: {
  user_id?: string
  module_id?: string
  role?: string
  status?: string
  limit?: number
  offset?: number
}): Promise<AssignmentListResponse> {
  const params = new URLSearchParams()
  if (filters?.user_id) params.set('user_id', filters.user_id)
  if (filters?.module_id) params.set('module_id', filters.module_id)
  if (filters?.role) params.set('role', filters.role)
  if (filters?.status) params.set('status', filters.status)
  if (filters?.limit) params.set('limit', String(filters.limit))
  if (filters?.offset) params.set('offset', String(filters.offset))
  const qs = params.toString()
  return apiFetch<AssignmentListResponse>(`/assignments${qs ? `?${qs}` : ''}`)
}

export async function getAssignment(id: string): Promise<TrainingAssignment> {
  return apiFetch<TrainingAssignment>(`/assignments/${id}`)
}

export async function startAssignment(id: string): Promise<{ status: string }> {
  return apiFetch(`/assignments/${id}/start`, { method: 'POST' })
}

export async function updateAssignmentProgress(id: string, progress: number): Promise<{ status: string; progress: number }> {
  return apiFetch(`/assignments/${id}/progress`, {
    method: 'POST',
    body: JSON.stringify({ progress }),
  })
}

export async function completeAssignment(id: string): Promise<{ status: string }> {
  return apiFetch(`/assignments/${id}/complete`, { method: 'POST' })
}

export async function updateAssignment(id: string, data: { deadline?: string }): Promise<TrainingAssignment> {
  return apiFetch<TrainingAssignment>(`/assignments/${id}`, {
    method: 'PUT',
    body: JSON.stringify(data),
  })
}

// =============================================================================
// QUIZ
// =============================================================================

export async function getQuiz(moduleId: string): Promise<{ questions: QuizQuestion[]; total: number }> {
  return apiFetch(`/quiz/${moduleId}`)
}

export async function submitQuiz(moduleId: string, data: {
  assignment_id: string
  answers: Array<{ question_id: string; selected_index: number }>
  duration_seconds?: number
}): Promise<QuizSubmitResponse> {
  return apiFetch<QuizSubmitResponse>(`/quiz/${moduleId}/submit`, {
    method: 'POST',
    body: JSON.stringify(data),
  })
}

export async function getQuizAttempts(assignmentId: string): Promise<{ attempts: QuizAttempt[]; total: number }> {
  return apiFetch(`/quiz/attempts/${assignmentId}`)
}

// =============================================================================
// CONTENT GENERATION
// =============================================================================

export async function generateContent(moduleId: string, language?: string): Promise<ModuleContent> {
  return apiFetch<ModuleContent>('/content/generate', {
    method: 'POST',
    body: JSON.stringify({ module_id: moduleId, language: language || 'de' }),
  })
}

export async function generateQuiz(moduleId: string, count?: number): Promise<{ questions: QuizQuestion[]; total: number }> {
  return apiFetch('/content/generate-quiz', {
    method: 'POST',
    body: JSON.stringify({ module_id: moduleId, count: count || 5 }),
  })
}

export async function getContent(moduleId: string): Promise<ModuleContent> {
  return apiFetch<ModuleContent>(`/content/${moduleId}`)
}

export async function publishContent(contentId: string): Promise<{ status: string }> {
  return apiFetch(`/content/${contentId}/publish`, { method: 'POST' })
}

// =============================================================================
// DEADLINES & ESCALATION
// =============================================================================

export async function getDeadlines(limit?: number): Promise<DeadlineListResponse> {
  const qs = limit ? `?limit=${limit}` : ''
  return apiFetch<DeadlineListResponse>(`/deadlines${qs}`)
}

export async function getOverdueDeadlines(): Promise<DeadlineListResponse> {
  return apiFetch<DeadlineListResponse>('/deadlines/overdue')
}

export async function checkEscalation(): Promise<EscalationResponse> {
  return apiFetch<EscalationResponse>('/escalation/check', { method: 'POST' })
}

// =============================================================================
// AUDIT & STATS
// =============================================================================

export async function getAuditLog(filters?: {
  action?: string
  entity_type?: string
  limit?: number
  offset?: number
}): Promise<AuditLogResponse> {
  const params = new URLSearchParams()
  if (filters?.action) params.set('action', filters.action)
  if (filters?.entity_type) params.set('entity_type', filters.entity_type)
  if (filters?.limit) params.set('limit', String(filters.limit))
  if (filters?.offset) params.set('offset', String(filters.offset))
  const qs = params.toString()
  return apiFetch<AuditLogResponse>(`/audit-log${qs ? `?${qs}` : ''}`)
}

export async function getStats(): Promise<TrainingStats> {
  return apiFetch<TrainingStats>('/stats')
}

// =============================================================================
// BULK GENERATION
// =============================================================================

export async function generateAllContent(language?: string): Promise<{ generated: number; skipped: number; errors: string[] }> {
  const qs = language ? `?language=${language}` : ''
  return apiFetch(`/content/generate-all${qs}`, { method: 'POST' })
}

export async function generateAllQuizzes(): Promise<{ generated: number; skipped: number; errors: string[] }> {
  return apiFetch('/content/generate-all-quiz', { method: 'POST' })
}

// =============================================================================
// MEDIA (Audio/Video)
// =============================================================================

export async function generateAudio(moduleId: string): Promise<TrainingMedia> {
  return apiFetch<TrainingMedia>(`/content/${moduleId}/generate-audio`, { method: 'POST' })
}

export async function getModuleMedia(moduleId: string): Promise<{ media: TrainingMedia[]; total: number }> {
  return apiFetch(`/media/module/${moduleId}`)
}

export async function getMediaURL(mediaId: string): Promise<{ bucket: string; object_key: string; mime_type: string }> {
  return apiFetch(`/media/${mediaId}/url`)
}

export async function publishMedia(mediaId: string, publish?: boolean): Promise<{ status: string; is_published: boolean }> {
  return apiFetch(`/media/${mediaId}/publish`, {
    method: 'POST',
    body: JSON.stringify({ publish: publish !== false }),
  })
}

export async function generateVideo(moduleId: string): Promise<TrainingMedia> {
  return apiFetch<TrainingMedia>(`/content/${moduleId}/generate-video`, { method: 'POST' })
}

export async function previewVideoScript(moduleId: string): Promise<{ title: string; sections: Array<{ heading: string; text: string; bullet_points: string[] }> }> {
  return apiFetch(`/content/${moduleId}/preview-script`, { method: 'POST' })
}

// =============================================================================
// TRAINING BLOCKS (Controls → Schulungsmodule)
// =============================================================================

import type {
  TrainingBlockConfig,
  CanonicalControlSummary,
  CanonicalControlMeta,
  BlockPreview,
  BlockGenerateResult,
  TrainingBlockControlLink,
} from './types'

export async function listBlockConfigs(): Promise<{ blocks: TrainingBlockConfig[]; total: number }> {
  return apiFetch('/blocks')
}

export async function createBlockConfig(data: {
  name: string
  description?: string
  domain_filter?: string
  category_filter?: string
  severity_filter?: string
  target_audience_filter?: string
  regulation_area: string
  module_code_prefix: string
  frequency_type?: string
  duration_minutes?: number
  pass_threshold?: number
  max_controls_per_module?: number
}): Promise<TrainingBlockConfig> {
  return apiFetch<TrainingBlockConfig>('/blocks', {
    method: 'POST',
    body: JSON.stringify(data),
  })
}

export async function getBlockConfig(id: string): Promise<TrainingBlockConfig> {
  return apiFetch<TrainingBlockConfig>(`/blocks/${id}`)
}

export async function updateBlockConfig(id: string, data: Record<string, unknown>): Promise<TrainingBlockConfig> {
  return apiFetch<TrainingBlockConfig>(`/blocks/${id}`, {
    method: 'PUT',
    body: JSON.stringify(data),
  })
}

export async function deleteBlockConfig(id: string): Promise<void> {
  return apiFetch(`/blocks/${id}`, { method: 'DELETE' })
}

export async function previewBlock(id: string): Promise<BlockPreview> {
  return apiFetch<BlockPreview>(`/blocks/${id}/preview`, { method: 'POST' })
}

export async function generateBlock(id: string, data?: {
  language?: string
  auto_matrix?: boolean
}): Promise<BlockGenerateResult> {
  return apiFetch<BlockGenerateResult>(`/blocks/${id}/generate`, {
    method: 'POST',
    body: JSON.stringify(data || { language: 'de', auto_matrix: true }),
  })
}

export async function getBlockControls(id: string): Promise<{ controls: TrainingBlockControlLink[]; total: number }> {
  return apiFetch(`/blocks/${id}/controls`)
}

export async function listCanonicalControls(filters?: {
  domain?: string
  category?: string
  severity?: string
  target_audience?: string
}): Promise<{ controls: CanonicalControlSummary[]; total: number }> {
  const params = new URLSearchParams()
  if (filters?.domain) params.set('domain', filters.domain)
  if (filters?.category) params.set('category', filters.category)
  if (filters?.severity) params.set('severity', filters.severity)
  if (filters?.target_audience) params.set('target_audience', filters.target_audience)
  const qs = params.toString()
  return apiFetch(`/canonical/controls${qs ? `?${qs}` : ''}`)
}

export async function getCanonicalMeta(): Promise<CanonicalControlMeta> {
  return apiFetch<CanonicalControlMeta>('/canonical/meta')
}

// =============================================================================
// CERTIFICATES
// =============================================================================

export async function generateCertificate(assignmentId: string): Promise<{ certificate_id: string; assignment: TrainingAssignment }> {
  return apiFetch(`/certificates/generate/${assignmentId}`, { method: 'POST' })
}

export async function listCertificates(): Promise<{ certificates: TrainingAssignment[]; total: number }> {
  return apiFetch('/certificates')
}

export async function downloadCertificatePDF(certificateId: string): Promise<Blob> {
  const res = await fetch(`${BASE_URL}/certificates/${certificateId}/pdf`, {
    headers: {
      'X-Tenant-ID': typeof window !== 'undefined'
        ? (localStorage.getItem('bp-tenant-id') || 'default')
        : 'default',
    },
  })
  if (!res.ok) throw new Error(`PDF download failed: ${res.status}`)
  return res.blob()
}

export async function verifyCertificate(certificateId: string): Promise<{ valid: boolean; assignment: TrainingAssignment }> {
  return apiFetch(`/certificates/${certificateId}/verify`)
}

// =============================================================================
// MEDIA STREAMING
// =============================================================================

export function getMediaStreamURL(mediaId: string): string {
  return `${BASE_URL}/media/${mediaId}/stream`
}

// =============================================================================
// INTERACTIVE VIDEO
// =============================================================================

import type {
  InteractiveVideoManifest,
  CheckpointQuizResult,
  CheckpointProgress,
} from './types'

export async function generateInteractiveVideo(moduleId: string): Promise<TrainingMedia> {
  return apiFetch<TrainingMedia>(`/content/${moduleId}/generate-interactive`, { method: 'POST' })
}

export async function getInteractiveManifest(moduleId: string, assignmentId?: string): Promise<InteractiveVideoManifest> {
  const qs = assignmentId ? `?assignment_id=${assignmentId}` : ''
  return apiFetch<InteractiveVideoManifest>(`/content/${moduleId}/interactive-manifest${qs}`)
}

export async function submitCheckpointQuiz(checkpointId: string, assignmentId: string, answers: number[]): Promise<CheckpointQuizResult> {
  return apiFetch<CheckpointQuizResult>(`/checkpoints/${checkpointId}/submit`, {
    method: 'POST',
    body: JSON.stringify({ assignment_id: assignmentId, answers }),
  })
}

export async function getCheckpointProgress(assignmentId: string): Promise<{ progress: CheckpointProgress[]; total: number }> {
  return apiFetch(`/checkpoints/progress/${assignmentId}`)
}
