import fs from 'fs/promises'
import path from 'path'
import sharp from 'sharp'

const getDataRoot = () => {
  const cwd = process.cwd()
  return cwd.endsWith('.output') ? `${cwd}/../server/data` : `${cwd}/server/data`
}

const DATA_ROOT = getDataRoot()
const GALERIE_DIR = `${DATA_ROOT}/galerie`
const GALERIE_METADATA = `${DATA_ROOT}/galerie-metadata.json`

async function readJsonArray(file) {
  try {
    const data = await fs.readFile(file, 'utf-8')
    const parsed = JSON.parse(data)
    return Array.isArray(parsed) ? parsed : []
  } catch (e) {
    if (e.code === 'ENOENT') return []
    throw e
  }
}

async function writeJson(file, obj) {
  await fs.writeFile(file, JSON.stringify(obj, null, 2), 'utf-8')
}

async function ensureDirs() {
  await fs.mkdir(path.join(GALERIE_DIR, 'originals'), { recursive: true })
  await fs.mkdir(path.join(GALERIE_DIR, 'previews'), { recursive: true })
}

async function fileExists(p) {
  try {
    await fs.access(p)
    return true
  } catch {
    return false
  }
}

async function generatePreviewForEntry(entry, size) {
  const safeOriginal = path.basename(String(entry.filename || ''))
  const original = `${GALERIE_DIR}/originals/${safeOriginal}`
  if (!(await fileExists(original))) return { ok: false, reason: 'missing original' }

  const previewFilename = entry.previewFilename && String(entry.previewFilename).trim() !== ''
    ? entry.previewFilename
    : `preview_${entry.filename}`

  const safePreview = path.basename(String(previewFilename || ''))
  const preview = `${GALERIE_DIR}/previews/${safePreview}`

  await sharp(original)
    .rotate()
    .resize(size, size, {
      fit: 'cover',
      withoutEnlargement: true
    })
    .jpeg({ quality: 82, mozjpeg: true })
    .toFile(preview)

  return { ok: true, previewFilename }
}

async function main() {
  const size = Number(process.env.GALERIE_PREVIEW_SIZE || 300)
  await ensureDirs()

  const entries = await readJsonArray(GALERIE_METADATA)
  if (entries.length === 0) {
    console.log('Keine Galerie-Metadaten gefunden.')
    return
  }

  let changed = 0
  let generated = 0
  let skipped = 0

  for (const entry of entries) {
    if (!entry || !entry.filename) {
      skipped++
      continue
    }

    const res = await generatePreviewForEntry(entry, size)
    if (!res.ok) {
      skipped++
      continue
    }

    generated++

    if (entry.previewFilename !== res.previewFilename) {
      entry.previewFilename = res.previewFilename
      changed++
    }
  }

  if (changed > 0) await writeJson(GALERIE_METADATA, entries)

  console.log(`Previews erzeugt: ${generated}, übersprungen: ${skipped}, metadata-updates: ${changed}`)
}

main().catch(e => {
  console.error(e)
  process.exit(1)
})
