package com.rosetta.messenger.ui.qr

import android.content.Intent
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
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.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.view.drawToBitmap
import com.rosetta.messenger.R
import com.rosetta.messenger.repository.AvatarRepository
import com.rosetta.messenger.ui.components.AvatarImage
import com.rosetta.messenger.ui.settings.ThemeWallpapers
import com.rosetta.messenger.utils.QrCodeGenerator
import compose.icons.TablerIcons
import compose.icons.tablericons.*
import androidx.compose.ui.layout.onSizeChanged
import kotlinx.coroutines.launch
import kotlin.math.hypot

// QR theme = wallpaper + QR color
private data class QrTheme(
    val wallpaperId: String,
    val qrColor: Int,
    val tintColor: Color,
    val isDark: Boolean
)

private val qrThemes = listOf(
    QrTheme("dark_01", 0xFF5AA5FF.toInt(), Color(0xFF5AA5FF), true),
    QrTheme("dark_02", 0xFF9575CD.toInt(), Color(0xFF9575CD), true),
    QrTheme("dark_03", 0xFF4DB6AC.toInt(), Color(0xFF4DB6AC), true),
    QrTheme("light_01", 0xFF228BE6.toInt(), Color(0xFF228BE6), false),
    QrTheme("light_02", 0xFF43A047.toInt(), Color(0xFF43A047), false),
    QrTheme("light_03", 0xFFE64980.toInt(), Color(0xFFE64980), false),
)

private fun maxRevealRadius(center: Offset, bounds: IntSize): Float {
    if (bounds.width <= 0 || bounds.height <= 0) return 0f
    val w = bounds.width.toFloat()
    val h = bounds.height.toFloat()
    return maxOf(
        hypot(center.x, center.y),
        hypot(w - center.x, center.y),
        hypot(center.x, h - center.y),
        hypot(w - center.x, h - center.y)
    )
}

