package com.fabledsword.minstrel.shared.widgets

import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.dp
import com.fabledsword.minstrel.theme.FabledSwordFlatTokens

/**
 * Skeleton placeholders for cold-load states. Mirror Flutter's
 * `SkeletonAlbumTile` / `SkeletonArtistTile` / `_CompactTrackSkeleton`
 * — same geometry as the real cards so the layout doesn't reflow when
 * real data lands and the screen-level Crossfade reveals.
 */

private const val PULSE_MIN_ALPHA = 0.3f
private const val PULSE_MAX_ALPHA = 0.55f
private const val PULSE_DURATION_MS = 800

/**
 * Solid-color box with a slow alpha pulse. Building block for the
 * tile-shape composites below. Mirrors the surfaceVariant fill the
 * real cards use as their cover-loading background.
 */
@Composable
fun SkeletonBox(
    modifier: Modifier = Modifier,
    shape: Shape = RoundedCornerShape(FabledSwordFlatTokens.radiusSm),
) {
    val transition = rememberInfiniteTransition(label = "skeleton-pulse")
    val alpha by transition.animateFloat(
        initialValue = PULSE_MIN_ALPHA,
        targetValue = PULSE_MAX_ALPHA,
        animationSpec = infiniteRepeatable(
            animation = tween(PULSE_DURATION_MS, easing = LinearEasing),
            repeatMode = RepeatMode.Reverse,
        ),
        label = "skeleton-alpha",
    )
    Box(
        modifier = modifier
            .clip(shape)
            .background(MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = alpha)),
    )
}

/**
 * Stand-in for AlbumCard / PlaylistCard (same 176dp×144dp cover +
 * 2 caption lines geometry).
 */
@Composable
fun SkeletonAlbumTile(modifier: Modifier = Modifier) {
    Column(
        modifier = modifier
            .width(176.dp)
            .padding(horizontal = 8.dp),
    ) {
        SkeletonBox(modifier = Modifier.size(144.dp))
        Spacer(Modifier.height(8.dp))
        SkeletonBox(modifier = Modifier.fillMaxWidth().height(14.dp))
        Spacer(Modifier.height(4.dp))
        SkeletonBox(modifier = Modifier.width(96.dp).height(12.dp))
    }
}

/**
 * Stand-in for ArtistCard (128dp circular cover + 1 name line).
 */
@Composable
fun SkeletonArtistTile(modifier: Modifier = Modifier) {
    Column(
        modifier = modifier
            .width(144.dp)
            .padding(horizontal = 8.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        SkeletonBox(
            modifier = Modifier.size(128.dp),
            shape = CircleShape,
        )
        Spacer(Modifier.height(8.dp))
        SkeletonBox(modifier = Modifier.width(96.dp).height(14.dp))
    }
}

/**
 * Stand-in for a compact track row (28dp cover thumb + title + subtitle).
 */
@Composable
fun SkeletonTrackRow(modifier: Modifier = Modifier) {
    Row(
        modifier = modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 8.dp),
        horizontalArrangement = Arrangement.spacedBy(12.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        SkeletonBox(modifier = Modifier.size(40.dp))
        Column(
            modifier = Modifier
                .weight(1f, fill = true),
            verticalArrangement = Arrangement.spacedBy(6.dp),
        ) {
            SkeletonBox(modifier = Modifier.fillMaxWidth().height(14.dp))
            SkeletonBox(modifier = Modifier.width(120.dp).height(12.dp))
        }
    }
}

/** Section-heading skeleton (~40% width title bar). */
@Composable
fun SkeletonSectionHeader(modifier: Modifier = Modifier) {
    Box(
        modifier = modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 12.dp),
    ) {
        SkeletonBox(modifier = Modifier.width(160.dp).height(20.dp))
    }
}
