package com.openclaw.alfred.ui.components

import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import coil.compose.rememberAsyncImagePainter
import coil.request.ImageRequest
import com.openclaw.alfred.ui.screens.ChatMessage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
 * Enhanced message bubble with support for:
 * - Selectable text
 * - Clickable links
 * - Inline images/GIFs
 * - YouTube embeds (as clickable thumbnails)
 */
@Composable
fun RichMessageBubble(message: ChatMessage) {
    val context = LocalContext.current
    val uriHandler = LocalUriHandler.current
    
    val alignment = if (message.sender == "You") Alignment.End else Alignment.Start
    val color = when {
        message.isSystem -> MaterialTheme.colorScheme.surfaceVariant
        message.sender == "You" -> MaterialTheme.colorScheme.primaryContainer
        else -> MaterialTheme.colorScheme.secondaryContainer
    }
    
    Column(
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = alignment
    ) {
        Card(
            colors = CardDefaults.cardColors(containerColor = color)
        ) {
            Column(
                modifier = Modifier.padding(12.dp)
            ) {
                // Sender name
                if (message.sender != "You") {
                    Text(
                        text = message.sender,
                        style = MaterialTheme.typography.labelSmall,
                        color = MaterialTheme.colorScheme.onSurfaceVariant
                    )
                    Spacer(modifier = Modifier.height(4.dp))
                }
                
                // Parse message content
                val contentParts = parseMessageContent(message.text)
                
                contentParts.forEach { part ->
                    when (part) {
                        is ContentPart.Text -> {
                            SelectionContainer {
                                ClickableTextWithLinks(
                                    text = part.text,
                                    onClick = { url ->
                                        try {
                                            uriHandler.openUri(url)
                                        } catch (e: Exception) {
                                            // Fallback to intent
                                            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
                                            context.startActivity(intent)
                                        }
                                    }
                                )
                            }
                        }
                        is ContentPart.Image -> {
                            Spacer(modifier = Modifier.height(8.dp))
                            ImageContent(
                                url = part.url,
                                onClick = { url ->
                                    val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
                                    context.startActivity(intent)
                                }
                            )
                            Spacer(modifier = Modifier.height(8.dp))
                        }
                        is ContentPart.YouTube -> {
                            Spacer(modifier = Modifier.height(8.dp))
                            YouTubeEmbed(
                                videoId = part.videoId,
                                onClick = {
                                    val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://youtube.com/watch?v=${part.videoId}"))
                                    context.startActivity(intent)
                                }
                            )
                            Spacer(modifier = Modifier.height(8.dp))
                        }
                    }
                }
            }
        }
    }
}

/**
 * Text component with clickable links
 */
@Composable
private fun ClickableTextWithLinks(
    text: String,
    onClick: (String) -> Unit
) {
    val linkColor = MaterialTheme.colorScheme.primary
    
    // Find all URLs in text
    val urlPattern = Regex("""https?://[^\s]+""")
    val matches = urlPattern.findAll(text).toList()
    
    if (matches.isEmpty()) {
        // No links, just show plain text
        Text(
            text = text,
            style = MaterialTheme.typography.bodyMedium
        )
        return
    }
    
    // Build annotated string with clickable links
    val annotatedString = buildAnnotatedString {
        var lastIndex = 0
        
        matches.forEach { match ->
            // Add text before link
            if (match.range.first > lastIndex) {
                append(text.substring(lastIndex, match.range.first))
            }
            
            // Add clickable link
            pushStringAnnotation(tag = "URL", annotation = match.value)
            pushStyle(
                SpanStyle(
                    color = linkColor,
                    textDecoration = TextDecoration.Underline
                )
            )
            append(match.value)
            pop()
            pop()
            
            lastIndex = match.range.last + 1
        }
        
        // Add remaining text
        if (lastIndex < text.length) {
            append(text.substring(lastIndex))
        }
    }
    
    androidx.compose.foundation.text.ClickableText(
        text = annotatedString,
        style = MaterialTheme.typography.bodyMedium.copy(
            color = MaterialTheme.colorScheme.onSurface
        ),
        onClick = { offset ->
            annotatedString.getStringAnnotations(tag = "URL", start = offset, end = offset)
                .firstOrNull()?.let { annotation ->
                    onClick(annotation.item)
                }
        }
    )
}