@Composable
fun MyQrCodeScreen(
    isDarkTheme: Boolean,
    publicKey: String,
    displayName: String,
    username: String,
    avatarRepository: AvatarRepository? = null,
    onBack: () -> Unit,
    onScanQr: () -> Unit = {},
    onToggleTheme: () -> Unit = {}
) {
    val context = LocalContext.current
    val view = LocalView.current
    val scope = rememberCoroutineScope()

    var selectedThemeIndex by remember { mutableIntStateOf(if (isDarkTheme) 0 else 3) }
    // Local dark/light state — independent from the global app theme
    var localIsDark by remember { mutableStateOf(isDarkTheme) }

    val theme = qrThemes[selectedThemeIndex]

    val wallpaperResId = remember(theme.wallpaperId) {
        ThemeWallpapers.drawableResOrNull(theme.wallpaperId)
    }

    val qrBitmap = remember(publicKey, selectedThemeIndex) {
        QrCodeGenerator.generateQrBitmap(
            content = QrCodeGenerator.profilePayload(publicKey),
            size = 768,
            foregroundColor = theme.qrColor,
            backgroundColor = android.graphics.Color.WHITE,
            context = context
        )
    }

    val shareUrl = remember(username, publicKey) {
        if (username.isNotBlank()) QrCodeGenerator.profileShareUrl(username)
        else QrCodeGenerator.profileShareUrlByKey(publicKey)
    }

    // Circular reveal state
    val revealRadius = remember { Animatable(0f) }
    var revealActive by remember { mutableStateOf(false) }
    var revealSnapshot by remember { mutableStateOf<ImageBitmap?>(null) }
    var revealCenter by remember { mutableStateOf(Offset.Zero) }
    var rootSize by remember { mutableStateOf(IntSize.Zero) }
    var lastRevealTime by remember { mutableLongStateOf(0L) }
    val revealCooldownMs = 600L
    var prewarmedBitmap by remember { mutableStateOf<android.graphics.Bitmap?>(null) }

    // Prewarm bitmap on screen appear
    LaunchedEffect(Unit) {
        kotlinx.coroutines.delay(300)
        prewarmedBitmap = runCatching { view.drawToBitmap() }.getOrNull()
    }

    fun startReveal(newIndex: Int, center: Offset) {
        val now = System.currentTimeMillis()
        if (revealActive || newIndex == selectedThemeIndex || now - lastRevealTime < revealCooldownMs) return
        lastRevealTime = now
        if (rootSize.width <= 0 || rootSize.height <= 0) {
            selectedThemeIndex = newIndex
            return
        }

        val snapshot = prewarmedBitmap ?: runCatching { view.drawToBitmap() }.getOrNull()
        prewarmedBitmap = null
        if (snapshot == null) {
            selectedThemeIndex = newIndex
            return
        }

        val maxR = maxRevealRadius(center, rootSize)
        if (maxR <= 0f) {
            selectedThemeIndex = newIndex
            return
        }

        revealActive = true
        revealCenter = center
        revealSnapshot = snapshot.asImageBitmap()

        scope.launch {
            try {
                revealRadius.snapTo(0f)
                selectedThemeIndex = newIndex
                kotlinx.coroutines.delay(16) // wait one frame for recomposition
                revealRadius.animateTo(
                    targetValue = maxR,
                    animationSpec = tween(
                        durationMillis = 400,
                        easing = CubicBezierEasing(0.45f, 0.05f, 0.55f, 0.95f)
                    )
                )
            } finally {
                revealSnapshot = null
                revealActive = false
            }
        }
    }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .onSizeChanged { rootSize = it }
    ) {
        // Wallpaper background
        if (wallpaperResId != null) {
            Image(
                painter = painterResource(id = wallpaperResId),
                contentDescription = null,
                modifier = Modifier.fillMaxSize(),
                contentScale = ContentScale.Crop
            )
        } else {
            Box(modifier = Modifier.fillMaxSize().background(if (theme.isDark) Color(0xFF1A1A1A) else Color(0xFFF0F0F5)))
        }

        // Main content
        Column(
            modifier = Modifier.fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Spacer(modifier = Modifier.statusBarsPadding().height(40.dp))

            // QR Card with overlapping avatar
            Box(
                modifier = Modifier.padding(horizontal = 32.dp),
                contentAlignment = Alignment.TopCenter
            ) {
                Card(
                    modifier = Modifier.fillMaxWidth().padding(top = 40.dp),
                    shape = RoundedCornerShape(24.dp),
                    colors = CardDefaults.cardColors(containerColor = Color.White),
                    elevation = CardDefaults.cardElevation(defaultElevation = 8.dp)
                ) {
                    Column(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(top = 52.dp, bottom = 24.dp, start = 24.dp, end = 24.dp),
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        if (qrBitmap != null) {
                            Image(
                                bitmap = qrBitmap.asImageBitmap(),
                                contentDescription = "QR Code",
                                modifier = Modifier.size(220.dp)
                            )
                        }

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

                        Text(
                            text = if (username.isNotBlank()) "@${username.uppercase()}"
                                   else displayName.uppercase(),
                            fontSize = 18.sp,
                            fontWeight = FontWeight.Bold,
                            color = Color(theme.qrColor),
                            textAlign = TextAlign.Center
                        )
                    }
                }

                // Avatar overlapping
                Box(
                    modifier = Modifier
                        .size(80.dp)
                        .clip(CircleShape)
                        .background(Color.White)
                        .padding(3.dp)
                        .clip(CircleShape)
                ) {
                    AvatarImage(
                        publicKey = publicKey,
                        avatarRepository = avatarRepository,
                        size = 74.dp,
                        isDarkTheme = false,
                        displayName = displayName
                    )
                }
            }

            Spacer(modifier = Modifier.weight(1f))

            // Bottom sheet
            Surface(
                modifier = Modifier.fillMaxWidth(),
                shape = RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp),
                color = if (localIsDark) Color(0xFF1C1C1E) else Color.White,
                shadowElevation = 16.dp
            ) {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .navigationBarsPadding()
                        .padding(top = 16.dp, bottom = 16.dp),
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    // Handle
                    Box(
                        modifier = Modifier
                            .width(36.dp).height(4.dp)
                            .clip(RoundedCornerShape(2.dp))
                            .background(Color.Gray.copy(alpha = 0.3f))
                    )

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

                    // Header: X + "QR Code" + theme toggle
                    Row(
                        modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        IconButton(onClick = onBack) {
                            Icon(TablerIcons.X, contentDescription = "Close",
                                tint = if (localIsDark) Color.White else Color.Black)
                        }
                        Spacer(modifier = Modifier.weight(1f))
                        Text("QR Code", fontSize = 17.sp, fontWeight = FontWeight.SemiBold,
                            color = if (localIsDark) Color.White else Color.Black)
                        Spacer(modifier = Modifier.weight(1f))
                        var themeButtonPos by remember { mutableStateOf(Offset.Zero) }
                        IconButton(
                            onClick = {
                                // Snapshot → toggle LOCAL theme → circular reveal
                                // Does NOT toggle the global app theme
                                val now = System.currentTimeMillis()
                                if (!revealActive && rootSize.width > 0 && now - lastRevealTime >= revealCooldownMs) {
                                    lastRevealTime = now
                                    val snapshot = prewarmedBitmap ?: runCatching { view.drawToBitmap() }.getOrNull()
                                    prewarmedBitmap = null
                                    if (snapshot != null) {
                                        val maxR = maxRevealRadius(themeButtonPos, rootSize)
                                        revealActive = true
                                        revealCenter = themeButtonPos
                                        revealSnapshot = snapshot.asImageBitmap()
                                        val posInGroup = if (localIsDark) selectedThemeIndex else selectedThemeIndex - 3
                                        val newIndex = if (localIsDark) (posInGroup + 3).coerceIn(3, 5) else posInGroup.coerceIn(0, 2)
                                        selectedThemeIndex = newIndex
                                        localIsDark = !localIsDark
                                        scope.launch {
                                            try {
                                                revealRadius.snapTo(0f)
                                                kotlinx.coroutines.delay(16)
                                                revealRadius.animateTo(
                                                    targetValue = maxR,
                                                    animationSpec = tween(400, easing = CubicBezierEasing(0.45f, 0.05f, 0.55f, 0.95f))
                                                )
                                            } finally {
                                                revealSnapshot = null
                                                revealActive = false
                                            }
                                        }
                                    }
                                }
                            },
                            modifier = Modifier.onGloballyPositioned { coords ->
                                val pos = coords.positionInRoot()
                                val sz = coords.size
                                themeButtonPos = Offset(pos.x + sz.width / 2f, pos.y + sz.height / 2f)
                            }
                        ) {
                            Icon(
                                imageVector = if (localIsDark) TablerIcons.Sun else TablerIcons.MoonStars,
                                contentDescription = "Toggle theme",
                                tint = if (localIsDark) Color.White else Color.Black
                            )
                        }
                    }

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

                    // Wallpaper selector — show current theme's wallpapers
                    val currentThemes = qrThemes.filter { it.isDark == localIsDark }

                    Row(
                        modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
                        horizontalArrangement = Arrangement.spacedBy(10.dp)
                    ) {
                        currentThemes.forEach { t ->
                            val index = qrThemes.indexOf(t)
                            val isSelected = index == selectedThemeIndex
                            val wpRes = ThemeWallpapers.drawableResOrNull(t.wallpaperId)
                            var itemPosition by remember { mutableStateOf(Offset.Zero) }

                            Box(
                                modifier = Modifier
                                    .weight(1f).aspectRatio(0.85f)
                                    .clip(RoundedCornerShape(12.dp))
                                    .border(
                                        width = if (isSelected) 2.dp else 0.dp,
                                        color = if (isSelected) Color(0xFF3390EC) else Color.Transparent,
                                        shape = RoundedCornerShape(12.dp)
                                    )
                                    .onGloballyPositioned { coords ->
                                        val pos = coords.positionInRoot()
                                        val sz = coords.size
                                        itemPosition = Offset(pos.x + sz.width / 2f, pos.y + sz.height / 2f)
                                    }
                                    .clickable { if (index != selectedThemeIndex) startReveal(index, itemPosition) },
                                contentAlignment = Alignment.Center
                            ) {
                                if (wpRes != null) {
                                    Image(painter = painterResource(id = wpRes), contentDescription = null,
                                        modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop)
                                }
                                Icon(TablerIcons.Scan, contentDescription = null,
                                    tint = if (localIsDark) Color.White.copy(alpha = 0.6f) else Color.Black.copy(alpha = 0.35f),
                                    modifier = Modifier.size(22.dp))
                            }
                        }
                    }

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

                    // Share button
                    Button(
                        onClick = {
                            val intent = Intent(Intent.ACTION_SEND).apply {
                                type = "text/plain"
                                putExtra(Intent.EXTRA_TEXT, "Add me on Rosetta: $shareUrl")
                            }
                            context.startActivity(Intent.createChooser(intent, "Share Profile"))
                        },
                        modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp).height(50.dp),
                        colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF3390EC)),
                        shape = RoundedCornerShape(12.dp)
                    ) {
                        Text("Share", fontSize = 16.sp, fontWeight = FontWeight.SemiBold, color = Color.White)
                    }

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

                    // Scan QR
                    TextButton(onClick = onScanQr) {
                        Icon(TablerIcons.Scan, contentDescription = null,
                            tint = Color(0xFF3390EC), modifier = Modifier.size(20.dp))
                        Spacer(modifier = Modifier.width(8.dp))
                        Text("Scan QR Code", color = Color(0xFF3390EC),
                            fontSize = 15.sp, fontWeight = FontWeight.Medium)
                    }
                }
            }
        }

        // Circular reveal overlay
        if (revealActive) {
            val snapshot = revealSnapshot
            if (snapshot != null) {
                Canvas(
                    modifier = Modifier
                        .fillMaxSize()
                        .graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen)
                ) {
                    val dstSize = IntSize(size.width.toInt(), size.height.toInt())
                    // Draw old screenshot
                    drawImage(
                        image = snapshot,
                        srcOffset = IntOffset.Zero,
                        srcSize = IntSize(snapshot.width, snapshot.height),
                        dstOffset = IntOffset.Zero,
                        dstSize = dstSize
                    )
                    // Cut expanding circle to reveal new theme underneath
                    drawCircle(
                        color = Color.Transparent,
                        radius = revealRadius.value,
                        center = revealCenter,
                        blendMode = BlendMode.Clear
                    )
                }
            }
        }
    }
}
