package app.closer.ui.dates

import app.closer.ui.theme.closerBackgroundBrush
import app.closer.ui.theme.closerCardColor
import app.closer.ui.theme.closerSoftPinkColor
import app.closer.ui.theme.closerSoftPurpleColor
import app.closer.ui.theme.closerSoftSurfaceColor
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectHorizontalDragGestures
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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Star
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
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.scale
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import app.closer.domain.model.DateCostLevel
import app.closer.domain.model.DateIdea
import app.closer.domain.model.DateMatch
import app.closer.domain.model.SwipeAction
import app.closer.ui.components.EmptyState
import app.closer.ui.components.ErrorState
import app.closer.ui.components.LoadingState
import kotlin.math.roundToInt

@Composable
fun DateMatchScreen(
    onNavigate: (String) -> Unit = {},
    viewModel: DateMatchViewModel = hiltViewModel()
) {
    val state by viewModel.uiState.collectAsState()

    DateMatchContent(
        state = state,
        onLove = viewModel::loveCurrent,
        onMaybe = viewModel::maybeCurrent,
        onSkip = viewModel::skipCurrent,
        onDismissMatch = viewModel::dismissJustMatched,
        onRetry = viewModel::retry,
        onViewMatches = { onNavigate("date_matches") }
    )
}

@Composable
private fun DateMatchContent(
    state: DateMatchUiState,
    onLove: () -> Unit,
    onMaybe: () -> Unit,
    onSkip: () -> Unit,
    onDismissMatch: () -> Unit,
    onRetry: () -> Unit,
    onViewMatches: () -> Unit
) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(
                closerBackgroundBrush()
            )
    ) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .safeDrawingPadding()
                .navigationBarsPadding()
                .padding(horizontal = 20.dp)
                .verticalScroll(rememberScrollState()),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            DateMatchHeader(
                matchCount = state.matches.size,
                partnerName = state.partnerName,
                onViewMatches = onViewMatches,
                modifier = Modifier
                    .fillMaxWidth()
                    .statusBarsPadding()
                    .padding(top = 12.dp, bottom = 6.dp)
            )

            when {
                state.isLoading -> {
                    LoadingState(
                        message = "Loading date ideas…",
                        modifier = Modifier.padding(top = 120.dp)
                    )
                }

                state.error != null -> {
                    ErrorState(
                        title = "Couldn't load date ideas",
                        message = state.error ?: "Tap below to try again.",
                        onRetry = onRetry,
                        modifier = Modifier.padding(top = 120.dp)
                    )
                }

                !state.hasMore -> {
                    EmptyState(
                        title = "You have browsed every idea",
                        body = buildString {
                            if (state.matches.isNotEmpty()) {
                                append("You and ")
                                append(state.partnerName ?: "your partner")
                                append(" have ")
                                append(state.matches.size)
                                append(" mutual match")
                                if (state.matches.size != 1) append("es")
                                append(". Revisit them anytime.")
                            } else {
                                append("No new ideas right now. Check back after your partner has swiped, or look at your matches.")
                            }
                        },
                        actionLabel = if (state.matches.isNotEmpty()) "View matches" else null,
                        onAction = if (state.matches.isNotEmpty()) onViewMatches else null,
                        modifier = Modifier.padding(top = 120.dp)
                    )
                }

                else -> {
                    CardStackArea(
                        current = state.currentIdea,
                        next = state.nextIdea,
                        onLove = onLove,
                        onMaybe = onMaybe,
                        onSkip = onSkip,
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(480.dp)
                    )

                    Spacer(modifier = Modifier.height(24.dp))

                    ActionButtons(
                        onSkip = onSkip,
                        onMaybe = onMaybe,
                        onLove = onLove
                    )
                }
            }

            Spacer(modifier = Modifier.height(24.dp))
        }

        state.justMatched?.let { match ->
            MatchOverlay(
                match = match,
                partnerName = state.partnerName,
                onDismiss = onDismissMatch,
                onViewMatches = onViewMatches
            )
        }
    }
}

