package com.seven.ikar.kotlin.ui

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import coil.compose.AsyncImage
import coil.compose.AsyncImagePainter
import coil.request.CachePolicy
import coil.request.ImageRequest
import java.security.MessageDigest

@Composable
fun AuthenticatedAsyncImage(
    imageUrl: String?,
    accessToken: String? = null,
    contentDescription: String,
    modifier: Modifier = Modifier,
    contentScale: ContentScale = ContentScale.Crop,
    onSuccess: ((AsyncImagePainter.State.Success) -> Unit)? = null
) {
    if (imageUrl.isNullOrBlank()) {
        return
    }

    val resolvedAccessToken = accessToken ?: LocalIkarAccessToken.current
    val context = LocalContext.current
    val request = remember(imageUrl, resolvedAccessToken) {
        val diskCacheKey = buildAuthenticatedDiskCacheKey(imageUrl, resolvedAccessToken)
        ImageRequest.Builder(context)
            .data(imageUrl)
            .diskCacheKey(diskCacheKey)
            .memoryCacheKey(diskCacheKey)
            .diskCachePolicy(CachePolicy.ENABLED)
            .memoryCachePolicy(CachePolicy.ENABLED)
            .apply {
                if (!resolvedAccessToken.isNullOrBlank()) {
                    addHeader("Authorization", "Bearer $resolvedAccessToken")
                }
            }
            .crossfade(true)
            .build()
    }

    AsyncImage(
        model = request,
        contentDescription = contentDescription,
        modifier = modifier,
        contentScale = contentScale,
        onSuccess = onSuccess
    )
}

private fun buildAuthenticatedDiskCacheKey(imageUrl: String, accessToken: String?): String {
    if (accessToken.isNullOrBlank()) {
        return imageUrl
    }

    val digest = MessageDigest.getInstance("SHA-256")
        .digest(accessToken.toByteArray(Charsets.UTF_8))
        .joinToString(separator = "") { byte -> "%02x".format(byte) }
    return "$imageUrl#auth:$digest"
}
