package com.cheng.blzb.utils

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Matrix
import android.util.Base64
import android.util.LruCache
import android.view.View
import com.example.base.extensions.toast
import com.example.base.utils.ScreenUtils
import com.jakewharton.disklrucache.DiskLruCache
import top.zibin.luban.Luban
import top.zibin.luban.OnCompressListener
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException


object BitmapUtils {
    private val lruCache by lazy {
        object : LruCache<String, Bitmap>(20 * 1024 * 1024) {
            override fun sizeOf(key: String?, value: Bitmap?): Int {
                return value?.allocationByteCount ?: 0
            }
        }
    }

    private val diskLruCache by lazy {
        DiskLruCache.open(com.cheng.blzb.utils.FileUtils.getInstance().cacheDir, 1, 1, 100L * 1024 * 1024)
    }

    fun putCacheBitmap(key: String, bitmap: Bitmap, diskCache: Boolean = true) {
        lruCache.put(key, bitmap)
        if (diskCache) {
            val editor = diskLruCache.edit(key)
            if (editor != null) {
                val outputStream = editor.newOutputStream(0)
                val success = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
                if (success) {
                    editor.commit()
                } else {
                    editor.abort()
                }
            }
        }
    }

    fun getCacheBitmap(key: String): Bitmap? {
        var cacheBitmap: Bitmap?
        cacheBitmap = lruCache.get(key)
        if (cacheBitmap == null) {
            try {
                val snapShot = diskLruCache.get(key) // 通过key获取Snapshot对象
                if (snapShot != null) {
                    val inputStream = snapShot.getInputStream(0) // 通过Snapshot对象获取缓存文件的输入流
                    cacheBitmap = BitmapFactory.decodeStream(inputStream)
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        return cacheBitmap
    }

    fun clearMemoryCache() {
        lruCache.trimToSize(20 * 1024 * 1024)
    }

    fun Base64ToBitmap(str: String): Bitmap {
        val decodeBytes = Base64.decode(str, Base64.DEFAULT)
        return BitmapFactory.decodeByteArray(decodeBytes, 0, decodeBytes.size)
    }

    fun compressImg(context: Context, str: String, compressBack: (File) -> Unit) {
        Luban.with(context)
            .load(str)
            .ignoreBy(100)
            .setTargetDir(com.cheng.blzb.utils.FileUtils.getInstance().cachE_DIR)
            .setCompressListener(object : OnCompressListener {
                override fun onStart() {

                }

                override fun onSuccess(file: File?) {
                    if (file != null)
                        compressBack.invoke(file)
                }

                override fun onError(e: Throwable?) {
                    toast("压缩失败")
                }

            }).launch()
    }

    /**
     * 长图拼接
     */
    fun mergeLongBitmap(bitmaps: List<Bitmap>, maxWidth: Int? = null): Bitmap {
        val longBitmap: Bitmap
        val totalW = maxWidth ?: ScreenUtils.getScreenWidth()
        var totalH = 0
        val newBitmaps = mutableListOf<Bitmap>()
        bitmaps.forEach {
            val height = it.getHeight().toFloat() * totalW / it.getWidth().toFloat()
            newBitmaps.add(resizeBitmap(it, totalW, height.toInt()))
            totalH += height.toInt()
        }
        longBitmap = Bitmap.createBitmap(totalW, totalH, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(longBitmap)
        var top = 0f
        newBitmaps.forEach {
            canvas.drawBitmap(it, 0f, top, null)
            top += it.height
        }
        return longBitmap
    }

    /**
     * 缩放图片
     */
    fun resizeBitmap(bitmap: Bitmap, newWidth: Int, newHeight: Int): Bitmap {
        val scaleWidth = newWidth.toFloat() / bitmap.getWidth()
        val scaleHeight = newHeight.toFloat() / bitmap.getHeight()
        val matrix = Matrix()
        matrix.postScale(scaleWidth, scaleHeight)
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false)
    }

    /**
     * 保存Bitmap到文件
     */
    fun saveBitmapToFile(bitmap: Bitmap, isPng: Boolean = false): File {
        val file = File(com.cheng.blzb.utils.FileUtils.getInstance().cacheDir, "jk_${System.currentTimeMillis()}.${if (isPng) "png" else "jpeg"}")//将要保存图片的路径
        try {
            val bos = BufferedOutputStream(FileOutputStream(file))
            bitmap.compress(if (isPng) Bitmap.CompressFormat.PNG else Bitmap.CompressFormat.JPEG, 100, bos)
            bos.flush()
            bos.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return file
    }

    /**
     * view转bitmap
     */
    fun getBitmapByView(context: Context, view: View): Bitmap {
        val bitmap: Bitmap?

        // 步骤一：获取视图的宽和高
        val width: Int = view.right - view.left
        val height: Int = view.bottom - view.top

        // 步骤二：生成bitmap
        bitmap = Bitmap.createBitmap(context.resources.displayMetrics, width, height, Bitmap.Config.ARGB_8888)
        bitmap.density = context.resources.displayMetrics.densityDpi

        // 步骤三：绘制canvas
        val canvas = Canvas(bitmap)
        view.computeScroll()
        val restoreCount: Int = canvas.save()
        canvas.translate((-view.scrollX).toFloat(), (-view.scrollY).toFloat())
        view.draw(canvas)
        canvas.restoreToCount(restoreCount)
        canvas.setBitmap(null)
        return bitmap
    }
}