/**
 * Image content (GIFs converted to video, static images displayed normally)
 */
@Composable
private fun ImageContent(
    url: String,
    onClick: (String) -> Unit
) {
    val context = LocalContext.current
    val isGif = url.matches(Regex(".*\\.(gif|GIF)(\\?.*)?$"))
    
    if (isGif) {
        // GIFs are converted to MP4 for better mobile playback
        GifVideoPlayer(url = url, onClick = onClick)
    } else {
        // Static images displayed normally
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .clickable { onClick(url) }
        ) {
            coil.compose.AsyncImage(
                model = ImageRequest.Builder(context)
                    .data(url)
                    .crossfade(true)
                    .build(),
                contentDescription = "Image",
                modifier = Modifier
                    .fillMaxWidth()
                    .heightIn(max = 300.dp),
                contentScale = ContentScale.Fit
            )
        }
    }
}

/**
 * GIF player using MP4 conversion
 */
@Composable
private fun GifVideoPlayer(
    url: String,
    onClick: (String) -> Unit
) {
    val context = LocalContext.current
    var videoUrl by remember { mutableStateOf<String?>(null) }
    var isLoading by remember { mutableStateOf(true) }
    var error by remember { mutableStateOf<String?>(null) }
    
    // Request GIF conversion on mount
    LaunchedEffect(url) {
        try {
            // Get gateway URL from preferences
            val prefs = context.getSharedPreferences("alfred_settings", android.content.Context.MODE_PRIVATE)
            val gatewayUrl = prefs.getString("gateway_url", com.openclaw.alfred.BuildConfig.GATEWAY_URL)
                ?.replace("wss://", "https://")
                ?.replace("ws://", "http://")
                ?: ""
            
            val convertUrl = "$gatewayUrl/api/convert-gif?url=${java.net.URLEncoder.encode(url, "UTF-8")}"
            
            // Request conversion
            val client = okhttp3.OkHttpClient()
            val request = okhttp3.Request.Builder().url(convertUrl).build()
            
            kotlinx.coroutines.withContext(kotlinx.coroutines.Dispatchers.IO) {
                val response = client.newCall(request).execute()
                
                if (response.isSuccessful) {
                    val json = org.json.JSONObject(response.body?.string() ?: "{}")
                    val relativeUrl = json.optString("videoUrl")
                    
                    if (relativeUrl.isNotEmpty()) {
                        videoUrl = "$gatewayUrl$relativeUrl"
                        isLoading = false
                    } else {
                        error = "Conversion failed"
                        isLoading = false
                    }
                } else {
                    error = "Conversion failed: ${response.code}"
                    isLoading = false
                }
            }
        } catch (e: Exception) {
            error = "Error: ${e.message}"
            isLoading = false
        }
    }
    
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .clickable { videoUrl?.let { onClick(it) } }
    ) {
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(200.dp),
            contentAlignment = Alignment.Center
        ) {
            when {
                isLoading -> {
                    CircularProgressIndicator()
                }
                error != null -> {
                    Text(
                        text = "⚠️ $error",
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.error
                    )
                }
                videoUrl != null -> {
                    // Use AndroidView to embed video player
                    AndroidVideoPlayer(videoUrl = videoUrl!!)
                }
            }
        }
    }
}

/**
 * Android VideoView wrapper for Compose
 */
@Composable
private fun AndroidVideoPlayer(videoUrl: String) {
    androidx.compose.ui.viewinterop.AndroidView(
        factory = { context ->
            android.widget.VideoView(context).apply {
                setVideoPath(videoUrl)
                setOnPreparedListener { mp ->
                    mp.isLooping = true
                    start()
                }
            }
        },
        modifier = Modifier.fillMaxSize()
    )
}

/**
 * YouTube embed (thumbnail with play button)
 */
