import { apiUrl } from '../lib/apiOrigin'
import { ApiHttpError, apiFetch, getStoredToken } from './http'
import type { ApiEnvelope } from './types'

export type CertificateDecisionRow = {
  decision: string
  source: string
  notes: string
  year_score: number | null
}

export type CertificateStudentRow = {
  student_id: number
  firstname: string
  lastname: string
  class_section_id: number
  class_section_name: string
  year_score: number | null
  eligible: boolean
  decision_state: 'pending' | 'pass' | 'decision'
  decision_labels: string[]
  decision_rows: CertificateDecisionRow[]
  certificate_number: string | null
}

export type CertificateSectionRow = {
  section_id: number
  section_name: string
  student_count: number
  pass_count: number
  cert_count: number
  remaining_count: number
  students: CertificateStudentRow[]
}

export type CertificateGradeGroup = {
  key: string
  label: string
  slug: string
  total: number
  pass: number
  cert: number
  fully_done: boolean
  has_pass: boolean
  sections: CertificateSectionRow[]
}

export type CertificateDashboardPayload = {
  school_year: string
  cert_date: string
  grade_groups: CertificateGradeGroup[]
  stats_per_class: Record<string, { name: string; total: number; pass: number; cert: number }>
  default_group_key: string | null
}

export type CertificateAuditRecord = {
  certificate_number: string
  student_name: string
  grade?: string | null
  cert_date?: string | null
  school_year?: string | null
  admin_firstname?: string | null
  admin_lastname?: string | null
  issued_at?: string | null
}

export type CertificateAuditPayload = {
  school_year: string
  records: CertificateAuditRecord[]
  year_summary: Array<{ school_year: string; total: number }>
}

function authHeaders(accept: string) {
  const headers = new Headers({ Accept: accept })
  const token = getStoredToken()
  if (token) headers.set('Authorization', `Bearer ${token}`)
  return headers
}

function withQuery(path: string, params?: Record<string, string | number | null | undefined>) {
  const qs = new URLSearchParams()
  Object.entries(params ?? {}).forEach(([key, value]) => {
    if (value !== undefined && value !== null && String(value).trim() !== '') {
      qs.set(key, String(value))
    }
  })
  return qs.size > 0 ? `${path}?${qs.toString()}` : path
}

export async function fetchCertificatesDashboard(params?: {
  school_year?: string
}): Promise<CertificateDashboardPayload> {
  const res = await apiFetch<ApiEnvelope<CertificateDashboardPayload>>(
    withQuery('/api/v1/administrator/certificates/dashboard', params),
  )
  return (res.data ?? {}) as CertificateDashboardPayload
}

export async function fetchCertificatesAuditLog(params?: {
  school_year?: string
}): Promise<CertificateAuditPayload> {
  const res = await apiFetch<ApiEnvelope<CertificateAuditPayload>>(
    withQuery('/api/v1/administrator/certificates/audit-log', params),
  )
  return (res.data ?? {}) as CertificateAuditPayload
}

export async function postCertificateGenerate(payload: {
  student_ids: number[]
  cert_date: string
  class_section_id?: number | null
  school_year?: string | null
}): Promise<Blob> {
  const res = await fetch(apiUrl('/api/v1/administrator/certificates/generate'), {
    method: 'POST',
    headers: (() => {
      const headers = authHeaders('application/pdf,*/*')
      headers.set('Content-Type', 'application/json')
      return headers
    })(),
    body: JSON.stringify(payload),
  })

  if (!res.ok) {
    const errBody: unknown = await res.json().catch(() => null)
    const message =
      typeof errBody === 'object' && errBody !== null && 'message' in errBody
        ? String((errBody as { message?: unknown }).message ?? '')
        : ''
    throw new ApiHttpError(message || `HTTP ${res.status}`, res.status, errBody)
  }

  return res.blob()
}

export async function fetchCertificateReprint(certificateNumber: string): Promise<Blob> {
  const res = await fetch(
    apiUrl(`/api/v1/administrator/certificates/reprint/${encodeURIComponent(certificateNumber)}`),
    {
      method: 'GET',
      headers: authHeaders('application/pdf,*/*'),
    },
  )

  if (!res.ok) {
    const errBody: unknown = await res.json().catch(() => null)
    const message =
      typeof errBody === 'object' && errBody !== null && 'message' in errBody
        ? String((errBody as { message?: unknown }).message ?? '')
        : ''
    throw new ApiHttpError(message || `HTTP ${res.status}`, res.status, errBody)
  }

  return res.blob()
}
