package com.isidroid.rendering.repository

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import com.isidroid.rendering.constant.PrintOrientation
import com.isidroid.rendering.ext.calculateScaleFactor
import com.isidroid.rendering.ext.convertMmToPixels
import com.isidroid.rendering.ext.createOriginalSizes
import com.isidroid.rendering.ext.createRenderBitmap
import com.isidroid.rendering.ext.getMaxBitmapSize
import com.isidroid.rendering.model.PreviewContainerInfo
import com.isidroid.rendering.model.RenderSettingsV2
import com.isidroid.rendering.model.SizeF
import kotlin.math.max
import kotlin.math.min

internal class RenderRepositoryIml(private val context: Context) : RenderRepository {

    override fun renderBitmap(
        width: Int,
        height: Int,
        printWidth: Int,
        printHeight: Int,
        marginTop: Int,
        marginLeft: Int,
        dpix: Int,
        dpiy: Int,
        renderSettingsV2: RenderSettingsV2,
        picture: Bitmap
    ): Bitmap {
        val idpix = if (dpix > 300) 300 else dpix
        val idpiy = if (dpiy > 300) 300 else dpiy
        val bitmapConfig = Bitmap.Config.RGB_565

        val canvasInfo = createOriginalSizes(
            width = convertMmToPixels(width, idpix),
            height = convertMmToPixels(height, idpiy),
            printWidth = convertMmToPixels(printWidth, idpix),
            printHeight = convertMmToPixels(printHeight, idpiy),
            marginLeft = convertMmToPixels(marginLeft, idpix),
            marginTop = convertMmToPixels(marginTop, idpiy)
        )

        val result = createRenderBitmap(
            settings = renderSettingsV2,
            printCanvas = canvasInfo,
            dpix = dpix,
            picture = picture,
            maxSize = getMaxBitmapSize(context, bitmapConfig),
            bitmapConfig = bitmapConfig
        )

        return result
    }

    override fun preparePreviewContainer(
        printOrientation: Int,
        filePath: String,
        viewWidth: Int,
        viewHeight: Int,
        dpiX: Int,
        dpiY: Int,
        paperWidthMm: Int,
        paperHeightMm: Int
    ): PreviewContainerInfo {
        val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
        BitmapFactory.decodeFile(filePath, options)

        val picWidth = options.outWidth
        val picHeight = options.outHeight
        val isPicturePortrait = picWidth < picHeight

        val paperWidth = convertMmToPixels(paperWidthMm, dpiX)
        val paperHeight = convertMmToPixels(paperHeightMm, dpiY)
        val minCanvasSize = min(paperWidth, paperHeight)
        val maxCanvasSize = max(paperWidth, paperHeight)

        val size = when (printOrientation) {
            PrintOrientation.PORTRAIT -> SizeF(minCanvasSize, maxCanvasSize)
            PrintOrientation.LANDSCAPE -> SizeF(maxCanvasSize, minCanvasSize)
            else -> SizeF(
                width = if (isPicturePortrait) minCanvasSize else maxCanvasSize,
                height = if (isPicturePortrait) maxCanvasSize else minCanvasSize
            )
        }

        val a1 = calculateScaleFactor(viewWidth.toFloat(), viewHeight.toFloat(), size.width, size.height)
        val a2 = calculateScaleFactor(viewHeight.toFloat(), viewWidth.toFloat(), size.height, size.width)
        val scale = a1 ?: a2 ?: 1f

        return PreviewContainerInfo(
            width = size.width * scale,
            height = size.height * scale,
            scale = scale
        )
    }
}