package com.placeholder.sherpai2.ui.rollingscan

import android.net.Uri
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import coil.compose.AsyncImage
import com.placeholder.sherpai2.domain.similarity.FaceSimilarityScorer

/**
 * RollingScanScreen - Real-time photo ranking UI
 *
 * FEATURES:
 * - Section headers (Most Similar / Good / Other)
 * - Similarity badges on top matches
 * - Selection checkmarks
 * - Face count indicators
 * - Scanning progress bar
 * - Quick action buttons (Select Top N)
 * - Submit button with validation
 */
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@Composable
fun RollingScanScreen(
    seedImageIds: List<String>,
    onSubmitForTraining: (List<String>) -> Unit,
    onNavigateBack: () -> Unit,
    modifier: Modifier = Modifier,
    viewModel: RollingScanViewModel = hiltViewModel()
) {
    val uiState by viewModel.uiState.collectAsState()
    val selectedImageIds by viewModel.selectedImageIds.collectAsState()
    val negativeImageIds by viewModel.negativeImageIds.collectAsState()
    val rankedPhotos by viewModel.rankedPhotos.collectAsState()
    val isScanning by viewModel.isScanning.collectAsState()

    // Initialize on first composition
    LaunchedEffect(seedImageIds) {
        viewModel.initialize(seedImageIds)
    }

    Scaffold(
        topBar = {
            RollingScanTopBar(
                selectedCount = selectedImageIds.size,
                onNavigateBack = onNavigateBack,
                onClearSelection = { viewModel.clearSelection() }
            )
        },
        bottomBar = {
            RollingScanBottomBar(
                selectedCount = selectedImageIds.size,
                isReadyForTraining = viewModel.isReadyForTraining(),
                validationMessage = viewModel.getValidationMessage(),
                onSelectTopN = { count -> viewModel.selectTopN(count) },
                onSelectAboveThreshold = { threshold -> viewModel.selectAllAboveThreshold(threshold) },
                onSubmit = {
                    val uris = viewModel.getSelectedImageUris()
                    onSubmitForTraining(uris)
                }
            )
        },
        modifier = modifier
    ) { padding ->

        when (val state = uiState) {
            is RollingScanState.Idle -> {
                // Waiting for initialization
                LoadingContent()
            }

            is RollingScanState.Loading -> {
                LoadingContent()
            }

            is RollingScanState.Ready -> {
                RollingScanPhotoGrid(
                    rankedPhotos = rankedPhotos,
                    selectedImageIds = selectedImageIds,
                    negativeImageIds = negativeImageIds,
                    isScanning = isScanning,
                    onToggleSelection = { imageId -> viewModel.toggleSelection(imageId) },
                    onToggleNegative = { imageId -> viewModel.toggleNegative(imageId) },
                    modifier = Modifier.padding(padding)
                )
            }

            is RollingScanState.Error -> {
                ErrorContent(
                    message = state.message,
                    onRetry = { viewModel.initialize(seedImageIds) },
                    onBack = onNavigateBack
                )
            }

            is RollingScanState.SubmittedForTraining -> {
                // Navigate back handled by parent
                LaunchedEffect(Unit) {
                    onNavigateBack()
                }
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════
// TOP BAR
// ═══════════════════════════════════════════════════════════

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun RollingScanTopBar(
    selectedCount: Int,
    onNavigateBack: () -> Unit,
    onClearSelection: () -> Unit
) {
    TopAppBar(
        title = {
            Column {
                Text(
                    "Find Similar Photos",
                    style = MaterialTheme.typography.titleLarge,
                    fontWeight = FontWeight.Bold
                )
                Text(
                    "$selectedCount selected",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
            }
        },
        navigationIcon = {
            IconButton(onClick = onNavigateBack) {
                Icon(Icons.Default.ArrowBack, "Back")
            }
        },
        actions = {
            if (selectedCount > 0) {
                TextButton(onClick = onClearSelection) {
                    Text("Clear")
                }
            }
        }
    )
}

// ═══════════════════════════════════════════════════════════
// PHOTO GRID - Similarity-based bucketing
// ═══════════════════════════════════════════════════════════

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun RollingScanPhotoGrid(
    rankedPhotos: List<FaceSimilarityScorer.ScoredPhoto>,
    selectedImageIds: Set<String>,
    negativeImageIds: Set<String>,
    isScanning: Boolean,
    onToggleSelection: (String) -> Unit,
    onToggleNegative: (String) -> Unit,
    modifier: Modifier = Modifier
) {
    // Bucket by similarity score
    val veryLikely = rankedPhotos.filter { it.finalScore >= 0.60f }
    val probably = rankedPhotos.filter { it.finalScore in 0.45f..0.599f }
    val maybe = rankedPhotos.filter { it.finalScore < 0.45f }

    Column(modifier = modifier.fillMaxSize()) {
        // Scanning indicator
        if (isScanning) {
            LinearProgressIndicator(
                modifier = Modifier.fillMaxWidth(),
                color = MaterialTheme.colorScheme.primary
            )
        }

        // Hint for negative marking
        Text(
            text = "Tap to select • Long-press to mark as NOT this person",
            style = MaterialTheme.typography.bodySmall,
            color = MaterialTheme.colorScheme.onSurfaceVariant,
            modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp)
        )

        LazyVerticalGrid(
            columns = GridCells.Fixed(3),
            contentPadding = PaddingValues(8.dp),
            horizontalArrangement = Arrangement.spacedBy(8.dp),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            // Section: Very Likely (>60%)
            if (veryLikely.isNotEmpty()) {
                item(span = { GridItemSpan(3) }) {
                    SectionHeader(
                        icon = Icons.Default.Whatshot,
                        text = "🟢 Very Likely (${veryLikely.size})",
                        color = Color(0xFF4CAF50)
                    )
                }
                items(veryLikely, key = { it.imageId }) { photo ->
                    PhotoCard(
                        photo = photo,
                        isSelected = photo.imageId in selectedImageIds,
                        isNegative = photo.imageId in negativeImageIds,
                        onToggle = { onToggleSelection(photo.imageId) },
                        onLongPress = { onToggleNegative(photo.imageId) },
                        showSimilarityBadge = true
                    )
                }
            }

            // Section: Probably (45-60%)
            if (probably.isNotEmpty()) {
                item(span = { GridItemSpan(3) }) {
                    SectionHeader(
                        icon = Icons.Default.CheckCircle,
                        text = "🟡 Probably (${probably.size})",
                        color = Color(0xFFFFC107)
                    )
                }
                items(probably, key = { it.imageId }) { photo ->
                    PhotoCard(
                        photo = photo,
                        isSelected = photo.imageId in selectedImageIds,
                        isNegative = photo.imageId in negativeImageIds,
                        onToggle = { onToggleSelection(photo.imageId) },
                        onLongPress = { onToggleNegative(photo.imageId) },
                        showSimilarityBadge = true
                    )
                }
            }

            // Section: Maybe (<45%)
            if (maybe.isNotEmpty()) {
                item(span = { GridItemSpan(3) }) {
                    SectionHeader(
                        icon = Icons.Default.Photo,
                        text = "🟠 Maybe (${maybe.size})",
                        color = Color(0xFFFF9800)
                    )
                }
                items(maybe, key = { it.imageId }) { photo ->
                    PhotoCard(
                        photo = photo,
                        isSelected = photo.imageId in selectedImageIds,
                        isNegative = photo.imageId in negativeImageIds,
                        onToggle = { onToggleSelection(photo.imageId) },
                        onLongPress = { onToggleNegative(photo.imageId) }
                    )
                }
            }

            // Empty state
            if (rankedPhotos.isEmpty()) {
                item(span = { GridItemSpan(3) }) {
                    EmptyStateContent()
                }
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════
// PHOTO CARD - with long-press for negative marking
// ═══════════════════════════════════════════════════════════

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun PhotoCard(
    photo: FaceSimilarityScorer.ScoredPhoto,
    isSelected: Boolean,
    isNegative: Boolean = false,
    onToggle: () -> Unit,
    onLongPress: () -> Unit = {},
    showSimilarityBadge: Boolean = false
) {
    val borderColor = when {
        isNegative -> Color(0xFFE53935)  // Red for negative
        isSelected -> MaterialTheme.colorScheme.primary
        else -> MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)
    }
    val borderWidth = if (isSelected || isNegative) 3.dp else 1.dp

    Card(
        modifier = Modifier
            .aspectRatio(1f)
            .combinedClickable(
                onClick = onToggle,
                onLongClick = onLongPress
            ),
        border = BorderStroke(borderWidth, borderColor),
        elevation = CardDefaults.cardElevation(
            defaultElevation = if (isSelected) 4.dp else 1.dp
        )
    ) {
        Box(modifier = Modifier.fillMaxSize()) {
            // Photo
            AsyncImage(
                model = Uri.parse(photo.imageUri),
                contentDescription = null,
                modifier = Modifier.fillMaxSize(),
                contentScale = ContentScale.Crop
            )

            // Dim overlay for negatives
            if (isNegative) {
                Box(
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(0.dp),
                    contentAlignment = Alignment.Center
                ) {
                    Surface(
                        modifier = Modifier.fillMaxSize(),
                        color = Color.Black.copy(alpha = 0.5f)
                    ) {}
                    Icon(
                        Icons.Default.Close,
                        contentDescription = "Not this person",
                        tint = Color.White,
                        modifier = Modifier.size(32.dp)
                    )
                }
            }

            // Similarity badge (top-left)
            if (showSimilarityBadge && !isNegative) {
                Surface(
                    modifier = Modifier
                        .align(Alignment.TopStart)
                        .padding(6.dp),
                    shape = RoundedCornerShape(8.dp),
                    color = when {
                        photo.finalScore >= 0.60f -> Color(0xFF4CAF50)
                        photo.finalScore >= 0.45f -> Color(0xFFFFC107)
                        else -> Color(0xFFFF9800)
                    },
                    shadowElevation = 4.dp
                ) {
                    Text(
                        text = "${(photo.finalScore * 100).toInt()}%",
                        modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
                        style = MaterialTheme.typography.labelSmall,
                        fontWeight = FontWeight.Bold,
                        color = Color.White
                    )
                }
            }

            // Selection checkmark (top-right)
            if (isSelected) {
                Surface(
                    modifier = Modifier
                        .align(Alignment.TopEnd)
                        .padding(6.dp)
                        .size(28.dp),
                    shape = CircleShape,
                    color = MaterialTheme.colorScheme.primary,
                    shadowElevation = 4.dp
                ) {
                    Icon(
                        Icons.Default.CheckCircle,
                        contentDescription = "Selected",
                        modifier = Modifier
                            .padding(4.dp)
                            .size(20.dp),
                        tint = MaterialTheme.colorScheme.onPrimary
                    )
                }
            }

            // Face count badge (bottom-right)
            if (photo.faceCount > 1 && !isNegative) {
                Surface(
                    modifier = Modifier
                        .align(Alignment.BottomEnd)
                        .padding(6.dp),
                    shape = CircleShape,
                    color = MaterialTheme.colorScheme.secondary
                ) {
                    Text(
                        text = "${photo.faceCount}",
                        modifier = Modifier.padding(6.dp),
                        style = MaterialTheme.typography.labelSmall,
                        fontWeight = FontWeight.Bold,
                        color = MaterialTheme.colorScheme.onSecondary
                    )
                }
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════
// SECTION HEADER
// ═══════════════════════════════════════════════════════════

@Composable
private fun SectionHeader(
    icon: ImageVector,
    text: String,
    color: Color
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 12.dp),
        horizontalArrangement = Arrangement.spacedBy(8.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(
            icon,
            contentDescription = null,
            tint = color,
            modifier = Modifier.size(24.dp)
        )
        Text(
            text = text,
            style = MaterialTheme.typography.titleMedium,
            fontWeight = FontWeight.Bold,
            color = color
        )
    }
}

// ═══════════════════════════════════════════════════════════
// BOTTOM BAR
// ═══════════════════════════════════════════════════════════

@Composable
private fun RollingScanBottomBar(
    selectedCount: Int,
    isReadyForTraining: Boolean,
    validationMessage: String?,
    onSelectTopN: (Int) -> Unit,
    onSelectAboveThreshold: (Float) -> Unit,
    onSubmit: () -> Unit
) {
    Surface(
        tonalElevation = 8.dp,
        shadowElevation = 8.dp
    ) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp)
        ) {
            // Validation message
            if (validationMessage != null) {
                Text(
                    text = validationMessage,
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.error,
                    modifier = Modifier.padding(bottom = 8.dp)
                )
            }

            // First row: threshold selection
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.spacedBy(6.dp)
            ) {
                OutlinedButton(
                    onClick = { onSelectAboveThreshold(0.60f) },
                    modifier = Modifier.weight(1f),
                    contentPadding = PaddingValues(horizontal = 8.dp, vertical = 4.dp)
                ) {
                    Text(">60%", style = MaterialTheme.typography.labelSmall)
                }
                OutlinedButton(
                    onClick = { onSelectAboveThreshold(0.50f) },
                    modifier = Modifier.weight(1f),
                    contentPadding = PaddingValues(horizontal = 8.dp, vertical = 4.dp)
                ) {
                    Text(">50%", style = MaterialTheme.typography.labelSmall)
                }
                OutlinedButton(
                    onClick = { onSelectTopN(15) },
                    modifier = Modifier.weight(1f),
                    contentPadding = PaddingValues(horizontal = 8.dp, vertical = 4.dp)
                ) {
                    Text("Top 15", style = MaterialTheme.typography.labelSmall)
                }
            }

            Spacer(Modifier.height(8.dp))

            // Second row: submit
            Button(
                onClick = onSubmit,
                enabled = isReadyForTraining,
                modifier = Modifier.fillMaxWidth()
            ) {
                Icon(
                    Icons.Default.Done,
                    contentDescription = null,
                    modifier = Modifier.size(18.dp)
                )
                Spacer(Modifier.width(8.dp))
                Text("Train Model ($selectedCount photos)")
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════
// STATE SCREENS
// ═══════════════════════════════════════════════════════════

@Composable
private fun LoadingContent() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            CircularProgressIndicator()
            Text(
                "Loading photos...",
                style = MaterialTheme.typography.bodyLarge
            )
        }
    }
}

@Composable
private fun ErrorContent(
    message: String,
    onRetry: () -> Unit,
    onBack: () -> Unit
) {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Column(
            modifier = Modifier.padding(32.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            Icon(
                Icons.Default.Error,
                contentDescription = null,
                modifier = Modifier.size(64.dp),
                tint = MaterialTheme.colorScheme.error
            )

            Text(
                "Oops!",
                style = MaterialTheme.typography.headlineMedium,
                fontWeight = FontWeight.Bold
            )

            Text(
                message,
                style = MaterialTheme.typography.bodyLarge,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )

            Row(
                horizontalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                OutlinedButton(onClick = onBack) {
                    Text("Back")
                }

                Button(onClick = onRetry) {
                    Text("Retry")
                }
            }
        }
    }
}

@Composable
private fun EmptyStateContent() {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(200.dp),
        contentAlignment = Alignment.Center
    ) {
        Text(
            "Select a photo to find similar ones",
            style = MaterialTheme.typography.bodyLarge,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )
    }
}