package com.ponzischeme89.memby.ui

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.PlayArrow
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.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.tv.material3.Icon
import androidx.tv.material3.Text
import com.ponzischeme89.memby.ui.theme.MembyAccent
import com.ponzischeme89.memby.ui.theme.MembyCardCorner
import com.ponzischeme89.memby.ui.theme.MembyChipCorner
import com.ponzischeme89.memby.ui.theme.MembyHairline
import com.ponzischeme89.memby.ui.theme.MembyMutedText

/**
 * One green Play button, in two sizes.
 *
 * The app had three button languages: this one, a hand-rolled copy in the home hero with
 * the same look and different metrics, and raw `androidx.tv.material3.Button`s carrying
 * glyphs in their labels ("▶  Resume", "✓ 30 min"), which picked up theme colours nothing
 * else on those screens uses. A remote user learns one shape and one green; drawing it
 * three ways teaches them nothing and makes every metric a separate decision.
 *
 * [MembyPlayChip] is the same surface without focus behaviour when the whole hero card is
 * already the focusable node.
 */
@Composable
internal fun MembyPlayButton(
    label: String,
    onClick: () -> Unit,
    onFocused: () -> Unit,
    modifier: Modifier = Modifier,
    compact: Boolean = false,
) {
    var focused by remember { mutableStateOf(false) }
    val scale by animateFloatAsState(if (focused) 1.055f else 1f, tween(100), label = "play-focus")
    PrimaryActionSurface(
        label = label,
        icon = Icons.Default.PlayArrow,
        focused = focused,
        compact = compact,
        modifier = modifier
            .graphicsLayer { scaleX = scale; scaleY = scale; translationY = if (focused) -3f else 0f }
            .onFocusChanged { focused = it.isFocused; if (it.isFocused) onFocused() }
            .clickable(onClick = onClick),
    )
}

@Composable
internal fun MembyPlayChip(
    label: String,
    focused: Boolean,
    modifier: Modifier = Modifier,
    compact: Boolean = true,
) {
    PrimaryActionSurface(
        label = label,
        icon = Icons.Default.PlayArrow,
        focused = focused,
        compact = compact,
        modifier = modifier,
    )
}

@Composable
private fun PrimaryActionSurface(
    label: String,
    icon: ImageVector,
    focused: Boolean,
    compact: Boolean,
    modifier: Modifier,
) {
    val shape = RoundedCornerShape(MembyCardCorner)
    Row(
        modifier = modifier
            .shadow(if (focused) 18.dp else 7.dp, shape)
            .clip(shape)
            .background(MembyAccent)
            .border(if (focused) 2.dp else 1.dp, if (focused) Color.White else MembyAccent, shape)
            .padding(
                horizontal = if (compact) 14.dp else 23.dp,
                vertical = if (compact) 7.dp else 12.dp,
            ),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Icon(
            icon,
            contentDescription = null,
            tint = Color.White,
            modifier = Modifier.size(if (compact) 18.dp else 23.dp),
        )
        Spacer(Modifier.width(if (compact) 6.dp else 8.dp))
        Text(
            label,
            color = Color.White,
            fontSize = if (compact) 13.sp else 16.sp,
            fontWeight = FontWeight.Bold,
            maxLines = 1,
        )
    }
}

/**
 * A selectable chip for a small set of mutually exclusive choices. The tick is a real icon
 * on the selected chip rather than a character in the label, so the chip does not change
 * width when the choice moves.
 */
@Composable
internal fun MembyChoiceChip(
    label: String,
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
) {
    var focused by remember { mutableStateOf(false) }
    val shape = RoundedCornerShape(MembyChipCorner)
    Row(
        modifier = modifier
            .clip(shape)
            .background(
                when {
                    focused -> Color.White
                    selected -> MembyAccent
                    else -> Color.White.copy(alpha = 0.07f)
                },
            )
            .border(1.dp, if (selected || focused) Color.Transparent else MembyHairline, shape)
            .onFocusChanged { focused = it.isFocused }
            .clickable(onClick = onClick)
            .padding(horizontal = 14.dp, vertical = 8.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        if (selected) {
            Icon(
                Icons.Default.Check,
                contentDescription = null,
                tint = if (focused) Color.Black else Color.White,
                modifier = Modifier.size(15.dp),
            )
            Spacer(Modifier.width(6.dp))
        }
        Text(
            label,
            color = when {
                focused -> Color.Black
                selected -> Color.White
                else -> MembyMutedText
            },
            fontSize = 13.sp,
            fontWeight = FontWeight.SemiBold,
            maxLines = 1,
        )
    }
}
