/**
 * Academy API Client — Course, Enrollment, Certificate, Quiz, Statistics, Generation
 *
 * API client for the Compliance E-Learning Academy module
 * Connects to the ai-compliance-sdk backend via Next.js proxy
 */

import type {
  Course,
  CourseCategory,
  CourseCreateRequest,
  CourseUpdateRequest,
  GenerateCourseRequest,
  Enrollment,
  EnrollmentStatus,
  EnrollmentListResponse,
  EnrollUserRequest,
  UpdateProgressRequest,
  Certificate,
  AcademyStatistics,
  LessonType,
  SubmitQuizRequest,
  SubmitQuizResponse,
} from './types'

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

const ACADEMY_API_BASE = '/api/sdk/v1/academy'
const API_TIMEOUT = 30000

// =============================================================================
// HELPER FUNCTIONS
// =============================================================================

function getTenantId(): string {
  if (typeof window !== 'undefined') {
    return localStorage.getItem('bp_tenant_id') || 'default-tenant'
  }
  return 'default-tenant'
}

function getAuthHeaders(): HeadersInit {
  const headers: HeadersInit = {
    'Content-Type': 'application/json',
    'X-Tenant-ID': getTenantId()
  }

  if (typeof window !== 'undefined') {
    const token = localStorage.getItem('authToken')
    if (token) {
      headers['Authorization'] = `Bearer ${token}`
    }
    const userId = localStorage.getItem('bp_user_id')
    if (userId) {
      headers['X-User-ID'] = userId
    }
  }

  return headers
}

