package com.remax.visualnovel.extension.glide

import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.core.graphics.scale
import androidx.core.view.isVisible
import com.bumptech.glide.Glide
import com.bumptech.glide.integration.webp.decoder.WebpDrawable
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.GranularRoundedCorners
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
import com.remax.visualnovel.extension.toS3Url
import com.remax.visualnovel.utils.spannablex.utils.dp
import com.remax.visualnovel.widget.glidetransformation.CropRectTransformation
import jp.wasabeef.glide.transformations.RoundedCornersTransformation
import timber.log.Timber
import ua.anatolii.graphics.ninepatch.NinePatchChunk


fun ImageView.loadGranularRoundedCorners(
    url: String?,
    topLeft: Int = 0,
    topRight: Int = 0,
    bottomRight: Int = 0,
    bottomLeft: Int = 0,
    cache: Boolean = false
) {
    Glide.with(context)
        .load(url)
        .diskCacheStrategy(if (cache) DiskCacheStrategy.AUTOMATIC else DiskCacheStrategy.NONE)
        .apply(
            RequestOptions.bitmapTransform(
                MultiTransformation(
                    CenterCrop(),
                    GranularRoundedCorners(
                        topLeft.dp.toFloat(),
                        topRight.dp.toFloat(),
                        bottomRight.dp.toFloat(),
                        bottomLeft.dp.toFloat()
                    )
                )
            )
        ).into(this)
}

fun ImageView.loadNoCenterCrop(url: String?) {
    visibility = View.VISIBLE
    Glide.with(context)
        .load(url)
        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        .into(this)
}

fun ImageView.loadFitCenter(url: String?, cache: Boolean = true) {
    visibility = View.VISIBLE
    Glide.with(context)
        .load(url)
        .skipMemoryCache(!cache)
        .diskCacheStrategy(if (cache) DiskCacheStrategy.AUTOMATIC else DiskCacheStrategy.NONE)
        .into(this)
}


fun ImageView.loadWebp(url: String?) {
    isVisible = true
    Glide.with(context)
        .load(url)
        .addListener(object : RequestListener<Drawable> {
            override fun onLoadFailed(
                e: GlideException?,
                model: Any?,
                target: Target<Drawable>,
                isFirstResource: Boolean
            ): Boolean {
                return false
            }

            override fun onResourceReady(
                resource: Drawable,
                model: Any,
                target: Target<Drawable>?,
                dataSource: DataSource,
                isFirstResource: Boolean
            ): Boolean {
                (resource as? WebpDrawable)?.loopCount = -1
                return false
            }
        })
        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        .into(this)
}

fun ImageView.load(url: String?) {
    visibility = View.VISIBLE
    Glide.with(context)
        .load(url)
        .centerCrop()
        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        .into(this)
}

fun TextView.loadNinePatch(nineImageUrl: String?) {
    Glide.with(context)
        .asBitmap()
        .load(nineImageUrl)
        .into(object : CustomTarget<Bitmap>() {
            override fun onResourceReady(
                bitmap: Bitmap,
                transition: Transition<in Bitmap>?
            ) {
                val drawable = NinePatchChunk.create9PatchDrawable(context, bitmap, null)
                Timber.e("点9图 drawable :$drawable")
                background = drawable
            }

            override fun onLoadCleared(placeholder: Drawable?) {

            }
        })
}

fun ImageView.load(drawable: Drawable?) {
    visibility = View.VISIBLE
    Glide.with(context)
        .load(drawable)
        .centerCrop()
        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        .into(this)
}

fun ImageView.loadToOriginal(url: String?, width: Int, height: Int, cache: Boolean = true) {
    Glide.with(context)
        .load(url)
        .override(width, height)
        .diskCacheStrategy(if (cache) DiskCacheStrategy.AUTOMATIC else DiskCacheStrategy.NONE)
        .into(this)
}

fun ImageView.loadAndCircleCrop(url: String?) {
    Glide.with(context).load(url).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).circleCrop().into(this)
}

fun ImageView.loadAndRoundCorner(
    url: String?,
    radius: Int,
    margin: Int = 0,
    cache: Boolean = true,
    cornerType: RoundedCornersTransformation.CornerType = RoundedCornersTransformation.CornerType.ALL
) {
    val transformation = MultiTransformation(
        CenterCrop(),
        RoundedCornersTransformation(radius.dp, margin, cornerType)
    )
    Glide.with(context).load(url)
        .skipMemoryCache(!cache)
        .transform(transformation)
        .diskCacheStrategy(if (cache) DiskCacheStrategy.AUTOMATIC else DiskCacheStrategy.NONE)
        .into(this)
}

fun ImageView.loadResAndRoundCorner(
    res: Int,
    radius: Int,
    margin: Int = 0,
    cornerType: RoundedCornersTransformation.CornerType = RoundedCornersTransformation.CornerType.ALL
) {
    val transformation = MultiTransformation(
        CenterCrop(),
        RoundedCornersTransformation(radius.dp, margin, cornerType)
    )
    Glide.with(context).load(res)
        .transform(transformation)
        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        .into(this)
}

fun ImageView.loadAndRoundCornerToOriginal(url: String?, radius: Int, margin: Int = 0, width: Int, height: Int) {
    val transformation = MultiTransformation(
        CenterCrop(),
        RoundedCornersTransformation(radius.dp, margin)
    )
    Glide.with(context)
        .load(url)
        .override(width, height)
        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        .centerCrop()
        .transform(transformation)
        .into(this)
}

fun ImageView.loadAndCropTransformation(
    url: String?,
    width: Int,
    height: Int,
    cropXType: CropRectTransformation.CropXType = CropRectTransformation.CropXType.TOP,
    cropYType: CropRectTransformation.CropYType = CropRectTransformation.CropYType.CENTER,
    radius: Int = 0
) {
    Glide.with(context)
        .load(url)
        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        .apply(
            RequestOptions.bitmapTransform(
                MultiTransformation(
                    CropRectTransformation(width, height, cropXType, cropYType),
                    RoundedCornersTransformation(radius.dp, 0)
                )
            )
        )
        .into(this)
}

fun ImageView.loadAndCropTransformation(
    @DrawableRes res: Int,
    width: Int,
    height: Int,
    cropXType: CropRectTransformation.CropXType = CropRectTransformation.CropXType.TOP,
    cropYType: CropRectTransformation.CropYType = CropRectTransformation.CropYType.CENTER,
    radius: Int = 0
) {
    Glide.with(context)
        .load(ContextCompat.getDrawable(context, res))
        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        .apply(
            RequestOptions.bitmapTransform(
                MultiTransformation(
                    CropRectTransformation(width, height, cropXType, cropYType),
                    RoundedCornersTransformation(radius.dp, 0)
                )
            )
        )
        .into(this)
}


fun ImageView.loadCircleAvatar(url: String?, wid: Int, hei: Int? = null) {
    this.isVisible = true
    val processImage = url?.toS3Url(wid, hei, isDp = false, isFill = false)
    Glide.with(context)
        .load(processImage)
        .circleCrop()
        .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
        .into(this)
}


