package com.abbidot.tracker.util

import android.app.Activity
import android.content.Context
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Rect
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.VectorDrawable
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.DisplayMetrics
import android.view.PixelCopy
import android.view.View
import android.view.Window
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import coil.ImageLoader
import coil.request.ImageRequest
import coil.transform.CircleCropTransformation
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.tracker.MyApplication
import com.abbidot.tracker.R
import com.qmuiteam.qmui.util.QMUIDisplayHelper


/**
 *Created  by .yzq on 2022/3/1/001.
 * @link
 * @description:
 */
object ImageUtil {
    /**
     * Return the bitmap of screen.截图
     *
     * @param activity The activity.
     * @return the bitmap of screen
     */
    fun screenShot(activity: Activity): Bitmap? {
        return screenShot(activity, false)
    }

    /**
     * Return the bitmap of screen.
     *
     * @param activity          The activity.
     * @param isDeleteStatusBar True to delete status bar, false otherwise.删除状态栏
     * @return the bitmap of screen
     */
    private fun screenShot(activity: Activity, isDeleteStatusBar: Boolean): Bitmap? {
        val decorView: View = activity.window.decorView
        val bmp: Bitmap = viewToBitmap(decorView)
        val dm = DisplayMetrics()
        activity.windowManager.defaultDisplay.getMetrics(dm)
        return if (isDeleteStatusBar) {
            val statusBarHeight: Int = getStatusBarHeight()
            LogUtil.e("$statusBarHeight")
            Bitmap.createBitmap(
                bmp, 0, statusBarHeight, dm.widthPixels, dm.heightPixels - statusBarHeight
            )
        } else {
            Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels)
        }
    }

    /**
     * 获取状态栏高度
     */
    private fun getStatusBarHeight(): Int {
        val resources: Resources = MyApplication.instance.resources
        val resourceId: Int = resources.getIdentifier("status_bar_height", "dimen", "android")
        return resources.getDimensionPixelSize(resourceId)
    }

    /**
     * View to bitmap.
     *View转换为bitmap
     *
     * @param view The view.
     * @return bitmap
     */
    fun viewToBitmap(view: View): Bitmap {
        val drawingCacheEnabled = view.isDrawingCacheEnabled
        val willNotCacheDrawing = view.willNotCacheDrawing()
        view.isDrawingCacheEnabled = true
        view.setWillNotCacheDrawing(false)
        var drawingCache = view.drawingCache
        val bitmap: Bitmap
        if (null == drawingCache || drawingCache.isRecycled) {
            view.measure(
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
            )
            view.layout(0, 0, view.measuredWidth, view.measuredHeight)
            view.buildDrawingCache()
            drawingCache = view.drawingCache
            if (null == drawingCache || drawingCache.isRecycled) {
                bitmap = Bitmap.createBitmap(
                    view.measuredWidth, view.measuredHeight, Bitmap.Config.RGB_565
                )
                val canvas = Canvas(bitmap)
                view.draw(canvas)
            } else {
                bitmap = Bitmap.createBitmap(drawingCache)
            }
        } else {
            bitmap = Bitmap.createBitmap(drawingCache)
        }
        view.setWillNotCacheDrawing(willNotCacheDrawing)
        view.isDrawingCacheEnabled = drawingCacheEnabled
        return bitmap
    }


    /**
     * View转换为bitmap
     * 要注明“android:hardwareAccelerated="false"”，不然会报错Software rendering doesn't support hardware bitmaps
     */
    fun viewToBitmap(view: View, bitmapCallback: (Bitmap) -> Unit) {
        val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        view.draw(canvas)
        bitmapCallback.invoke(bitmap)
    }

    /**
     * View转换为bitmap
     */
    fun viewToBitmap(
        context: Context, view: View, window: Window, bitmapCallback: (Bitmap) -> Unit
    ) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //三星手机未渲染显示view部分会有黑边
            LogUtil.d("captureView version O 以上")
            // 高于 O 的，使用 PixelCopy
            val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
            bitmap.eraseColor(ContextCompat.getColor(context, R.color.share_color))
            val location = IntArray(2)
            view.getLocationInWindow(location)
            PixelCopy.request(
                window,
                Rect(location[0], location[1], location[0] + view.width, location[1] + view.height),
                bitmap,
                {
                    if (it == PixelCopy.SUCCESS) {
                        LogUtil.d("captureView 获取到 bitmap")
                        bitmapCallback.invoke(bitmap)
                    } else {
                        LogUtil.d("captureView 未获取到 bitmap, copyResult = $it")
                    }
                },
                Handler(Looper.getMainLooper())
            )
        } else {
            LogUtil.d("captureView version O 以下")
            val tBitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.RGB_565)
            tBitmap.eraseColor(ContextCompat.getColor(context, R.color.share_color))
            val canvas = Canvas(tBitmap)
            view.draw(canvas)
            canvas.setBitmap(null)
            bitmapCallback.invoke(tBitmap)
        }
    }

    /**
     * 等比缩放bitmap
     *
     * @param bm
     * @param newWidth
     * @param newHeight
     * @return
     */
    fun zoomImg(bm: Bitmap, newWidth: Int, newHeight: Int): Bitmap {
        // 获得图片的宽高
        val width = bm.width
        val height = bm.height
        // 计算缩放比例
        val scaleWidth = newWidth.toFloat() / width
        val scaleHeight = newHeight.toFloat() / height
        // 取得想要缩放的matrix参数
        val matrix = Matrix()
        matrix.postScale(scaleWidth, scaleHeight)
        // 得到新的图片
        return Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true)
    }

    /**
     * 合并两张bitmap为一张
     *
     * @param background
     * @param foreground
     * @return Bitmap
     */
    fun combineBitmap(background: Bitmap, foreground: Bitmap): Bitmap {
        val bgWidth = background.width
        val bgHeight = background.height
        val fgWidth = foreground.width
        val fgHeight = foreground.height
        val newBitmap = Bitmap.createBitmap(bgWidth, bgHeight, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(newBitmap)
        canvas.drawBitmap(background, 0f, 0f, null)
        canvas.drawBitmap(foreground, (bgWidth - fgWidth) / 2f, (bgHeight - fgHeight) / 2f, null)
        canvas.save()
        canvas.restore()
        return newBitmap
    }

    /**
     * 使用coil和协程获取网络图片Bitmap
     */
    suspend fun getImageBitmapByUrl(context: Context, url: String): Bitmap {
        val imageLoader = ImageLoader(context)
        val request =
            ImageRequest.Builder(context).data(url).transformations(CircleCropTransformation())
                //默认大小50dp
                .size(QMUIDisplayHelper.dpToPx(50)).allowHardware(false).build()
        val drawable = imageLoader.execute(request).drawable ?: return getBitmapFromDrawableAndSvg(
            context, R.drawable.icon_pet_default_head_svg
        ) ?: BitmapFactory.decodeResource(
            context.resources, R.drawable.pic_avatar_df
        )
        return (drawable as BitmapDrawable).bitmap
    }

    /**
     * 适配 SVG转Bitmap,drawableRes转Bitmap
     */
    fun getBitmapFromDrawableAndSvg(context: Context, @DrawableRes drawableId: Int): Bitmap? {
        return when (val drawable = ContextCompat.getDrawable(context, drawableId)) {
            is BitmapDrawable -> {
                drawable.bitmap
            }

            is VectorDrawable, is VectorDrawableCompat -> {
                val bitmap = Bitmap.createBitmap(
                    drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888
                )
                val canvas = Canvas(bitmap)
                drawable.setBounds(0, 0, canvas.width, canvas.height)
                drawable.draw(canvas)
                bitmap
            }

            else -> {
                throw IllegalArgumentException("unsupported drawable type")
            }
        }
    }
}