package com.aistudio.bonjuteri.jwlry.ui.screens import android.app.Activity import android.content.Context import android.util.Log import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Email import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Visibility import androidx.compose.material.icons.filled.VisibilityOff import androidx.compose.material.icons.outlined.Diamond import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Tab import androidx.compose.material3.TabRow import androidx.compose.material3.TabRowDefaults import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset import androidx.compose.material3.Text import androidx.compose.runtime.Composable 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.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontWeight 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 androidx.credentials.ClearCredentialStateRequest import androidx.credentials.CredentialManager import androidx.credentials.CustomCredential import androidx.credentials.GetCredentialRequest import androidx.credentials.exceptions.GetCredentialCancellationException import com.aistudio.bonjuteri.jwlry.R import com.aistudio.bonjuteri.jwlry.model.UserProfile import com.aistudio.bonjuteri.jwlry.ui.theme.GoldDark import com.aistudio.bonjuteri.jwlry.ui.theme.GoldPrimary import com.aistudio.bonjuteri.jwlry.ui.theme.GoldSubtle import com.aistudio.bonjuteri.jwlry.ui.theme.MutedGrey import com.aistudio.bonjuteri.jwlry.ui.theme.PrimaryBlack import com.aistudio.bonjuteri.jwlry.ui.theme.PureWhite import com.aistudio.bonjuteri.jwlry.ui.theme.SurfaceBorder import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential import com.google.firebase.auth.AuthCredential import com.google.firebase.auth.GoogleAuthProvider import kotlinx.coroutines.launch @Composable fun AuthScreen( onSignInWithEmail: suspend (String, String) -> Result, onSignUpWithEmail: suspend (String, String, String, String) -> Result, onSignInWithCredential: suspend (AuthCredential) -> Result, onSendPasswordReset: suspend (String) -> Result, onAuthSuccess: (UserProfile) -> Unit, snackbarHostState: SnackbarHostState, modifier: Modifier = Modifier ) { val context = LocalContext.current val scope = rememberCoroutineScope() var selectedTab by remember { mutableIntStateOf(0) } // 0: Giriş Yap, 1: Kayıt Ol // Login Form State var loginEmail by remember { mutableStateOf("") } var loginPassword by remember { mutableStateOf("") } var isLoginPasswordVisible by remember { mutableStateOf(false) } // Register Form State var registerFirstName by remember { mutableStateOf("") } var registerLastName by remember { mutableStateOf("") } var registerEmail by remember { mutableStateOf("") } var registerPassword by remember { mutableStateOf("") } var isRegisterPasswordVisible by remember { mutableStateOf(false) } var isLoading by remember { mutableStateOf(false) } var errorMessage by remember { mutableStateOf(null) } // Forgot password dialog var showForgotPasswordDialog by remember { mutableStateOf(false) } var resetEmail by remember { mutableStateOf("") } var resetMessage by remember { mutableStateOf(null) } var isResetLoading by remember { mutableStateOf(false) } Column( modifier = modifier .fillMaxSize() .background(PureWhite) .verticalScroll(rememberScrollState()) .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Spacer(modifier = Modifier.height(24.dp)) // Luxury Boutique Brand 3D Emblem Image( painter = painterResource(id = R.drawable.img_app_icon_3d), contentDescription = "BONJUTERİ", modifier = Modifier .size(76.dp) .clip(CircleShape) ) Spacer(modifier = Modifier.height(12.dp)) Text( text = "BONJUTERİ", style = MaterialTheme.typography.headlineMedium.copy( fontWeight = FontWeight.Black, letterSpacing = 2.5.sp, color = PrimaryBlack ) ) Text( text = "ÖZEL TASARIM & MÜCEVHER BUTİĞİ", style = MaterialTheme.typography.labelSmall.copy( fontSize = 9.sp, fontWeight = FontWeight.Bold, letterSpacing = 1.5.sp, color = GoldDark ) ) Spacer(modifier = Modifier.height(28.dp)) // Tabs: Giriş Yap / Kayıt Ol TabRow( selectedTabIndex = selectedTab, containerColor = PureWhite, indicator = { tabPositions -> TabRowDefaults.SecondaryIndicator( modifier = Modifier.tabIndicatorOffset(tabPositions[selectedTab]), color = PrimaryBlack, height = 2.5.dp ) } ) { Tab( selected = selectedTab == 0, onClick = { selectedTab = 0 errorMessage = null }, text = { Text( text = "Giriş Yap", fontWeight = if (selectedTab == 0) FontWeight.Bold else FontWeight.Medium, color = if (selectedTab == 0) PrimaryBlack else MutedGrey, fontSize = 15.sp ) }, modifier = Modifier.testTag("auth_tab_login") ) Tab( selected = selectedTab == 1, onClick = { selectedTab = 1 errorMessage = null }, text = { Text( text = "Kayıt Ol", fontWeight = if (selectedTab == 1) FontWeight.Bold else FontWeight.Medium, color = if (selectedTab == 1) PrimaryBlack else MutedGrey, fontSize = 15.sp ) }, modifier = Modifier.testTag("auth_tab_register") ) } Spacer(modifier = Modifier.height(20.dp)) // Error message banner if (errorMessage != null) { Card( colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.errorContainer), shape = RoundedCornerShape(8.dp), modifier = Modifier .fillMaxWidth() .padding(bottom = 14.dp) ) { Text( text = errorMessage!!, color = MaterialTheme.colorScheme.onErrorContainer, fontSize = 13.sp, modifier = Modifier.padding(12.dp) ) } } if (selectedTab == 0) { // LOGIN FORM Column( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(14.dp) ) { OutlinedTextField( value = loginEmail, onValueChange = { loginEmail = it }, label = { Text("E-posta Adresi") }, leadingIcon = { Icon(Icons.Filled.Email, contentDescription = null, tint = MutedGrey) }, modifier = Modifier .fillMaxWidth() .testTag("login_email_input"), singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email) ) OutlinedTextField( value = loginPassword, onValueChange = { loginPassword = it }, label = { Text("Şifre") }, leadingIcon = { Icon(Icons.Filled.Lock, contentDescription = null, tint = MutedGrey) }, trailingIcon = { IconButton(onClick = { isLoginPasswordVisible = !isLoginPasswordVisible }) { Icon( imageVector = if (isLoginPasswordVisible) Icons.Filled.VisibilityOff else Icons.Filled.Visibility, contentDescription = "Şifreyi Göster", tint = MutedGrey ) } }, visualTransformation = if (isLoginPasswordVisible) VisualTransformation.None else PasswordVisualTransformation(), modifier = Modifier .fillMaxWidth() .testTag("login_password_input"), singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password) ) // Forgot Password link Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End ) { Text( text = "Şifremi Unuttum", color = GoldDark, fontWeight = FontWeight.SemiBold, fontSize = 12.sp, modifier = Modifier .clickable { resetEmail = loginEmail resetMessage = null showForgotPasswordDialog = true } .testTag("forgot_password_link") ) } Spacer(modifier = Modifier.height(6.dp)) Button( onClick = { scope.launch { isLoading = true errorMessage = null val result = onSignInWithEmail(loginEmail, loginPassword) isLoading = false if (result.isSuccess) { onAuthSuccess(result.getOrThrow()) } else { errorMessage = result.exceptionOrNull()?.message ?: "Giriş başarısız oldu." } } }, enabled = !isLoading, modifier = Modifier .fillMaxWidth() .height(50.dp) .testTag("login_submit_button"), shape = RoundedCornerShape(10.dp), colors = ButtonDefaults.buttonColors( containerColor = PrimaryBlack, contentColor = PureWhite ) ) { if (isLoading) { CircularProgressIndicator(color = PureWhite, modifier = Modifier.size(22.dp)) } else { Text("Giriş Yap", fontWeight = FontWeight.Bold, fontSize = 15.sp) } } } } else { // REGISTER FORM Column( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(14.dp) ) { Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) { OutlinedTextField( value = registerFirstName, onValueChange = { registerFirstName = it }, label = { Text("Ad") }, leadingIcon = { Icon(Icons.Filled.Person, contentDescription = null, tint = MutedGrey) }, modifier = Modifier .weight(1f) .testTag("register_first_name_input"), singleLine = true ) OutlinedTextField( value = registerLastName, onValueChange = { registerLastName = it }, label = { Text("Soyad") }, modifier = Modifier .weight(1f) .testTag("register_last_name_input"), singleLine = true ) } OutlinedTextField( value = registerEmail, onValueChange = { registerEmail = it }, label = { Text("E-posta Adresi") }, leadingIcon = { Icon(Icons.Filled.Email, contentDescription = null, tint = MutedGrey) }, modifier = Modifier .fillMaxWidth() .testTag("register_email_input"), singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email) ) OutlinedTextField( value = registerPassword, onValueChange = { registerPassword = it }, label = { Text("Şifre (En az 6 karakter)") }, leadingIcon = { Icon(Icons.Filled.Lock, contentDescription = null, tint = MutedGrey) }, trailingIcon = { IconButton(onClick = { isRegisterPasswordVisible = !isRegisterPasswordVisible }) { Icon( imageVector = if (isRegisterPasswordVisible) Icons.Filled.VisibilityOff else Icons.Filled.Visibility, contentDescription = "Şifreyi Göster", tint = MutedGrey ) } }, visualTransformation = if (isRegisterPasswordVisible) VisualTransformation.None else PasswordVisualTransformation(), modifier = Modifier .fillMaxWidth() .testTag("register_password_input"), singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password) ) Spacer(modifier = Modifier.height(6.dp)) Button( onClick = { scope.launch { isLoading = true errorMessage = null val result = onSignUpWithEmail( registerFirstName, registerLastName, registerEmail, registerPassword ) isLoading = false if (result.isSuccess) { onAuthSuccess(result.getOrThrow()) } else { errorMessage = result.exceptionOrNull()?.message ?: "Kayıt işlemi başarısız." } } }, enabled = !isLoading, modifier = Modifier .fillMaxWidth() .height(50.dp) .testTag("register_submit_button"), shape = RoundedCornerShape(10.dp), colors = ButtonDefaults.buttonColors( containerColor = PrimaryBlack, contentColor = PureWhite ) ) { if (isLoading) { CircularProgressIndicator(color = PureWhite, modifier = Modifier.size(22.dp)) } else { Text("Hesap Oluştur", fontWeight = FontWeight.Bold, fontSize = 15.sp) } } } } Spacer(modifier = Modifier.height(24.dp)) // Divider Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { HorizontalDivider(modifier = Modifier.weight(1f), color = SurfaceBorder) Text( text = "VEYA", modifier = Modifier.padding(horizontal = 12.dp), color = MutedGrey, fontSize = 11.sp, fontWeight = FontWeight.Bold ) HorizontalDivider(modifier = Modifier.weight(1f), color = SurfaceBorder) } Spacer(modifier = Modifier.height(20.dp)) // Google Sign In Button via Credential Manager OutlinedButton( onClick = { handleGoogleSignIn( context = context, scope = scope, onLoading = { isLoading = it }, onError = { errorMessage = it }, onCredential = { cred -> scope.launch { isLoading = true val result = onSignInWithCredential(cred) isLoading = false if (result.isSuccess) { onAuthSuccess(result.getOrThrow()) } else { errorMessage = result.exceptionOrNull()?.message ?: "Google ile giriş başarısız." } } } ) }, modifier = Modifier .fillMaxWidth() .height(50.dp) .testTag("google_sign_in_button"), shape = RoundedCornerShape(10.dp), border = androidx.compose.foundation.BorderStroke(1.dp, SurfaceBorder) ) { Text( text = "Google ile Giriş Yap", color = PrimaryBlack, fontWeight = FontWeight.Bold, fontSize = 14.sp ) } Spacer(modifier = Modifier.height(24.dp)) } // Forgot Password Dialog if (showForgotPasswordDialog) { AlertDialog( onDismissRequest = { showForgotPasswordDialog = false }, title = { Text("Şifremi Unuttum", fontWeight = FontWeight.Bold) }, text = { Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { Text( text = "Kayıtlı e-posta adresinizi giriniz. Şifre sıfırlama bağlantısı gönderilecektir.", fontSize = 13.sp, color = MutedGrey ) OutlinedTextField( value = resetEmail, onValueChange = { resetEmail = it }, label = { Text("E-posta Adresi") }, modifier = Modifier.fillMaxWidth(), singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email) ) if (resetMessage != null) { Text( text = resetMessage!!, color = if (resetMessage!!.contains("gönderildi", ignoreCase = true)) GoldDark else MaterialTheme.colorScheme.error, fontSize = 12.sp, fontWeight = FontWeight.Medium ) } } }, confirmButton = { Button( onClick = { scope.launch { isResetLoading = true val res = onSendPasswordReset(resetEmail) isResetLoading = false if (res.isSuccess) { resetMessage = "Sıfırlama bağlantısı e-posta adresinize gönderildi!" } else { resetMessage = res.exceptionOrNull()?.message ?: "Sıfırlama e-postası gönderilemedi." } } }, colors = ButtonDefaults.buttonColors(containerColor = PrimaryBlack) ) { if (isResetLoading) { CircularProgressIndicator(color = PureWhite, modifier = Modifier.size(16.dp)) } else { Text("Gönder") } } }, dismissButton = { OutlinedButton(onClick = { showForgotPasswordDialog = false }) { Text("Kapat") } } ) } } private fun handleGoogleSignIn( context: Context, scope: kotlinx.coroutines.CoroutineScope, onLoading: (Boolean) -> Unit, onError: (String) -> Unit, onCredential: (AuthCredential) -> Unit ) { val clientId = try { context.getString(R.string.default_web_client_id) } catch (_: Exception) { onError("Google Sign-In yapılandırması bulunamadı (default_web_client_id eksik).") return } val credentialManager = CredentialManager.create(context) val signInOption = GetSignInWithGoogleOption.Builder(serverClientId = clientId).build() val request = GetCredentialRequest.Builder().addCredentialOption(signInOption).build() onLoading(true) scope.launch { try { val result = credentialManager.getCredential(context as Activity, request) val credential = result.credential if (credential is CustomCredential && credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) { val googleIdToken = GoogleIdTokenCredential.createFrom(credential.data).idToken val authCredential = GoogleAuthProvider.getCredential(googleIdToken, null) onCredential(authCredential) } else { onError("Google kimlik bilgisi doğrulanamadı.") onLoading(false) } } catch (e: GetCredentialCancellationException) { Log.w("AuthScreen", "Google Giriş iptal edildi: ${e.message}") onLoading(false) } catch (e: Exception) { Log.e("AuthScreen", "Google Giriş hatası", e) onError(e.localizedMessage ?: "Google ile giriş yapılamadı.") onLoading(false) } } }