package com.drawing.drawsketch

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Point
import android.graphics.drawable.PictureDrawable
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.util.DisplayMetrics
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import androidx.core.graphics.createBitmap
import androidx.core.graphics.scale
import androidx.core.net.toUri
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.caverock.androidsvg.SVG
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.concurrent.Executors
import kotlin.math.sqrt

object Utils {

    fun loadSvgFromAssets(context: Context, filePath: String, imageView: ImageView) {
        try {
            val inputStream = context.assets.open(filePath)
            val svg = SVG.getFromInputStream(inputStream)
            val drawable = PictureDrawable(svg.renderToPicture())
            imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
            imageView.setImageDrawable(drawable)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    fun loadSvgToImageViewOld(
        context: Context,
        fileName: String,
        width: Float,
        height: Float,
        im:ImageView? = null,
        onBitmapResult: ((Bitmap?) -> Unit)? = null
    ) {
        Executors.newSingleThreadExecutor().execute {
            try {
                val svg = SVG.getFromAsset(context.assets, fileName)
                val scaleX = width / svg.documentWidth
                val scaleY = height / svg.documentHeight

                val bitmap = Bitmap.createBitmap(width.toInt(), height.toInt(), Bitmap.Config.ARGB_8888)
                val canvas = Canvas(bitmap)
                canvas.scale(scaleX, scaleY)
                svg.renderToCanvas(canvas)

                Handler(Looper.getMainLooper()).post {
                    onBitmapResult?.invoke(bitmap)
                    im?.setImageBitmap(bitmap)
                    Log.d(App.TAG, "im: $im  bitmap=${bitmap}" )
                }
            } catch (e: Exception) {
                Log.e("SVG", "Error loading SVG: $fileName", e)

                Handler(Looper.getMainLooper()).post {
                    onBitmapResult?.invoke(null)
                }
            }
        }
    }

    fun loadSvgToImageView(
        context: Context,
        filePath: String,
        widthPx: Float,
        heightPx: Float,
        imageView: ImageView,
        onBitmapResult: ((bitmap: Bitmap?) -> Unit)? = null
    ) {
        Executors.newSingleThreadExecutor().execute {
            try {
                val svg = SVG.getFromAsset(context.assets, filePath)
                val density = context.resources.displayMetrics.density
                val bitmap = createBitmap((widthPx).toInt(), (heightPx).toInt())
                val canvas = Canvas(bitmap)
                canvas.scale(density, density)
                svg.setDocumentWidth("100%")
                svg.setDocumentHeight("100%")
                svg.renderToCanvas(canvas)
                Handler(Looper.getMainLooper()).post {
                    onBitmapResult?.invoke(bitmap)
                }
                imageView.post { imageView.setImageBitmap(bitmap) }

            } catch (e: java.lang.Exception) {
                Log.e("SVG", "Error loading SVG: $filePath", e)
                Handler(Looper.getMainLooper()).post {
                    onBitmapResult?.invoke(null)
                }
            }
        }
    }

    fun loadImage(
        context: Context, filePath: String, widthPx: Float = 600f,
        heightPx: Float = 600f,    image:ImageView? = null, onBitmapResult: ((bitmap: Bitmap?) -> Unit)? = null
    ) {

        if (filePath.endsWith(".svg")) {
            loadSvgToImageViewOld(context, filePath, widthPx, heightPx, im=image,onBitmapResult=onBitmapResult)
        } else if (filePath.endsWith(".jpg")) {
            val uri = "file:///android_asset/$filePath".toUri()


            Glide.with(context)
                .asBitmap()
                .load(uri)
                .override(Target.SIZE_ORIGINAL)

                .listener(object : RequestListener<Bitmap> {
                    override fun onLoadFailed(
                        e: GlideException?,
                        model: Any?,
                        target: Target<Bitmap>,
                        isFirstResource: Boolean
                    ): Boolean {
                        onBitmapResult?.invoke(null)
                        return false
                    }

                    override fun onResourceReady(
                        resource: Bitmap,
                        model: Any,
                        target: Target<Bitmap>?,
                        dataSource: DataSource,
                        isFirstResource: Boolean
                    ): Boolean {
                        onBitmapResult?.invoke(resource)
                        image?.setImageBitmap(resource.scale(600,600))
                        return false
                    }

                })
                .preload()
        }

    }


    fun listAssetFiles(context: Context, folderName: String): List<String> {
        return try {
            val assetManager = context.assets
            val files = assetManager.list(folderName) ?: emptyArray()
            files.toList()
        } catch (e: IOException) {
            e.printStackTrace()
            emptyList()
        }
    }

    fun dpToPx(dpValue: Float): Float {
        val density: Float = App.mInstance.resources.displayMetrics.density
        return density * dpValue + 0.5f
    }

    fun getDisPlayName(fileName: String): String {
        return fileName.replace("kt_", "")
    }


    fun getScreen(context: Context): Point {
        val displayMetrics = DisplayMetrics()
        val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        val width = displayMetrics.widthPixels
        val height = displayMetrics.heightPixels
        val point = Point()
        point.x = width
        point.y = height
        return point
    }


    fun getDistance(event: MotionEvent): Float {
        val x = event.getX(0) - event.getX(1)
        val y = event.getY(0) - event.getY(1)
        return sqrt((x * x + y * y).toDouble()).toFloat()
    }

    fun saveToStorage(fileName: String, fileUri: Uri, context: Context): Boolean {
        try {
            // 获取输入流
            val bitmap =
                BitmapFactory.decodeStream(context.contentResolver.openInputStream(fileUri))
            // 创建图片文件
            val file = File(context.filesDir, fileName)
            val fileOutputStream = FileOutputStream(file)
            // 将Bitmap图片进行存储
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)
            fileOutputStream.close()
            return true
        } catch (e: IOException) {
            e.printStackTrace()
            return false
        }
    }
    fun getUriFileSize(context: Context, uri: Uri): Double {
        var fileSize = 0.0
        val contentResolver = context.contentResolver

        // 如果Uri是文件类型
        if (uri.scheme == "file") {
            val file = File(uri.path)
            fileSize = file.length().toDouble()
        } else { // 如果Uri不是文件类型，则通过ContentResolver获取大小
            try {
                fileSize = contentResolver.openFileDescriptor(uri, "r")!!.statSize.toDouble()
            } catch (e: java.lang.Exception) {
                Log.e("UriUtils", "Error while retrieving file size: " + e.message)
            }
        }
        fileSize = fileSize / 1048576.0
        return fileSize
    }
    fun getImportPath(name: String): String {
        val filesDir: File = App.mInstance.filesDir
        val s = "$filesDir/$name"
        return s
    }
}