package com.rosetta.messenger.ui.auth

import androidx.compose.animation.*
import androidx.compose.animation.core.*
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import compose.icons.TablerIcons
import compose.icons.tablericons.*
import com.rosetta.messenger.ui.icons.TelegramIcons
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.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.rosetta.messenger.crypto.CryptoManager
import com.rosetta.messenger.data.AccountManager
import com.rosetta.messenger.data.DecryptedAccount
import com.rosetta.messenger.data.EncryptedAccount
import com.rosetta.messenger.ui.onboarding.PrimaryBlue
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SetPasswordScreen(
        seedPhrase: List<String>,
        isDarkTheme: Boolean,
        isImportMode: Boolean = false,
        onBack: () -> Unit,
        onAccountCreated: (DecryptedAccount) -> Unit
) {
    val themeAnimSpec =
            tween<Color>(durationMillis = 500, easing = CubicBezierEasing(0.4f, 0f, 0.2f, 1f))
    val backgroundColor by
            animateColorAsState(
                    if (isDarkTheme) AuthBackground else AuthBackgroundLight,
                    animationSpec = themeAnimSpec
            )
    val textColor by
            animateColorAsState(
                    if (isDarkTheme) Color.White else Color.Black,
                    animationSpec = themeAnimSpec
            )
    val secondaryTextColor by
            animateColorAsState(
                    if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666),
                    animationSpec = themeAnimSpec
            )
    val cardColor by
            animateColorAsState(
                    if (isDarkTheme) AuthSurface else AuthSurfaceLight,
                    animationSpec = themeAnimSpec
            )

    val context = LocalContext.current
    val accountManager = remember { AccountManager(context) }
    val scope = rememberCoroutineScope()

    var password by remember { mutableStateOf("") }
    var confirmPassword by remember { mutableStateOf("") }
    var passwordVisible by remember { mutableStateOf(false) }
    var confirmPasswordVisible by remember { mutableStateOf(false) }
    var isCreating by remember { mutableStateOf(false) }
    var error by remember { mutableStateOf<String?>(null) }
    var visible by remember { mutableStateOf(false) }

    // Track keyboard visibility
    val view = LocalView.current
    if (!view.isInEditMode) {
        SideEffect {
            val window = (view.context as android.app.Activity).window
            val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view)
            // Auth screens should always keep white status bar icons.
            insetsController.isAppearanceLightStatusBars = false
            window.statusBarColor = android.graphics.Color.TRANSPARENT
        }
    }
    var isKeyboardVisible by remember { mutableStateOf(false) }

    DisposableEffect(view) {
        val listener =
                android.view.ViewTreeObserver.OnGlobalLayoutListener {
                    val rect = android.graphics.Rect()
                    view.getWindowVisibleDisplayFrame(rect)
                    val screenHeight = view.rootView.height
                    val keypadHeight = screenHeight - rect.bottom
                    isKeyboardVisible = keypadHeight > screenHeight * 0.15
                }
        view.viewTreeObserver.addOnGlobalLayoutListener(listener)
        onDispose { view.viewTreeObserver.removeOnGlobalLayoutListener(listener) }
    }

    LaunchedEffect(Unit) { visible = true }

    val passwordsMatch = password == confirmPassword && password.isNotEmpty()
    val isPasswordWeak = password.isNotEmpty() && password.length < 6
    val canContinue = passwordsMatch && !isCreating

    Box(modifier = Modifier.fillMaxSize().background(backgroundColor).navigationBarsPadding()) {
        Column(modifier = Modifier.fillMaxSize().statusBarsPadding()) {
            // Top Bar
            Row(
                    modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp, vertical = 8.dp),
                    verticalAlignment = Alignment.CenterVertically
            ) {
                IconButton(onClick = onBack, enabled = !isCreating) {
                    Icon(
                            imageVector = TablerIcons.ChevronLeft,
                            contentDescription = "Back",
                            tint = textColor.copy(alpha = 0.6f)
                    )
                }
                Spacer(modifier = Modifier.weight(1f))
                Text(
                        text = "Set Password",
                        fontSize = 18.sp,
                        fontWeight = FontWeight.SemiBold,
                        color = textColor
                )
                Spacer(modifier = Modifier.weight(1f))
                Spacer(modifier = Modifier.width(48.dp))
            }

            Column(
                    modifier =
                            Modifier.fillMaxSize()
                                    .imePadding()
                                    .padding(horizontal = 24.dp)
                                    .verticalScroll(rememberScrollState()),
                    horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Spacer(modifier = Modifier.height(if (isKeyboardVisible) 8.dp else 16.dp))

                // Lock Icon - smaller when keyboard is visible
                val iconSize by
                        animateDpAsState(
                                targetValue = if (isKeyboardVisible) 48.dp else 80.dp,
                                animationSpec = tween(300, easing = FastOutSlowInEasing)
                        )
                val iconInnerSize by
                        animateDpAsState(
                                targetValue = if (isKeyboardVisible) 24.dp else 40.dp,
                                animationSpec = tween(300, easing = FastOutSlowInEasing)
                        )

                AnimatedVisibility(
                        visible = visible,
                        enter =
                                fadeIn(tween(250)) +
                                        scaleIn(
                                                initialScale = 0.5f,
                                                animationSpec =
                                                        tween(250, easing = FastOutSlowInEasing)
                                        )
                ) {
                    Box(
                            modifier =
                                    Modifier.size(iconSize)
                                            .clip(
                                                    RoundedCornerShape(
                                                            if (isKeyboardVisible) 12.dp else 20.dp
                                                    )
                                            )
                                            .background(PrimaryBlue.copy(alpha = 0.1f)),
                            contentAlignment = Alignment.Center
                    ) {
                        Icon(
                                TablerIcons.Lock,
                                contentDescription = null,
                                tint = PrimaryBlue,
                                modifier = Modifier.size(iconInnerSize)
                        )
                    }
                }

                Spacer(modifier = Modifier.height(if (isKeyboardVisible) 12.dp else 24.dp))

                AnimatedVisibility(
                        visible = visible,
                        enter = fadeIn(tween(400, delayMillis = 100))
                ) {
                    Text(
                            text = if (isImportMode) "Recover Account" else "Protect Your Account",
                            fontSize = if (isKeyboardVisible) 20.sp else 24.sp,
                            fontWeight = FontWeight.Bold,
                            color = textColor
                    )
                }

                Spacer(modifier = Modifier.height(if (isKeyboardVisible) 6.dp else 8.dp))

                AnimatedVisibility(
                        visible = visible,
                        enter = fadeIn(tween(500, delayMillis = 200))
                ) {
                    Text(
                            text = if (isImportMode)
                                    "Set a password to protect your recovered account.\nYou'll need it to unlock Rosetta."
                            else
                                    "This password encrypts your keys locally.\nYou'll need it to unlock Rosetta.",
                            fontSize = if (isKeyboardVisible) 12.sp else 14.sp,
                            color = secondaryTextColor,
                            textAlign = TextAlign.Center,
                            lineHeight = if (isKeyboardVisible) 16.sp else 20.sp
                    )
                }

                Spacer(modifier = Modifier.height(if (isKeyboardVisible) 16.dp else 32.dp))

                // Password Field
                AnimatedVisibility(
                        visible = visible,
                        enter = fadeIn(tween(400, delayMillis = 300))
                ) {
                    OutlinedTextField(
                            value = password,
                            onValueChange = {
                                password = it
                                error = null
                            },
                            label = { Text("Password") },
                            placeholder = { Text("Enter password") },
                            singleLine = true,
                            visualTransformation =
                                    if (passwordVisible) VisualTransformation.None
                                    else PasswordVisualTransformation(),
                            trailingIcon = {
                                IconButton(onClick = { passwordVisible = !passwordVisible }) {
                                    Icon(
                                            imageVector =
                                                    if (passwordVisible) TablerIcons.EyeOff
                                                    else TablerIcons.Eye,
                                            contentDescription =
                                                    if (passwordVisible) "Hide" else "Show"
                                    )
                                }
                            },
                            colors =
                                    OutlinedTextFieldDefaults.colors(
                                            focusedBorderColor = PrimaryBlue,
                                            unfocusedBorderColor =
                                                    if (isDarkTheme) Color(0xFF4A4A4A)
                                                    else Color(0xFFD0D0D0),
                                            focusedLabelColor = PrimaryBlue,
                                            cursorColor = PrimaryBlue,
                                            focusedTextColor = textColor,
                                            unfocusedTextColor = textColor
                                    ),
                            modifier = Modifier.fillMaxWidth(),
                            shape = RoundedCornerShape(12.dp),
                            keyboardOptions =
                                    KeyboardOptions(
                                            keyboardType = KeyboardType.Password,
                                            imeAction = ImeAction.Next
                                    )
                    )
                }

                // Password strength indicator
                if (password.isNotEmpty()) {
                    Spacer(modifier = Modifier.height(8.dp))
                    AnimatedVisibility(
                            visible = visible,
                            enter = fadeIn(tween(400, delayMillis = 350))
                    ) {
                        Column(modifier = Modifier.fillMaxWidth()) {
                            Row(
                                    modifier = Modifier.fillMaxWidth(),
                                    verticalAlignment = Alignment.CenterVertically
                            ) {
                                val strength =
                                        when {
                                            password.length < 6 -> "Weak"
                                            password.length < 10 -> "Medium"
                                            else -> "Strong"
                                        }
                                val strengthColor =
                                        when {
                                            password.length < 6 -> Color(0xFFE53935)
                                            password.length < 10 -> Color(0xFFFFA726)
                                            else -> Color(0xFF4CAF50)
                                        }
                                Icon(
                                        painter = TelegramIcons.Secret,
                                        contentDescription = null,
                                        tint = strengthColor,
                                        modifier = Modifier.size(16.dp)
                                )
                                Spacer(modifier = Modifier.width(4.dp))
                                Text(
                                        text = "Password strength: $strength",
                                        fontSize = 12.sp,
                                        color = strengthColor
                                )
                            }
                            // Warning for weak passwords
                            if (isPasswordWeak) {
                                Spacer(modifier = Modifier.height(4.dp))
                                Row(
                                        modifier =
                                                Modifier.fillMaxWidth()
                                                        .clip(RoundedCornerShape(8.dp))
                                                        .background(
                                                                Color(0xFFE53935).copy(alpha = 0.1f)
                                                        )
                                                        .padding(8.dp),
                                        verticalAlignment = Alignment.Top
                                ) {
                                    Icon(
                                            painter = TelegramIcons.Warning,
                                            contentDescription = null,
                                            tint = Color(0xFFE53935),
                                            modifier = Modifier.size(16.dp)
                                    )
                                    Spacer(modifier = Modifier.width(8.dp))
                                    Text(
                                            text =
                                                    "Your password is too weak. Consider using at least 6 characters for better security.",
                                            fontSize = 11.sp,
                                            color = Color(0xFFE53935),
                                            lineHeight = 14.sp
                                    )
                                }
                            }
                        }
                    }
                }

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

                // Confirm Password Field
                AnimatedVisibility(
                        visible = visible,
                        enter = fadeIn(tween(400, delayMillis = 400))
                ) {
                    OutlinedTextField(
                            value = confirmPassword,
                            onValueChange = {
                                confirmPassword = it
                                error = null
                            },
                            label = { Text("Confirm Password") },
                            placeholder = { Text("Re-enter password") },
                            singleLine = true,
                            visualTransformation =
                                    if (confirmPasswordVisible) VisualTransformation.None
                                    else PasswordVisualTransformation(),
                            trailingIcon = {
                                IconButton(
                                        onClick = {
                                            confirmPasswordVisible = !confirmPasswordVisible
                                        }
                                ) {
                                    Icon(
                                            imageVector =
                                                    if (confirmPasswordVisible)
                                                            TablerIcons.EyeOff
                                                    else TablerIcons.Eye,
                                            contentDescription =
                                                    if (confirmPasswordVisible) "Hide" else "Show"
                                    )
                                }
                            },
                            isError = confirmPassword.isNotEmpty() && !passwordsMatch,
                            colors =
                                    OutlinedTextFieldDefaults.colors(
                                            focusedBorderColor = PrimaryBlue,
                                            unfocusedBorderColor =
                                                    if (isDarkTheme) Color(0xFF4A4A4A)
                                                    else Color(0xFFD0D0D0),
                                            focusedLabelColor = PrimaryBlue,
                                            cursorColor = PrimaryBlue,
                                            focusedTextColor = textColor,
                                            unfocusedTextColor = textColor
                                    ),
                            modifier = Modifier.fillMaxWidth(),
                            shape = RoundedCornerShape(12.dp),
                            keyboardOptions =
                                    KeyboardOptions(
                                            keyboardType = KeyboardType.Password,
                                            imeAction = ImeAction.Done
                                    )
                    )
                }

                // Match indicator
                if (confirmPassword.isNotEmpty()) {
                    Spacer(modifier = Modifier.height(8.dp))
                    AnimatedVisibility(
                            visible = visible,
                            enter = fadeIn(tween(400, delayMillis = 450))
                    ) {
                        Row(
                                modifier = Modifier.fillMaxWidth(),
                                verticalAlignment = Alignment.CenterVertically
                        ) {
                            val matchIcon =
                                    if (passwordsMatch) TablerIcons.Check else TablerIcons.X
                            val matchColor =
                                    if (passwordsMatch) Color(0xFF4CAF50) else Color(0xFFE53935)
                            val matchText =
                                    if (passwordsMatch) "Passwords match"
                                    else "Passwords don't match"

                            Icon(
                                    imageVector = matchIcon,
                                    contentDescription = null,
                                    tint = matchColor,
                                    modifier = Modifier.size(16.dp)
                            )
                            Spacer(modifier = Modifier.width(4.dp))
                            Text(text = matchText, fontSize = 12.sp, color = matchColor)
                        }
                    }
                }

                // Error message
                error?.let { errorMsg ->
                    Spacer(modifier = Modifier.height(16.dp))
                    AnimatedVisibility(
                            visible = true,
                            enter = fadeIn(tween(300)) + scaleIn(initialScale = 0.9f)
                    ) {
                        Text(
                                text = errorMsg,
                                fontSize = 14.sp,
                                color = Color(0xFFE53935),
                                textAlign = TextAlign.Center
                        )
                    }
                }

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

                // Info - hide when keyboard is visible
                AnimatedVisibility(
                        visible = visible && !isKeyboardVisible,
                        enter = fadeIn(tween(300)),
                        exit = fadeOut(tween(200))
                ) {
                    Row(
                            modifier =
                                    Modifier.fillMaxWidth()
                                            .clip(RoundedCornerShape(12.dp))
                                            .background(cardColor)
                                            .padding(16.dp),
                            verticalAlignment = Alignment.Top
                    ) {
                        Icon(
                                painter = TelegramIcons.Info,
                                contentDescription = null,
                                tint = PrimaryBlue,
                                modifier = Modifier.size(20.dp)
                        )
                        Spacer(modifier = Modifier.width(12.dp))
                        Text(
                                text =
                                        "Your password is never stored or sent anywhere. It's only used to encrypt your keys locally.",
                                fontSize = 13.sp,
                                color = secondaryTextColor,
                                lineHeight = 18.sp
                        )
                    }
                }

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

                // Create Account Button
                AnimatedVisibility(
                        visible = visible,
                        enter = fadeIn(tween(400, delayMillis = 600))
                ) {
                    Button(
                            onClick = {
                                if (!passwordsMatch) {
                                    error = "Passwords don't match"
                                    return@Button
                                }

                                isCreating = true
                                scope.launch {
                                    try {
                                        // Generate keys from seed phrase
                                        val keyPair =
                                                CryptoManager.generateKeyPairFromSeed(seedPhrase)

                                        // Encrypt private key and seed phrase
                                        val encryptedPrivateKey =
                                                CryptoManager.encryptWithPassword(
                                                        keyPair.privateKey,
                                                        password
                                                )
                                        val encryptedSeedPhrase =
                                                CryptoManager.encryptWithPassword(
                                                        seedPhrase.joinToString(" "),
                                                        password
                                                )

                                        // Save account with truncated public key as name
                                        val truncatedKey =
                                                "${keyPair.publicKey.take(6)}...${keyPair.publicKey.takeLast(4)}"
                                        val account =
                                                EncryptedAccount(
                                                        publicKey = keyPair.publicKey,
                                                        encryptedPrivateKey = encryptedPrivateKey,
                                                        encryptedSeedPhrase = encryptedSeedPhrase,
                                                        name = truncatedKey
                                                )

                                        accountManager.saveAccount(account)

                                        // 🔌 Connect to server and authenticate
                                        val privateKeyHash =
                                                CryptoManager.generatePrivateKeyHash(
                                                        keyPair.privateKey
                                                )

                                        val handshakeState =
                                                awaitAuthHandshakeState(
                                                        keyPair.publicKey,
                                                        privateKeyHash
                                                )
                                        if (handshakeState == null) {
                                            error =
                                                    "Failed to connect to server. Please try again."
                                            isCreating = false
                                            return@launch
                                        }

                                        accountManager.setCurrentAccount(keyPair.publicKey)

                                        // Create DecryptedAccount to pass to callback
                                        val decryptedAccount =
                                                DecryptedAccount(
                                                        publicKey = keyPair.publicKey,
                                                        privateKey = keyPair.privateKey,
                                                        seedPhrase = seedPhrase,
                                                        privateKeyHash = privateKeyHash,
                                                        name = truncatedKey
                                                )

                                        onAccountCreated(decryptedAccount)
                                    } catch (e: Exception) {
                                        error = "Failed to create account: ${e.message}"
                                        isCreating = false
                                    }
                                }
                            },
                            enabled = canContinue,
                            modifier = Modifier.fillMaxWidth().height(56.dp),
                            colors =
                                    ButtonDefaults.buttonColors(
                                            containerColor = PrimaryBlue,
                                            contentColor = Color.White,
                                            disabledContainerColor = PrimaryBlue.copy(alpha = 0.5f),
                                            disabledContentColor = Color.White.copy(alpha = 0.5f)
                                    ),
                            shape = RoundedCornerShape(12.dp)
                    ) {
                        if (isCreating) {
                            CircularProgressIndicator(
                                    modifier = Modifier.size(24.dp),
                                    color = Color.White,
                                    strokeWidth = 2.dp
                            )
                        } else {
                            Text(
                                    text = if (isImportMode) "Recover Account" else "Create Account",
                                    fontSize = 16.sp,
                                    fontWeight = FontWeight.SemiBold
                            )
                        }
                    }
                }
                Spacer(modifier = Modifier.height(32.dp))
            }
        }
    }
}
