import { join } from 'node:path'
import { readFileSync, existsSync } from 'node:fs'

// Polyfills nécessaires pour pdfjs-dist en Node.js pur (pas de DOM)
// On n'a besoin que du parsing, pas du rendu
if (typeof globalThis.DOMMatrix === 'undefined') {
  // @ts-expect-error polyfill minimal pour pdfjs
  globalThis.DOMMatrix = class DOMMatrix {
    constructor() { return Object.assign(this, { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }) }
    isIdentity = true
    translate() { return new DOMMatrix() }
    scale() { return new DOMMatrix() }
    inverse() { return new DOMMatrix() }
    multiply() { return new DOMMatrix() }
  }
}
if (typeof globalThis.Path2D === 'undefined') {
  // @ts-expect-error polyfill stub
  globalThis.Path2D = class Path2D { constructor() {} }
}
if (typeof globalThis.ImageData === 'undefined') {
  // @ts-expect-error polyfill stub
  globalThis.ImageData = class ImageData { constructor(w: number, h: number) { this.width = w; this.height = h; this.data = new Uint8ClampedArray(w * h * 4) } }
}

export default defineEventHandler(async () => {
  const config = await readYaml('bookplayer.config.yml')
  const pdfFile = config?.book?.pdfFile || '/pdf/une-economie-du-don.pdf'

  // Résolution du chemin PDF : dev (public/) et prod (.output/public/)
  const cwd = process.cwd()
  const candidates = [
    join(cwd, 'public', pdfFile),
    join(cwd, '.output', 'public', pdfFile),
  ]
  const pdfPath = candidates.find(p => existsSync(p))

  if (!pdfPath) {
    console.warn('[pdf-outline] PDF non trouvé. cwd:', cwd, 'candidats:', candidates)
    return []
  }

  let data: Uint8Array
  try {
    data = new Uint8Array(readFileSync(pdfPath))
  } catch (err) {
    console.warn('[pdf-outline] Erreur lecture PDF:', err)
    return []
  }

  const pdfjsLib = await import('pdfjs-dist/legacy/build/pdf.mjs')

  let doc
  try {
    doc = await pdfjsLib.getDocument({ data, useSystemFonts: true }).promise
  } catch (err) {
    console.warn('[pdf-outline] Erreur getDocument:', err)
    return []
  }

  const outline = await doc.getOutline()

  if (!outline || outline.length === 0) {
    doc.destroy()
    return []
  }

  const entries: Array<{ title: string; page: number; level: number }> = []

  async function extract(items: any[], level: number) {
    for (const item of items) {
      let page: number | null = null
      try {
        let dest = item.dest
        if (typeof dest === 'string') dest = await doc.getDestination(dest)
        if (dest) page = (await doc.getPageIndex(dest[0])) + 1
      } catch {}
      if (page !== null) entries.push({ title: item.title, page, level })
      if (item.items?.length) await extract(item.items, level + 1)
    }
  }

  await extract(outline, 0)
  doc.destroy()
  return entries
})
