package com.a2i.forwarder.core

import android.content.Context
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.net.Uri
import androidx.documentfile.provider.DocumentFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

class IconExporter(private val context: Context) {
    data class ExportResult(val total: Int, val ok: Int, val fail: Int)

    suspend fun exportAll(treeUri: Uri): ExportResult = withContext(Dispatchers.IO) {
        val tree = DocumentFile.fromTreeUri(context, treeUri)
            ?: return@withContext ExportResult(0, 0, 0)
        val pm = context.packageManager
        val apps = pm.getInstalledApplications(PackageManager.GET_META_DATA)
        var ok = 0
        var fail = 0
        for (app in apps) {
            val name = app.packageName
            try {
                val drawable: Drawable = pm.getApplicationIcon(name)
                val bmp = drawableToBitmap(drawable)
                tree.findFile("$name.png")?.delete()
                val file = tree.createFile("image/png", "$name.png")
                if (file != null) {
                    context.contentResolver.openOutputStream(file.uri)?.use { out ->
                        bmp.compress(Bitmap.CompressFormat.PNG, 100, out)
                    }
                    ok++
                } else {
                    fail++
                }
            } catch (e: Exception) {
                fail++
            }
        }
        ExportResult(apps.size, ok, fail)
    }

    private fun drawableToBitmap(d: Drawable): Bitmap {
        if (d is BitmapDrawable && d.bitmap != null) return d.bitmap
        val size = maxOf(d.intrinsicWidth, d.intrinsicHeight, 192).coerceAtLeast(1)
        val bmp = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bmp)
        d.setBounds(0, 0, canvas.width, canvas.height)
        d.draw(canvas)
        return bmp
    }
}