@Composable
private fun DateMatchHeader(
    matchCount: Int,
    partnerName: String?,
    onViewMatches: () -> Unit,
    modifier: Modifier = Modifier
) {
    Row(
        modifier = modifier,
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Column(
            modifier = Modifier.weight(1f)
        ) {
            Text(
                text = "Date Match",
                style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.SemiBold),
                color = MaterialTheme.colorScheme.onSurface,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
            Text(
                text = partnerName?.let { "Swiping with $it" } ?: "Find something you both love",
                style = MaterialTheme.typography.bodyMedium,
                color = MaterialTheme.colorScheme.onSurfaceVariant,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }

        IconButton(onClick = onViewMatches) {
            Surface(
                shape = CircleShape,
                color = Color(0xFFF3E8FF)
            ) {
                Box(modifier = Modifier.padding(8.dp)) {
                    Icon(
                        imageVector = Icons.Filled.Favorite,
                        contentDescription = "View matches",
                        tint = Color(0xFF56306F)
                    )
                    if (matchCount > 0) {
                        Surface(
                            shape = CircleShape,
                            color = Color(0xFF8D2D35),
                            modifier = Modifier
                                .size(16.dp)
                                .align(Alignment.TopEnd)
                        ) {
                            Text(
                                text = matchCount.toString(),
                                style = MaterialTheme.typography.labelSmall,
                                color = Color.White,
                                modifier = Modifier.align(Alignment.Center)
                            )
                        }
                    }
                }
            }
        }
    }
}

@Composable
private fun CardStackArea(
    current: DateIdea?,
    next: DateIdea?,
    onLove: () -> Unit,
    onMaybe: () -> Unit,
    onSkip: () -> Unit,
    modifier: Modifier = Modifier
) {
    var dragOffset by remember { mutableFloatStateOf(0f) }
    val animatedOffset by animateFloatAsState(
        targetValue = dragOffset,
        animationSpec = spring(stiffness = 200f, dampingRatio = 0.7f),
        label = "cardDrag"
    )

    val swipeThreshold = 180f

    Box(
        modifier = modifier,
        contentAlignment = Alignment.Center
    ) {
        // Background (next card)
        next?.let { idea ->
            DateCard(
                idea = idea,
                modifier = Modifier
                    .fillMaxWidth(0.9f)
                    .height(420.dp)
                    .scale(0.94f)
                    .offset(y = 16.dp),
                dimmed = true
            )
        }

        // Foreground (current card)
        current?.let { idea ->
            DateCard(
                idea = idea,
                modifier = Modifier
                    .fillMaxWidth()
                    .height(440.dp)
                    .offset { IntOffset(animatedOffset.roundToInt(), 0) }
                    .pointerInput(Unit) {
                        detectHorizontalDragGestures(
                            onDragEnd = {
                                when {
                                    dragOffset > swipeThreshold -> onLove()
                                    dragOffset < -swipeThreshold -> onSkip()
                                    else -> dragOffset = 0f
                                }
                            },
                            onHorizontalDrag = { _, dragAmount ->
                                dragOffset += dragAmount
                            }
                        )
                    },
                dimmed = false
            )
        }
    }
}

@Composable
private fun DateCard(
    idea: DateIdea,
    modifier: Modifier = Modifier,
    dimmed: Boolean = false
) {
    Card(
        modifier = modifier,
        shape = RoundedCornerShape(32.dp),
        colors = CardDefaults.cardColors(
            containerColor = closerCardColor(alpha = if (dimmed) 0.70f else 0.96f)
        ),
        elevation = CardDefaults.cardElevation(defaultElevation = if (dimmed) 1.dp else 6.dp)
    ) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(24.dp),
            verticalArrangement = Arrangement.SpaceBetween
        ) {
            Column(verticalArrangement = Arrangement.spacedBy(14.dp)) {
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceBetween,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    CategoryPill(idea.category.displayDateCategory())
                    if (idea.isPremium) {
                        PremiumBadge()
                    }
                }

                Text(
                    text = idea.title,
                    style = MaterialTheme.typography.headlineMedium.copy(fontWeight = FontWeight.SemiBold),
                    color = MaterialTheme.colorScheme.onSurface,
                    maxLines = 3,
                    overflow = TextOverflow.Ellipsis
                )

                Text(
                    text = idea.description,
                    style = MaterialTheme.typography.bodyLarge,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    maxLines = 6,
                    overflow = TextOverflow.Ellipsis
                )
            }

            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.Bottom
            ) {
                InfoChip(label = idea.estimatedDuration)
                InfoChip(label = idea.estimatedCost.displayLabel())
            }
        }
    }
}

@Composable
private fun PremiumBadge() {
    Surface(
        shape = RoundedCornerShape(999.dp),
        color = closerSoftPinkColor()
    ) {
        Row(
            modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp),
            horizontalArrangement = Arrangement.spacedBy(4.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Icon(
                imageVector = Icons.Filled.Star,
                contentDescription = null,
                modifier = Modifier.size(14.dp),
                tint = MaterialTheme.colorScheme.onSecondaryContainer
            )
            Text(
                text = "Premium",
                style = MaterialTheme.typography.labelSmall,
                color = MaterialTheme.colorScheme.onSecondaryContainer,
                fontWeight = FontWeight.SemiBold
            )
        }
    }
}

@Composable
private fun CategoryPill(label: String) {
    Surface(
        shape = RoundedCornerShape(999.dp),
        color = closerSoftPurpleColor()
    ) {
        Text(
            text = label,
            modifier = Modifier.padding(horizontal = 12.dp, vertical = 7.dp),
            style = MaterialTheme.typography.labelMedium,
            color = MaterialTheme.colorScheme.onPrimaryContainer,
            fontWeight = FontWeight.SemiBold,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis
        )
    }
}

