package eu.geyskens.pdfscan.pdf

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.pdf.PdfDocument
import java.io.File
import java.io.FileOutputStream

/** How each PDF page is sized relative to its scanned image. */
enum class PageSizeMode { A4, ORIGINAL }

object PdfBuilder {

    // A4 in PostScript points (1/72"): 210 x 297 mm.
    private const val A4_WIDTH_PT = 595
    private const val A4_HEIGHT_PT = 842

    /**
     * Writes [pages] into a single multi-page PDF at [output].
     * With [PageSizeMode.A4] each image is centered and scaled to fit an A4 page
     * (portrait or landscape chosen per image); with ORIGINAL the page matches the image.
     */
    fun build(pages: List<Bitmap>, output: File, mode: PageSizeMode = PageSizeMode.A4) {
        require(pages.isNotEmpty()) { "Cannot build a PDF with no pages." }
        val doc = PdfDocument()
        val paint = Paint(Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG)
        try {
            pages.forEachIndexed { index, bitmap ->
                val (pageW, pageH) = when (mode) {
                    PageSizeMode.ORIGINAL -> bitmap.width to bitmap.height
                    PageSizeMode.A4 ->
                        if (bitmap.width >= bitmap.height) A4_HEIGHT_PT to A4_WIDTH_PT // landscape
                        else A4_WIDTH_PT to A4_HEIGHT_PT
                }
                val info = PdfDocument.PageInfo.Builder(pageW, pageH, index + 1).create()
                val page = doc.startPage(info)
                val canvas = page.canvas
                canvas.drawColor(Color.WHITE)
                canvas.drawBitmap(bitmap, null, fitRect(bitmap, pageW, pageH), paint)
                doc.finishPage(page)
            }
            FileOutputStream(output).use { doc.writeTo(it) }
        } finally {
            doc.close()
        }
    }

    /** Largest centered rect inside the page that preserves the bitmap's aspect ratio. */
    private fun fitRect(bitmap: Bitmap, pageW: Int, pageH: Int): Rect {
        val scale = minOf(pageW.toFloat() / bitmap.width, pageH.toFloat() / bitmap.height)
        val w = (bitmap.width * scale).toInt()
        val h = (bitmap.height * scale).toInt()
        val left = (pageW - w) / 2
        val top = (pageH - h) / 2
        return Rect(left, top, left + w, top + h)
    }
}
