package com.fabledsword.minstrel.shared.widgets

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Play
import kotlinx.coroutines.launch

/**
 * Always-visible circular play button overlaid on Home tile cover art
 * (AlbumCard / ArtistCard / PlaylistCard). Mirrors
 * `flutter_client/lib/library/widgets/play_circle_button.dart`: 44dp
 * accent-colored disc, parchment Play icon, drop shadow, self-managed
 * loading spinner.
 *
 * [onPlay] is a suspend lambda so the caller can await the fetch-and-
 * queue setup. While it runs, the icon is swapped for a spinner and
 * the button rejects further taps (re-entrancy guard). [enabled] false
 * renders the disc semi-transparent and disables the tap.
 */
@Composable
fun PlayCircleButton(
    onPlay: suspend () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    size: Dp = PLAY_BUTTON_DEFAULT_SIZE.dp,
) {
    val scope = rememberCoroutineScope()
    var starting by remember { mutableStateOf(false) }
    val iconSize = size * PLAY_BUTTON_ICON_RATIO
    val alpha = if (enabled) 1f else PLAY_BUTTON_DISABLED_ALPHA
    Surface(
        onClick = {
            if (starting) return@Surface
            starting = true
            scope.launch {
                try {
                    onPlay()
                } finally {
                    starting = false
                }
            }
        },
        modifier = modifier
            .size(size)
            .alpha(alpha),
        enabled = enabled && !starting,
        shape = CircleShape,
        color = MaterialTheme.colorScheme.primary,
        tonalElevation = PLAY_BUTTON_ELEVATION.dp,
        shadowElevation = PLAY_BUTTON_ELEVATION.dp,
    ) {
        Box(contentAlignment = Alignment.Center) {
            if (starting) {
                CircularProgressIndicator(
                    modifier = Modifier.size(iconSize),
                    color = MaterialTheme.colorScheme.onPrimary,
                    strokeWidth = PLAY_BUTTON_SPINNER_STROKE.dp,
                )
            } else {
                Icon(
                    imageVector = Lucide.Play,
                    contentDescription = "Play",
                    tint = MaterialTheme.colorScheme.onPrimary,
                    modifier = Modifier.size(iconSize),
                )
            }
        }
    }
}

private const val PLAY_BUTTON_DEFAULT_SIZE = 44
private const val PLAY_BUTTON_ICON_RATIO = 0.5f
private const val PLAY_BUTTON_DISABLED_ALPHA = 0.5f
private const val PLAY_BUTTON_ELEVATION = 2
private const val PLAY_BUTTON_SPINNER_STROKE = 2
