package com.syncflow.ui.pairdetail

import androidx.compose.animation.core.LinearEasing
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.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.outlined.Circle
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.syncflow.data.db.entities.SyncPairEntity
import com.syncflow.domain.model.SyncStatus
import com.syncflow.ui.shared.SyncProgress
import com.syncflow.ui.shared.SyncEventRow
import java.time.Duration
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PairDetailScreen(
    onBack: () -> Unit,
    onEdit: (Long) -> Unit,
    onConflicts: (Long) -> Unit,
    vm: PairDetailViewModel = hiltViewModel(),
) {
    val pair by vm.pair.collectAsState()
    val events by vm.events.collectAsState()
    val conflictCount by vm.unresolvedConflicts.collectAsState()
    val syncProgress by vm.syncProgress.collectAsState()
    var showDelete by remember { mutableStateOf(false) }

    if (showDelete) {
        AlertDialog(
            onDismissRequest = { showDelete = false },
            title = { Text("Delete sync pair?") },
            text = { Text("This removes the pair and all sync history. Files are NOT deleted.") },
            confirmButton = {
                TextButton(
                    onClick = { vm.delete(); onBack() },
                    colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.error),
                ) {
                    Text("Delete")
                }
            },
            dismissButton = { TextButton(onClick = { showDelete = false }) { Text("Cancel") } },
        )
    }

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(pair?.name ?: "…") },
                navigationIcon = { IconButton(onClick = onBack) { Icon(Icons.Default.ArrowBack, "Back") } },
                actions = {
                    IconButton(onClick = { pair?.let { onEdit(it.id) } }) { Icon(Icons.Default.Edit, "Edit") }
                    when (pair?.lastSyncResult) {
                        SyncStatus.SYNCING -> IconButton(onClick = { vm.pauseSync() }) {
                            Icon(Icons.Default.Pause, "Pause sync")
                        }
                        SyncStatus.PAUSED -> IconButton(onClick = { vm.syncNow() }, enabled = pair?.isEnabled == true) {
                            Icon(Icons.Default.PlayArrow, "Resume sync")
                        }
                        else -> IconButton(onClick = { vm.syncNow() }) {
                            Icon(Icons.Default.Sync, "Sync now")
                        }
                    }
                    IconButton(onClick = { showDelete = true }) { Icon(Icons.Default.Delete, "Delete") }
                },
            )
        },
    ) { padding ->
        LazyColumn(
            modifier = Modifier.padding(padding),
            contentPadding = PaddingValues(16.dp),
            verticalArrangement = Arrangement.spacedBy(12.dp),
        ) {
            item {
                pair?.let { p -> StatusBanner(p, syncProgress) }
            }

            item {
                pair?.let { p ->
                    InfoCard(p.localPath, p.remotePath, p.syncDirection.name, p.scheduleType.name)
                }
            }

            if (conflictCount > 0) {
                item {
                    FilledTonalButton(
                        onClick = { pair?.let { onConflicts(it.id) } },
                        modifier = Modifier.fillMaxWidth(),
                        colors = ButtonDefaults.filledTonalButtonColors(
                            containerColor = MaterialTheme.colorScheme.errorContainer,
                        ),
                    ) {
                        Icon(Icons.Default.Warning, null)
                        Spacer(Modifier.width(8.dp))
                        Text("$conflictCount unresolved conflict${if (conflictCount != 1) "s" else ""}")
                    }
                }
            }

            item {
                Row(
                    verticalAlignment = Alignment.CenterVertically,
                    modifier = Modifier.padding(top = 4.dp),
                ) {
                    Box(
                        modifier = Modifier
                            .width(3.dp)
                            .height(16.dp)
                            .clip(RoundedCornerShape(2.dp)),
                    ) {
                        Surface(color = MaterialTheme.colorScheme.primary, modifier = Modifier.fillMaxSize()) {}
                    }
                    Spacer(Modifier.width(8.dp))
                    Text("Activity", style = MaterialTheme.typography.titleSmall)
                }
                HorizontalDivider(modifier = Modifier.padding(top = 4.dp))
            }

            if (events.isEmpty()) {
                item {
                    Box(Modifier.fillMaxWidth().padding(32.dp), contentAlignment = Alignment.Center) {
                        Text("No sync activity yet", color = MaterialTheme.colorScheme.onSurfaceVariant)
                    }
                }
            } else {
                items(events, key = { it.id }) { event ->
                    SyncEventRow(event, showDivider = event != events.last())
                }
            }
        }
    }
}

