package me.eternal.purrfectsnap.ui.setup.screens.impl

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Warning
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.eternal.purrfectsnap.ui.manager.components.AestheticDialog
import me.eternal.purrfectsnap.ui.manager.theme.PurrfectPalette
import me.eternal.purrfectsnap.ui.setup.screens.SetupScreen
import me.eternal.purrfectsnap.ui.util.AlertDialogs
import me.eternal.purrfectsnap.ui.util.Motion

class MappingsScreen : SetupScreen() {
    @Composable
    override fun Content() {
        val coroutineScope = rememberCoroutineScope()
        var infoText by remember { mutableStateOf(null as String?) }
        var isGenerating by remember { mutableStateOf(false) }
        var showCompletionNotice by remember { mutableStateOf(false) }
        var completionCountdown by remember { mutableIntStateOf(10) }

        fun finishMappings() {
            if (isFirstRunFlow) {
                showCompletionNotice = true
            } else {
                goNext()
            }
        }

        if (infoText != null) {
            fun dismiss() {
                infoText = null
                finishMappings()
            }

            var visible by remember { mutableStateOf(false) }
            LaunchedEffect(Unit) { visible = true }
            Dialog(onDismissRequest = { dismiss() }) {
                AnimatedVisibility(
                    visible = visible,
                    enter = fadeIn(animationSpec = Motion.tweenFloatSpec(180)) + scaleIn(animationSpec = Motion.tweenFloatSpec(200)),
                    exit = fadeOut(animationSpec = Motion.tweenFloatSpec(150)) + scaleOut(animationSpec = Motion.tweenFloatSpec(180))
                ) {
                    remember { AlertDialogs(context.translation) }.InfoDialog(title = infoText!!) {
                        dismiss()
                    }
                }
            }
        }

        LaunchedEffect(showCompletionNotice) {
            if (showCompletionNotice) {
                completionCountdown = 10
                while (completionCountdown > 0) {
                    delay(1000)
                    completionCountdown--
                }
            }
        }

        if (showCompletionNotice) {
            val confirmLabel = if (completionCountdown > 0) {
                "I understand (${completionCountdown}s)"
            } else {
                "I understand"
            }
            AestheticDialog(
                onDismissRequest = { if (completionCountdown == 0) { showCompletionNotice = false; goNext() } },
                title = "Please note!",
                text = "",
                icon = Icons.Filled.Warning,
                confirmButtonText = confirmLabel,
                onConfirm = { if (completionCountdown == 0) { showCompletionNotice = false; goNext() } },
                confirmEnabled = completionCountdown == 0,
                showCloseButton = false,
                customContent = {
                    val bodyStyle = MaterialTheme.typography.bodyMedium.copy(
                        color = PurrfectPalette.textSecondary,
                        lineHeight = 18.sp
                    )
                    Surface(
                        shape = RoundedCornerShape(14.dp),
                        color = PurrfectPalette.cardOverlayColor,
                        tonalElevation = 0.dp,
                        shadowElevation = 0.dp,
                        border = BorderStroke(
                            1.dp,
                            Brush.linearGradient(
                                listOf(
                                    PurrfectPalette.glowPrimary.copy(alpha = 0.55f),
                                    PurrfectPalette.glowSecondary.copy(alpha = 0.35f)
                                )
                            )
                        )
                    ) {
                        Column(
                            modifier = Modifier
                                .fillMaxWidth()
                                .heightIn(max = 360.dp)
                                .verticalScroll(rememberScrollState())
                                .padding(horizontal = 14.dp, vertical = 12.dp),
                            horizontalAlignment = Alignment.CenterHorizontally,
                            verticalArrangement = Arrangement.spacedBy(10.dp)
                        ) {
                            Text(
                                text = "If you see the \"Account temporarily disabled\" error while logging in, do not worry. Follow these steps in order:",
                                style = bodyStyle,
                                modifier = Modifier.fillMaxWidth()
                            )
                            Text(
                                text = "1. Reopen Snapchat and log in. This fixes it most of the time.",
                                style = bodyStyle,
                                modifier = Modifier.fillMaxWidth()
                            )
                            Text(
                                text = "2. If it still fails, tap the login button repeatedly. This usually covers the next chunk.",
                                style = bodyStyle,
                                modifier = Modifier.fillMaxWidth()
                            )
                            Text(
                                text = "3. If it still fails, clear Snapchat's data, disable any VPN, and log in again.",
                                style = bodyStyle,
                                modifier = Modifier.fillMaxWidth()
                            )
                            Text(
                                text = "For rooted users:",
                                style = MaterialTheme.typography.bodyMedium.copy(
                                    color = Color.White,
                                    fontWeight = FontWeight.SemiBold,
                                    lineHeight = 18.sp
                                ),
                                modifier = Modifier.fillMaxWidth()
                            )
                            Text(
                                text = "Reopen Snapchat and log in. If it still fails, disable PurrfectSnap in LSPosed, log in, then re-enable PurrfectSnap.",
                                style = bodyStyle,
                                modifier = Modifier.fillMaxWidth()
                            )
                        }
                    }
                }
            )
        }

        LaunchedEffect(Unit) {
            coroutineScope.launch(Dispatchers.IO) {
                if (isGenerating) return@launch
                isGenerating = true
                runCatching {
                    context.mappings.init(context.androidContext)
                    if (context.mappings.getSnapchatPackageInfo() == null) {
                        throw Exception(context.translation["setup.mappings.generate_failure_no_snapchat"])
                    }
                    val warnings = context.mappings.refresh()

                    if (warnings.isNotEmpty()) {
                        isGenerating = false
                        infoText = "${warnings.size} warning(s) occurred while generating mappings:\n\n${warnings.joinToString("\n")}".also {
                            context.log.warn(it)
                        }
                        return@launch
                    }

                    withContext(Dispatchers.Main) {
                        finishMappings()
                    }
                }.onFailure {
                    isGenerating = false
                    infoText = context.translation["setup.mappings.generate_failure"] + "\n\n" + it.message
                    context.log.error("Failed to generate mappings", it)
                }
            }
        }

        SetupCard {
            StepTitle(
                title = context.translation["setup.mappings.dialog"],
                subtitle = null
            )
            DialogText(
                text = "This only takes a moment. Keep the app open while magic happens!"
            )
            Spacer(modifier = Modifier.height(12.dp))
            Surface(
                shape = RoundedCornerShape(20.dp),
                color = Color.White.copy(alpha = 0.05f),
                border = BorderStroke(
                    1.dp,
                    Brush.linearGradient(
                        listOf(
                            PurrfectPalette.glowPrimary.copy(alpha = 0.48f),
                            PurrfectPalette.glowSecondary.copy(alpha = 0.36f)
                        )
                    )
                )
            ) {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp, vertical = 14.dp),
                    verticalArrangement = Arrangement.spacedBy(16.dp),
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    LinearProgressIndicator(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(10.dp),
                        color = PurrfectPalette.glowPrimary,
                        trackColor = Color.White.copy(alpha = 0.12f)
                    )
                }
            }
        }
    }
}