@Composable
private fun YouTubeEmbed(
    videoId: String,
    onClick: () -> Unit
) {
    val thumbnailUrl = "https://img.youtube.com/vi/$videoId/hqdefault.jpg"
    
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .clickable { onClick() }
    ) {
        Box {
            coil.compose.AsyncImage(
                model = ImageRequest.Builder(LocalContext.current)
                    .data(thumbnailUrl)
                    .crossfade(true)
                    .build(),
                contentDescription = "YouTube video",
                modifier = Modifier
                    .fillMaxWidth()
                    .heightIn(max = 200.dp),
                contentScale = ContentScale.Crop
            )
            
            // Play button overlay
            Surface(
                modifier = Modifier.align(Alignment.Center),
                shape = MaterialTheme.shapes.medium,
                color = MaterialTheme.colorScheme.surface.copy(alpha = 0.8f)
            ) {
                Text(
                    text = "▶ Play on YouTube",
                    modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
                    style = MaterialTheme.typography.labelLarge
                )
            }
        }
    }
}

/**
 * Parse message content into different parts (text, images, YouTube, etc.)
 */
private fun parseMessageContent(text: String): List<ContentPart> {
    val parts = mutableListOf<ContentPart>()
    
    // Patterns (order matters - markdown first to capture before plain URLs)
    val markdownImagePattern = Regex("""!\[([^\]]*)\]\(([^)]+\.(jpg|jpeg|png|gif|webp)[^)]*)\)""", RegexOption.IGNORE_CASE)
    val imagePattern = Regex("""(https?://[^\s]+\.(jpg|jpeg|png|gif|webp))""", RegexOption.IGNORE_CASE)
    val youtubePattern = Regex("""https?://(?:www\.)?(?:youtube\.com/watch\?v=|youtu\.be/)([a-zA-Z0-9_-]{11})""")
    
    // Find all media (markdown images first, then plain URLs, then YouTube)
    val markdownImageMatches = markdownImagePattern.findAll(text).toList()
    val imageMatches = imagePattern.findAll(text).toList()
    val youtubeMatches = youtubePattern.findAll(text).toList()
    
    // Filter out plain URL matches that are inside markdown syntax
    val markdownRanges = markdownImageMatches.map { it.range }
    val filteredImageMatches = imageMatches.filter { imgMatch ->
        markdownRanges.none { mdRange -> imgMatch.range.first >= mdRange.first && imgMatch.range.last <= mdRange.last }
    }
    
    // Combine and sort by position
    val allMatches = (
        markdownImageMatches.map { it to "markdown-image" } +
        filteredImageMatches.map { it to "image" } +
        youtubeMatches.map { it to "youtube" }
    ).sortedBy { it.first.range.first }
    
    if (allMatches.isEmpty()) {
        // No media, just text
        parts.add(ContentPart.Text(text))
        return parts
    }
    
    var lastIndex = 0
    
    allMatches.forEach { (match, type) ->
        // Add text before media
        if (match.range.first > lastIndex) {
            val textBefore = text.substring(lastIndex, match.range.first).trim()
            if (textBefore.isNotEmpty()) {
                parts.add(ContentPart.Text(textBefore))
            }
        }
        
        // Add media
        when (type) {
            "markdown-image" -> {
                // Extract URL from markdown syntax: ![alt](url)
                val url = match.groupValues[2]
                parts.add(ContentPart.Image(url))
            }
            "image" -> parts.add(ContentPart.Image(match.value))
            "youtube" -> {
                val videoId = match.groupValues[1]
                parts.add(ContentPart.YouTube(videoId))
            }
        }
        
        lastIndex = match.range.last + 1
    }
    
    // Add remaining text
    if (lastIndex < text.length) {
        val textAfter = text.substring(lastIndex).trim()
        if (textAfter.isNotEmpty()) {
            parts.add(ContentPart.Text(textAfter))
        }
    }
    
    return parts
}

/**
 * Content parts within a message
 */
private sealed class ContentPart {
    data class Text(val text: String) : ContentPart()
    data class Image(val url: String) : ContentPart()
    data class YouTube(val videoId: String) : ContentPart()
}