async function fetchWithTimeout<T>(
  url: string,
  options: RequestInit = {},
  timeout: number = API_TIMEOUT
): Promise<T> {
  const controller = new AbortController()
  const timeoutId = setTimeout(() => controller.abort(), timeout)

  try {
    const response = await fetch(url, {
      ...options,
      signal: controller.signal,
      headers: {
        ...getAuthHeaders(),
        ...options.headers
      }
    })

    if (!response.ok) {
      const errorBody = await response.text()
      let errorMessage = `HTTP ${response.status}: ${response.statusText}`
      try {
        const errorJson = JSON.parse(errorBody)
        errorMessage = errorJson.error || errorJson.message || errorMessage
      } catch {
        // Keep the HTTP status message
      }
      throw new Error(errorMessage)
    }

    const contentType = response.headers.get('content-type')
    if (contentType && contentType.includes('application/json')) {
      return response.json()
    }

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

// =============================================================================
// BACKEND TYPES
// =============================================================================

interface BackendCourse {
  id: string
  title: string
  description: string
  category: CourseCategory
  duration_minutes: number
  required_for_roles: string[]
  is_active: boolean
  passing_score?: number
  status?: string
  lessons?: BackendLesson[]
  created_at: string
  updated_at: string
}

interface BackendQuizQuestion {
  id: string
  question: string
  options: string[]
  correct_index: number
  explanation: string
}

interface BackendLesson {
  id: string
  course_id: string
  title: string
  description?: string
  lesson_type: LessonType
  content_url?: string
  duration_minutes: number
  order_index: number
  quiz_questions?: BackendQuizQuestion[]
}

function mapCourseFromBackend(bc: BackendCourse): Course {
  return {
    id: bc.id,
    title: bc.title,
    description: bc.description || '',
    category: bc.category,
    durationMinutes: bc.duration_minutes || 0,
    passingScore: bc.passing_score ?? 70,
    isActive: bc.is_active ?? true,
    status: (bc.status as 'draft' | 'published') ?? 'draft',
    requiredForRoles: bc.required_for_roles || [],
    lessons: (bc.lessons || []).map(l => ({
      id: l.id,
      courseId: l.course_id,
      title: l.title,
      type: l.lesson_type,
      contentMarkdown: l.content_url || '',
      durationMinutes: l.duration_minutes || 0,
      order: l.order_index,
      quizQuestions: (l.quiz_questions || []).map(q => ({
        id: q.id || `q-${Math.random().toString(36).slice(2)}`,
        lessonId: l.id,
        question: q.question,
        options: q.options,
        correctOptionIndex: q.correct_index,
        explanation: q.explanation,
      })),
    })),
    createdAt: bc.created_at,
    updatedAt: bc.updated_at,
  }
}

function mapCoursesFromBackend(courses: BackendCourse[]): Course[] {
  return courses.map(mapCourseFromBackend)
}

// =============================================================================
// COURSE CRUD
// =============================================================================

export async function fetchCourses(): Promise<Course[]> {
  const res = await fetchWithTimeout<{ courses: BackendCourse[]; total: number }>(
    `${ACADEMY_API_BASE}/courses`
  )
  return mapCoursesFromBackend(res.courses || [])
}

export async function fetchCourse(id: string): Promise<Course> {
  const res = await fetchWithTimeout<{ course: BackendCourse }>(
    `${ACADEMY_API_BASE}/courses/${id}`
  )
  return mapCourseFromBackend(res.course)
}

export async function createCourse(request: CourseCreateRequest): Promise<Course> {
  return fetchWithTimeout<Course>(
    `${ACADEMY_API_BASE}/courses`,
    { method: 'POST', body: JSON.stringify(request) }
  )
}

export async function updateCourse(id: string, update: CourseUpdateRequest): Promise<Course> {
  return fetchWithTimeout<Course>(
    `${ACADEMY_API_BASE}/courses/${id}`,
    { method: 'PUT', body: JSON.stringify(update) }
  )
}

export async function deleteCourse(id: string): Promise<void> {
  await fetchWithTimeout<void>(
    `${ACADEMY_API_BASE}/courses/${id}`,
    { method: 'DELETE' }
  )
}

// =============================================================================
// ENROLLMENTS
// =============================================================================

export async function fetchEnrollments(courseId?: string): Promise<Enrollment[]> {
  const params = new URLSearchParams()
  if (courseId) {
    params.set('course_id', courseId)
  }
  const queryString = params.toString()
  const url = `${ACADEMY_API_BASE}/enrollments${queryString ? `?${queryString}` : ''}`

  const res = await fetchWithTimeout<{ enrollments: Enrollment[]; total: number }>(url)
  return res.enrollments || []
}

export async function enrollUser(request: EnrollUserRequest): Promise<Enrollment> {
  return fetchWithTimeout<Enrollment>(
    `${ACADEMY_API_BASE}/enrollments`,
    { method: 'POST', body: JSON.stringify(request) }
  )
}

export async function updateProgress(enrollmentId: string, update: UpdateProgressRequest): Promise<Enrollment> {
  return fetchWithTimeout<Enrollment>(
    `${ACADEMY_API_BASE}/enrollments/${enrollmentId}/progress`,
    { method: 'PUT', body: JSON.stringify(update) }
  )
}

export async function completeEnrollment(enrollmentId: string): Promise<Enrollment> {
  return fetchWithTimeout<Enrollment>(
    `${ACADEMY_API_BASE}/enrollments/${enrollmentId}/complete`,
    { method: 'POST' }
  )
}

export async function deleteEnrollment(id: string): Promise<void> {
  await fetchWithTimeout<void>(
    `${ACADEMY_API_BASE}/enrollments/${id}`,
    { method: 'DELETE' }
  )
}

export async function updateEnrollment(id: string, data: { deadline?: string }): Promise<Enrollment> {
  return fetchWithTimeout<Enrollment>(
    `${ACADEMY_API_BASE}/enrollments/${id}`,
    { method: 'PUT', body: JSON.stringify(data) }
  )
}

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

export async function fetchCertificate(id: string): Promise<Certificate> {
  return fetchWithTimeout<Certificate>(
    `${ACADEMY_API_BASE}/certificates/${id}`
  )
}

export async function generateCertificate(enrollmentId: string): Promise<Certificate> {
  return fetchWithTimeout<Certificate>(
    `${ACADEMY_API_BASE}/enrollments/${enrollmentId}/certificate`,
    { method: 'POST' }
  )
}

export async function fetchCertificates(): Promise<Certificate[]> {
  const res = await fetchWithTimeout<{ certificates: Certificate[]; total: number }>(
    `${ACADEMY_API_BASE}/certificates`
  )
  return res.certificates || []
}

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

export async function submitQuiz(lessonId: string, answers: SubmitQuizRequest): Promise<SubmitQuizResponse> {
  return fetchWithTimeout<SubmitQuizResponse>(
    `${ACADEMY_API_BASE}/lessons/${lessonId}/quiz-test`,
    { method: 'POST', body: JSON.stringify(answers) }
  )
}

export async function updateLesson(lessonId: string, update: {
  title?: string
  description?: string
  content_url?: string
  duration_minutes?: number
  quiz_questions?: Array<{ question: string; options: string[]; correct_index: number; explanation: string }>
}): Promise<{ lesson: any }> {
  return fetchWithTimeout(
    `${ACADEMY_API_BASE}/lessons/${lessonId}`,
    { method: 'PUT', body: JSON.stringify(update) }
  )
}

// =============================================================================
// STATISTICS
// =============================================================================

export async function fetchAcademyStatistics(): Promise<AcademyStatistics> {
  const res = await fetchWithTimeout<{
    total_courses: number
    total_enrollments: number
    completion_rate: number
    overdue_count: number
    avg_completion_days: number
    by_category?: Record<string, number>
    by_status?: Record<string, number>
  }>(`${ACADEMY_API_BASE}/stats`)

  return {
    totalCourses: res.total_courses || 0,
    totalEnrollments: res.total_enrollments || 0,
    completionRate: res.completion_rate || 0,
    overdueCount: res.overdue_count || 0,
    byCategory: (res.by_category || {}) as Record<CourseCategory, number>,
    byStatus: (res.by_status || {}) as Record<EnrollmentStatus, number>,
  }
}

// =============================================================================
// COURSE GENERATION
// =============================================================================

export async function generateCourse(request: GenerateCourseRequest): Promise<{ course: Course }> {
  return fetchWithTimeout<{ course: Course }>(
    `${ACADEMY_API_BASE}/courses/generate`,
    {
      method: 'POST',
      body: JSON.stringify({ module_id: request.moduleId || request.title })
    },
    120000
  )
}

export async function generateAllCourses(): Promise<{ generated: number; skipped: number; errors: string[]; total: number }> {
  return fetchWithTimeout(
    `${ACADEMY_API_BASE}/courses/generate-all`,
    { method: 'POST' },
    300000
  )
}

export async function generateVideos(courseId: string): Promise<{ status: string; jobId?: string }> {
  return fetchWithTimeout<{ status: string; jobId?: string }>(
    `${ACADEMY_API_BASE}/courses/${courseId}/generate-videos`,
    { method: 'POST' },
    300000
  )
}

export async function getVideoStatus(courseId: string): Promise<{
  status: string
  total: number
  completed: number
  failed: number
  videos: Array<{ lessonId: string; status: string; url?: string }>
}> {
  return fetchWithTimeout(
    `${ACADEMY_API_BASE}/courses/${courseId}/video-status`
  )
}
