package com.aiosman.riderpro.ui.composables

import android.content.Context
import android.graphics.drawable.BitmapDrawable
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.core.graphics.drawable.toDrawable
import coil.ImageLoader
import coil.annotation.ExperimentalCoilApi
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.aiosman.riderpro.utils.BlurHashDecoder
import com.aiosman.riderpro.utils.Utils.getImageLoader

const val DEFAULT_HASHED_BITMAP_WIDTH = 4
const val DEFAULT_HASHED_BITMAP_HEIGHT = 3

/**
 * This function is used to load an image asynchronously and blur it using BlurHash.
 * @param imageUrl The URL of the image to be loaded.
 * @param modifier The modifier to be applied to the image.
 * @param imageModifier The modifier to be applied to the image.
 * @param contentDescription The content description to be applied to the image.
 * @param contentScale The content scale to be applied to the image.
 * @param isCrossFadeRequired Whether cross-fade is required or not.
 * @param onImageLoadSuccess The callback to be called when the image is loaded successfully.
 * @param onImageLoadFailure The callback to be called when the image is failed to load.
 * @see AsyncImage
 */
@Suppress("LongParameterList")
@ExperimentalCoilApi
@Composable
fun AsyncBlurImage(
    imageUrl: String,
    blurHash: String,
    modifier: Modifier = Modifier,
    imageModifier: Modifier? = null,
    contentDescription: String? = null,
    contentScale: ContentScale = ContentScale.Fit,
    isCrossFadeRequired: Boolean = false,
    onImageLoadSuccess: () -> Unit = {},
    onImageLoadFailure: () -> Unit = {}
) {
    val context = LocalContext.current
    val resources = context.resources
    val imageLoader = getImageLoader(context)

    val blurBitmap by remember(blurHash) {
        mutableStateOf(
            BlurHashDecoder.decode(
                blurHash = blurHash,
                width = DEFAULT_HASHED_BITMAP_WIDTH,
                height = DEFAULT_HASHED_BITMAP_HEIGHT
            )
        )
    }

    AsyncImage(
        modifier = imageModifier ?: modifier,
        model = ImageRequest.Builder(context)
            .data(imageUrl)
            .crossfade(isCrossFadeRequired)
            .placeholder(
                blurBitmap?.toDrawable(resources)
            )
            .fallback(blurBitmap?.toDrawable(resources))
            .build(),
        contentDescription = contentDescription,
        contentScale = contentScale,
        onSuccess = { onImageLoadSuccess() },
        onError = { onImageLoadFailure() },
        imageLoader = imageLoader
    )
}