package com.fabledsword.minstrel.shared.widgets

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import coil3.compose.AsyncImage
import coil3.compose.AsyncImagePainter
import com.fabledsword.minstrel.shared.resolveServerUrl

/**
 * Renders a server-hosted image, resolving relative URLs centrally so
 * every cover surface loads consistently. Shows [fallback] when the URL
 * is blank/unresolvable, while the image is still loading, and when the
 * load fails — so a tile is never left blank (e.g. art not yet backfilled,
 * which the "You might like" row hits often).
 */
@Composable
fun ServerImage(
    url: String?,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    contentScale: ContentScale = ContentScale.Crop,
    fallback: @Composable () -> Unit = {},
) {
    val resolved = resolveServerUrl(url)
    if (resolved == null) {
        fallback()
        return
    }
    // Track Coil's load state so the fallback doubles as a placeholder
    // (loading) and an error state (404 / unreachable) — not just a
    // null-URL guard, which left present-but-failing URLs blank.
    var state by remember(resolved) {
        mutableStateOf<AsyncImagePainter.State>(AsyncImagePainter.State.Empty)
    }
    Box(modifier = modifier, contentAlignment = Alignment.Center) {
        AsyncImage(
            model = resolved,
            contentDescription = contentDescription,
            modifier = Modifier.fillMaxSize(),
            contentScale = contentScale,
            onState = { state = it },
        )
        if (state is AsyncImagePainter.State.Loading ||
            state is AsyncImagePainter.State.Error
        ) {
            fallback()
        }
    }
}