@Composable
private fun StatusBanner(pair: SyncPairEntity, progress: SyncProgress? = null) {
    val (icon, label, containerColor) = when (pair.lastSyncResult) {
        SyncStatus.SUCCESS  -> Triple(Icons.Default.CheckCircle, "Synced",    MaterialTheme.colorScheme.primaryContainer)
        SyncStatus.SYNCING  -> Triple(Icons.Default.Sync,        "Syncing…",  MaterialTheme.colorScheme.secondaryContainer)
        SyncStatus.PAUSED   -> Triple(Icons.Default.Pause,       "Paused — tap ▶ to resume", MaterialTheme.colorScheme.surfaceVariant)
        SyncStatus.FAILED   -> Triple(Icons.Default.Error,       "Failed",    MaterialTheme.colorScheme.errorContainer)
        SyncStatus.CONFLICT -> Triple(Icons.Default.Warning,     "Conflict",  MaterialTheme.colorScheme.tertiaryContainer)
        SyncStatus.PARTIAL  -> Triple(Icons.Default.WarningAmber,"Partial",   MaterialTheme.colorScheme.tertiaryContainer)
        SyncStatus.IDLE     -> Triple(Icons.Outlined.Circle,     "Idle",      MaterialTheme.colorScheme.surfaceVariant)
    }
    val rotation by rememberInfiniteTransition(label = "bannerSpin").animateFloat(
        initialValue = 0f, targetValue = 360f,
        animationSpec = infiniteRepeatable(tween(1000, easing = LinearEasing)),
        label = "bannerRotation",
    )
    Surface(
        color = containerColor,
        shape = RoundedCornerShape(16.dp),
        modifier = Modifier.fillMaxWidth(),
    ) {
        Row(
            modifier = Modifier.padding(16.dp),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Icon(
                icon, null,
                modifier = Modifier.size(40.dp).graphicsLayer {
                    if (pair.lastSyncResult == SyncStatus.SYNCING) rotationZ = rotation
                },
            )
            Spacer(Modifier.width(16.dp))
            Column {
                Text(label, style = MaterialTheme.typography.titleMedium)
                val displayProgress = when {
                    pair.lastSyncResult == SyncStatus.SYNCING -> progress
                    pair.lastSyncUploaded > 0 || pair.lastSyncDownloaded > 0 || pair.lastSyncDeleted > 0 ->
                        SyncProgress(pair.lastSyncUploaded, pair.lastSyncDownloaded, pair.lastSyncDeleted, pair.lastSyncBytesTransferred)
                    else -> null
                }
                if (pair.lastSyncResult == SyncStatus.SYNCING && displayProgress == null) {
                    Text("Starting…", style = MaterialTheme.typography.bodySmall)
                } else if (displayProgress != null) {
                    Row(
                        verticalAlignment = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.spacedBy(6.dp),
                    ) {
                        if (displayProgress.uploaded > 0) {
                            Icon(Icons.Default.ArrowUpward, null, Modifier.size(12.dp))
                            Text("${displayProgress.uploaded} up", style = MaterialTheme.typography.bodySmall)
                        }
                        if (displayProgress.downloaded > 0) {
                            Icon(Icons.Default.ArrowDownward, null, Modifier.size(12.dp))
                            Text("${displayProgress.downloaded} down", style = MaterialTheme.typography.bodySmall)
                        }
                        if (displayProgress.deleted > 0) {
                            Icon(Icons.Default.DeleteOutline, null, Modifier.size(12.dp))
                            Text("${displayProgress.deleted} del", style = MaterialTheme.typography.bodySmall)
                        }
                        if (displayProgress.bytesTransferred > 0) {
                            Text("· ${displayProgress.bytesTransferred.toDisplaySize()}", style = MaterialTheme.typography.bodySmall)
                        }
                    }
                } else {
                    pair.lastSyncAt?.let {
                        Text(it.toRelativeString(), style = MaterialTheme.typography.bodySmall)
                    }
                }
            }
        }
    }
}

@Composable
private fun InfoCard(localPath: String, remotePath: String, direction: String, schedule: String) {
    Card(
        modifier = Modifier.fillMaxWidth(),
        shape = RoundedCornerShape(16.dp),
        border = androidx.compose.foundation.BorderStroke(1.dp, MaterialTheme.colorScheme.outline),
        colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
    ) {
        Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
            InfoRow(Icons.Default.PhoneAndroid, "Local", localPath.toDisplayPath())
            HorizontalDivider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.5f))
            InfoRow(Icons.Default.Cloud, "Remote", remotePath)
            HorizontalDivider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.5f))
            Row {
                InfoRow(Icons.Default.SwapHoriz, "Direction", direction, modifier = Modifier.weight(1f))
                InfoRow(Icons.Default.Schedule, "Schedule", schedule, modifier = Modifier.weight(1f))
            }
        }
    }
}

@Composable
private fun InfoRow(
    icon: androidx.compose.ui.graphics.vector.ImageVector,
    label: String,
    value: String,
    modifier: Modifier = Modifier,
) {
    Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) {
        Surface(
            shape = RoundedCornerShape(8.dp),
            color = MaterialTheme.colorScheme.primaryContainer,
            modifier = Modifier.size(28.dp),
        ) {
            Box(contentAlignment = Alignment.Center) {
                Icon(
                    icon,
                    null,
                    Modifier.size(16.dp),
                    tint = MaterialTheme.colorScheme.onPrimaryContainer,
                )
            }
        }
        Spacer(Modifier.width(8.dp))
        Column {
            Text(label, style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
            Text(value, style = MaterialTheme.typography.bodySmall)
        }
    }
}

private fun Long.toDisplaySize(): String = when {
    this < 1_024 -> "$this B"
    this < 1_048_576 -> "${"%.1f".format(this / 1_024.0)} KB"
    this < 1_073_741_824 -> "${"%.1f".format(this / 1_048_576.0)} MB"
    else -> "${"%.1f".format(this / 1_073_741_824.0)} GB"
}

private fun String.toDisplayPath(): String {
    val decoded = java.net.URLDecoder.decode(this, "UTF-8")
    return decoded.trimEnd('/').substringAfterLast('/').substringAfterLast(':').ifEmpty { decoded }
}

private fun Instant.toRelativeString(): String {
    val diff = Duration.between(this, Instant.now()).abs()
    return when {
        diff.toMinutes() < 1  -> "Just now"
        diff.toMinutes() < 60 -> "${diff.toMinutes()} min ago"
        diff.toHours() < 24   -> "${diff.toHours()} hr ago"
        diff.toDays() == 1L   -> "Yesterday"
        else -> DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
            .format(atZone(ZoneId.systemDefault()))
    }
}
