@file:Suppress("DEPRECATION")

package com.recordatorios.app

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import android.util.LruCache
import java.io.File
import java.io.FileOutputStream

object PhotoUtils {

    private const val MAX_WIDTH = 300
    private const val BLUR_RADIUS = 8f

    private val bitmapCache = LruCache<String, Bitmap>(40)

    fun copyToInternalStorage(context: Context, uri: Uri): String? {
        return try {
            val dir = File(context.filesDir, "photos")
            dir.mkdirs()
            val file = File(dir, "photo_${System.currentTimeMillis()}.jpg")
            context.contentResolver.openInputStream(uri)?.use { input ->
                FileOutputStream(file).use { output ->
                    input.copyTo(output)
                }
            }
            file.absolutePath
        } catch (e: Exception) {
            null
        }
    }

    fun loadPhotoBitmap(path: String, maxWidth: Int = MAX_WIDTH): Bitmap? {
        if (path.isBlank()) return null
        val cacheKey = "${path}_${maxWidth}_${BLUR_RADIUS}"
        bitmapCache.get(cacheKey)?.let { return it }

        return try {
            val options = BitmapFactory.Options().apply {
                inJustDecodeBounds = true
            }
            BitmapFactory.decodeFile(path, options)

            val scaleFactor = maxOf(options.outWidth / maxWidth, 1)

            val decodeOptions = BitmapFactory.Options().apply {
                inSampleSize = scaleFactor
            }
            val bitmap = BitmapFactory.decodeFile(path, decodeOptions) ?: return null
            bitmapCache.put(cacheKey, bitmap)
            bitmap
        } catch (e: Exception) {
            null
        }
    }

    fun loadBlurredBitmap(context: Context, path: String, maxWidth: Int = MAX_WIDTH, radius: Float = BLUR_RADIUS): Bitmap? {
        if (path.isBlank()) return null
        val cacheKey = "${path}_${maxWidth}_${radius}_blurred"
        bitmapCache.get(cacheKey)?.let { return it }

        val bitmap = loadPhotoBitmap(path, maxWidth) ?: return null
        val blurred = applyBlur(context, bitmap, radius)
        if (blurred != null) {
            bitmapCache.put(cacheKey, blurred)
        }
        return blurred
    }

    private fun applyBlur(context: Context, bitmap: Bitmap, radius: Float): Bitmap? {
        return try {
            val rs = RenderScript.create(context)
            val input = Allocation.createFromBitmap(rs, bitmap)
            val output = Allocation.createTyped(rs, input.type)
            val script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))
            script.setRadius(radius.coerceIn(0f, 25f))
            script.setInput(input)
            script.forEach(output)
            output.copyTo(bitmap)
            rs.destroy()
            bitmap
        } catch (e: Exception) {
            null
        }
    }

    fun deletePhoto(path: String) {
        if (path.isNotBlank()) {
            try { File(path).delete() } catch (_: Exception) {}
        }
    }
}