@Composable
private fun InfoChip(label: String) {
    Surface(
        shape = RoundedCornerShape(12.dp),
        color = closerSoftSurfaceColor()
    ) {
        Text(
            text = label,
            modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp),
            style = MaterialTheme.typography.labelMedium,
            color = MaterialTheme.colorScheme.onSurfaceVariant,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis
        )
    }
}

@Composable
private fun ActionButtons(
    onSkip: () -> Unit,
    onMaybe: () -> Unit,
    onLove: () -> Unit
) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.SpaceEvenly,
        verticalAlignment = Alignment.CenterVertically
    ) {
        CircularActionButton(
            icon = Icons.Filled.Close,
            contentDescription = "Skip",
            color = MaterialTheme.colorScheme.errorContainer,
            iconColor = Color(0xFF8D2D35),
            onClick = onSkip
        )
        CircularActionButton(
            icon = Icons.Filled.Star,
            contentDescription = "Maybe",
            color = MaterialTheme.colorScheme.tertiaryContainer.copy(alpha = 0.74f),
            iconColor = Color(0xFF6B5D00),
            onClick = onMaybe,
            size = 72.dp
        )
        CircularActionButton(
            icon = Icons.Filled.Favorite,
            contentDescription = "Love",
            color = closerSoftPinkColor(),
            iconColor = Color(0xFF9B1B5A),
            onClick = onLove
        )
    }
}

@Composable
private fun CircularActionButton(
    icon: ImageVector,
    contentDescription: String,
    color: Color,
    iconColor: Color,
    onClick: () -> Unit,
    size: androidx.compose.ui.unit.Dp = 64.dp
) {
    IconButton(
        onClick = onClick,
        modifier = Modifier.size(size)
    ) {
        Surface(
            shape = CircleShape,
            color = color,
            shadowElevation = 4.dp
        ) {
            Box(
                modifier = Modifier.fillMaxSize(),
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    imageVector = icon,
                    contentDescription = contentDescription,
                    modifier = Modifier.size(size / 2.2f),
                    tint = iconColor
                )
            }
        }
    }
}

@Composable
private fun MatchOverlay(
    match: DateMatch,
    partnerName: String?,
    onDismiss: () -> Unit,
    onViewMatches: () -> Unit
) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(MaterialTheme.colorScheme.onSurface.copy(alpha = 0.54f))
            .padding(24.dp),
        contentAlignment = Alignment.Center
    ) {
        Card(
            shape = RoundedCornerShape(28.dp),
            colors = CardDefaults.cardColors(containerColor = closerCardColor(alpha = 0.96f))
        ) {
            Column(
                modifier = Modifier.padding(28.dp),
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.spacedBy(16.dp)
            ) {
                Surface(
                    shape = CircleShape,
                    color = closerSoftPinkColor(),
                    modifier = Modifier.size(72.dp)
                ) {
                    Box(contentAlignment = Alignment.Center) {
                        Icon(
                            imageVector = Icons.Filled.Favorite,
                            contentDescription = null,
                            modifier = Modifier.size(36.dp),
                            tint = Color(0xFF9B1B5A)
                        )
                    }
                }

                Text(
                    text = "It is a match!",
                    style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.SemiBold),
                    color = MaterialTheme.colorScheme.onSurface
                )

                Text(
                    text = buildString {
                        append("You and ")
                        append(partnerName ?: "your partner")
                        append(" both loved this idea.")
                    },
                    style = MaterialTheme.typography.bodyLarge,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )

                match.dateIdea?.let { idea ->
                    DateCard(
                        idea = idea,
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(220.dp)
                    )
                }

                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.spacedBy(12.dp)
                ) {
                    Button(
                        onClick = onDismiss,
                        modifier = Modifier.weight(1f),
                        shape = RoundedCornerShape(16.dp),
                        colors = ButtonDefaults.buttonColors(
                            containerColor = Color(0xFFF3E8FF),
                            contentColor = Color(0xFF56306F)
                        )
                    ) {
                        Text("Keep swiping")
                    }
                    Button(
                        onClick = onViewMatches,
                        modifier = Modifier.weight(1f),
                        shape = RoundedCornerShape(16.dp),
                        colors = ButtonDefaults.buttonColors(
                            containerColor = Color(0xFFB98AF4),
                            contentColor = MaterialTheme.colorScheme.onPrimary
                        )
                    ) {
                        Text("View matches")
                    }
                }
            }
        }
    }
}

private fun String.displayDateCategory(): String =
    replace("_", " ")
        .split(" ")
        .joinToString(" ") { it.replaceFirstChar { c -> c.uppercaseChar() } }

private fun DateCostLevel.displayLabel(): String = when (this) {
    DateCostLevel.FREE -> "Free"
    DateCostLevel.LOW -> "$"
    DateCostLevel.MEDIUM -> "$$"
    DateCostLevel.HIGH -> "$$$"
}
