package uz.aigroup.myid

import android.content.Intent
import android.graphics.Bitmap
import android.util.Base64
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.PluginRegistry
import uz.myid.android.sdk.capture.MyIdClient
import uz.myid.android.sdk.capture.MyIdException
import uz.myid.android.sdk.capture.MyIdResult
import uz.myid.android.sdk.capture.MyIdResultListener
import uz.myid.android.sdk.capture.model.MyIdImageFormat
import java.io.ByteArrayOutputStream
import java.io.IOException

class MyIdSdkActivityListener(
    private val client: MyIdClient
) : PluginRegistry.ActivityResultListener {

    private var flutterResult: MethodChannel.Result? = null

    fun setCurrentFlutterResult(result: MethodChannel.Result?) {
        this.flutterResult = result
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
        client.handleActivityResult(resultCode, object : MyIdResultListener {
            override fun onSuccess(result: MyIdResult) {
                if (flutterResult != null) {
                    try {
                        val response = Response(
                            code = result.code,
                            comparison = result.comparison,
                            base64 = result.bitmap?.toBase64()
                        )
                        flutterResult?.success(response.toMap())
                    } catch (e: Exception) {
                        if (result.code != null) {
                            val response = Response(
                                code = result.code,
                                comparison = result.comparison
                            )
                            flutterResult?.success(response.toMap())
                        } else {
                            flutterResult?.error("error", e.message, null)
                        }
                    } finally {
                        flutterResult = null
                    }
                }
            }

            override fun onError(e: MyIdException) {
                if (flutterResult != null) {
                    flutterResult?.error(
                        "error",
                        "${e.code} - ${e.message}",
                        null
                    )
                    flutterResult = null
                }
            }

            override fun onUserExited() {
                if (flutterResult != null) {
                    flutterResult?.error(
                        "cancel",
                        "User exited by clicking the back button.",
                        null
                    )
                    flutterResult = null
                }
            }
        })
        return true
    }

    private fun Bitmap?.toBase64(
        format: MyIdImageFormat = MyIdImageFormat.JPG
    ): String? {
        this ?: return null

        return try {
            "data:image/png;base64,${
                Base64.encodeToString(toByteArray(format), Base64.DEFAULT)
            }"
        } catch (_: Throwable) {
            null
        }
    }

    private fun Bitmap.toByteArray(
        format: MyIdImageFormat,
        quality: Int = 100
    ): ByteArray? {
        var baos: ByteArrayOutputStream? = null
        return try {
            val compressFormat = when (format) {
                MyIdImageFormat.JPG -> Bitmap.CompressFormat.JPEG
                MyIdImageFormat.PNG -> Bitmap.CompressFormat.PNG
            }

            baos = ByteArrayOutputStream()
            compress(compressFormat, quality, baos)
            baos.toByteArray()
        } finally {
            if (baos != null) {
                try {
                    baos.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
    }
}