package com.keylightpiano.pianotimeline.ui

import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.combinedClickable
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.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.Block
import androidx.compose.material.icons.filled.DownloadForOffline
import androidx.compose.material.icons.filled.MusicNote
import androidx.compose.material.icons.filled.Star
import androidx.compose.material.icons.outlined.StarBorder
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
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.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.keylightpiano.pianotimeline.R
import com.keylightpiano.pianotimeline.domain.Recording
import kotlinx.coroutines.launch

private val NotesGreen = Color(0xFF25B300)
private val NewBadgeRed = Color(0xFFE53935)
private val PlayingRed = Color(0xFFFF3D3D)

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun RecordingItem(
    recording: Recording,
    isPlaying: Boolean,
    isDisabledOffline: Boolean,
    onPlayClick: () -> Unit,
    onFavoriteClick: () -> Unit,
    onNotesClick: (() -> Unit)?,           // null = no MIDI -> Notes button disabled
    onShareAudio: () -> Unit,
    onShareVisualization: (() -> Unit)?,   // null when no MIDI
    onCopyLink: () -> Unit,
    onMarkAsNew: () -> Unit,
    modifier: Modifier = Modifier
) {
    var menuExpanded by remember { mutableStateOf(false) }
    val hasMidi = onNotesClick != null

    Box(modifier = modifier.fillMaxWidth()) {
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .graphicsLayer { alpha = if (isDisabledOffline) 0.4f else 1f }
                .combinedClickable(
                    onClick = {},  // normal taps handled by inner buttons
                    onLongClick = { menuExpanded = true }
                ),
            colors = CardDefaults.cardColors(
                containerColor = MaterialTheme.colorScheme.surface
            ),
            elevation = CardDefaults.cardElevation(defaultElevation = 1.dp)
        ) {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 12.dp, vertical = 10.dp)
            ) {
                // Date row (own line at the very top) — favorite star on the right
                Row(
                    verticalAlignment = Alignment.CenterVertically,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(bottom = 6.dp)
                ) {
                    Box(
                        modifier = Modifier
                            .clip(RoundedCornerShape(4.dp))
                            .background(Color(0xFF054D00))
                            .padding(horizontal = 6.dp, vertical = 1.dp)
                    ) {
                        Text(
                            text = recording.formattedDate,
                            style = MaterialTheme.typography.labelSmall,
                            fontWeight = FontWeight.Bold,
                            color = Color(0xFFCCCCCC)
                        )
                    }

                    // "NEW" badge — shown until the recording is first played.
                    if (recording.isNew) {
                        Spacer(Modifier.width(8.dp))
                        Box(
                            modifier = Modifier
                                .clip(RoundedCornerShape(4.dp))
                                .background(NewBadgeRed)
                                .padding(horizontal = 6.dp, vertical = 1.dp)
                        ) {
                            Text(
                                text = stringResource(R.string.badge_new),
                                style = MaterialTheme.typography.labelSmall,
                                fontWeight = FontWeight.Bold,
                                color = Color.White
                            )
                        }
                    }

                    Spacer(Modifier.weight(1f))

                    // Favorite star with a spring "pop" on each tap.
                    val starScale = remember { Animatable(1f) }
                    val starScope = rememberCoroutineScope()
                    IconButton(
                        onClick = {
                            onFavoriteClick()
                            starScope.launch {
                                starScale.snapTo(0.6f)
                                starScale.animateTo(
                                    targetValue = 1f,
                                    animationSpec = spring(
                                        dampingRatio = Spring.DampingRatioMediumBouncy,
                                        stiffness = Spring.StiffnessMedium
                                    )
                                )
                            }
                        },
                        modifier = Modifier.size(28.dp)
                    ) {
                        Icon(
                            imageVector = if (recording.isFavorite) Icons.Filled.Star
                                          else Icons.Outlined.StarBorder,
                            contentDescription = stringResource(if (recording.isFavorite) R.string.cd_unfavorite else R.string.cd_favorite),
                            tint = if (recording.isFavorite) Color(0xFFFFC107)
                                   else MaterialTheme.colorScheme.onSurfaceVariant,
                            modifier = Modifier
                                .size(20.dp)
                                .graphicsLayer {
                                    scaleX = starScale.value
                                    scaleY = starScale.value
                                }
                        )
                    }
                }

                // Main row: play - artist/title - star - notes
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    FilledTonalIconButton(
                        onClick = onPlayClick,
                        enabled = !isDisabledOffline,
                        modifier = Modifier.size(44.dp)
                    ) {
                        Icon(
                            painter = painterResource(
                                if (isPlaying) android.R.drawable.ic_media_pause
                                else android.R.drawable.ic_media_play
                            ),
                            contentDescription = stringResource(if (isPlaying) R.string.cd_pause else R.string.cd_play),
                            modifier = Modifier.size(22.dp)
                        )
                    }

                    Spacer(Modifier.width(12.dp))

                    Column(modifier = Modifier.weight(1f)) {
                        Text(
                            text = recording.artist,
                            style = MaterialTheme.typography.labelMedium,
                            color = Color(0xFF61B5FF),
                            maxLines = 1,
                            overflow = TextOverflow.Ellipsis
                        )
                        Row(verticalAlignment = Alignment.CenterVertically) {
                            // Small green "downloaded" glyph, shown only when the
                            // full audio is cached (playable offline).
                            if (recording.isCached) {
                                Icon(
                                    imageVector = Icons.Filled.DownloadForOffline,
                                    contentDescription = stringResource(R.string.cd_downloaded),
                                    tint = NotesGreen,
                                    modifier = Modifier.size(14.dp)
                                )
                                Spacer(Modifier.width(4.dp))
                            }
                            Text(
                                text = recording.title,
                                style = MaterialTheme.typography.bodyLarge,
                                fontWeight = FontWeight.Medium,
                                color = if (isPlaying) PlayingRed
                                        else MaterialTheme.colorScheme.onSurface,
                                maxLines = 1,
                                modifier = Modifier
                                    .weight(1f)
                                    .basicMarquee(
                                        iterations = Int.MAX_VALUE,
                                        repeatDelayMillis = 2000,
                                        initialDelayMillis = 3000,
                                        velocity = 30.dp
                                    )
                            )
                        }
                        Row(
                            horizontalArrangement = Arrangement.spacedBy(8.dp),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            Text(
                                text = recording.formattedDuration,
                                style = MaterialTheme.typography.bodySmall,
                                color = Color(0xFFA3FFBC)
                            )
                            Text("\u00B7", style = MaterialTheme.typography.bodySmall,
                                color = MaterialTheme.colorScheme.onSurfaceVariant)
                            Text(
                                text = recording.performanceLabel,
                                style = MaterialTheme.typography.bodySmall,
                                color = Color(0xFF999999)
                            )
                        }
                    }

                    Spacer(Modifier.width(4.dp))

                    // Notes button - round, always present. Enabled only when a MIDI
                    // file exists; disabled with a "blocked" icon otherwise.
                    FilledTonalIconButton(
                        onClick = { onNotesClick?.invoke() },
                        enabled = hasMidi && !isDisabledOffline,
                        modifier = Modifier.size(44.dp),
                        colors = IconButtonDefaults.filledTonalIconButtonColors(
                            containerColor = if (hasMidi) NotesGreen.copy(alpha = 0.18f)
                                             else MaterialTheme.colorScheme.surfaceVariant
                        )
                    ) {
                        Icon(
                            imageVector = if (hasMidi) Icons.Filled.MusicNote else Icons.Filled.Block,
                            contentDescription = stringResource(R.string.notes),
                            tint = if (hasMidi) NotesGreen
                                   else MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f),
                            modifier = Modifier.size(22.dp)
                        )
                    }
                }
            }
        }

        // Bottom divider between cards
        HorizontalDivider(
            modifier = Modifier.align(Alignment.BottomCenter),
            thickness = 1.dp,
            color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.08f)
        )

        // Long-press context menu (extensible - more actions can be added later)
        DropdownMenu(
            expanded = menuExpanded,
            onDismissRequest = { menuExpanded = false }
        ) {
            DropdownMenuItem(
                text = { Text(stringResource(R.string.menu_share_audio)) },
                onClick = {
                    menuExpanded = false
                    onShareAudio()
                }
            )
            if (onShareVisualization != null) {
                DropdownMenuItem(
                    text = { Text(stringResource(R.string.menu_share_visualization)) },
                    onClick = {
                        menuExpanded = false
                        onShareVisualization()
                    }
                )
            }
            DropdownMenuItem(
                text = { Text(stringResource(R.string.menu_copy_link)) },
                onClick = {
                    menuExpanded = false
                    onCopyLink()
                }
            )
            // Only offer "Mark as new" when it isn't already flagged.
            if (!recording.isNew) {
                DropdownMenuItem(
                    text = { Text(stringResource(R.string.menu_mark_as_new)) },
                    onClick = {
                        menuExpanded = false
                        onMarkAsNew()
                    }
                )
            }
        }
    }
}
