package ru.fromchat.ui.setup import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.ime import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material3.Button import androidx.compose.material3.Checkbox import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.rememberTopAppBarState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue 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.input.nestedscroll.nestedScroll import androidx.compose.ui.unit.dp import com.pr0gramm3r101.utils.navigateAndWipeBackStack import com.pr0gramm3r101.utils.storage.ServerConfigData import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import ru.fromchat.Res import ru.fromchat.api.ApiClient import ru.fromchat.api.WebSocketManager import ru.fromchat.back import ru.fromchat.core.config.Config import ru.fromchat.https_enabled import ru.fromchat.save_continue import ru.fromchat.server_config_subtitle import ru.fromchat.server_config_title import ru.fromchat.server_url_hint import ru.fromchat.server_url_label import ru.fromchat.ui.LocalNavController @OptIn(ExperimentalMaterial3Api::class) @Composable fun ServerConfigScreen() { val navController = LocalNavController.current val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) // Load existing config if available var serverUrl by remember { mutableStateOf("fromchat.ru") } var httpsEnabled by remember { mutableStateOf(true) } LaunchedEffect(Unit) { val config = Config.serverConfig.value if (config != null) { serverUrl = config.serverUrl httpsEnabled = config.httpsEnabled } } var isLoading by remember { mutableStateOf(false) } val scope = rememberCoroutineScope() Scaffold( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { TopAppBar( title = {}, navigationIcon = { IconButton(onClick = navController::navigateUp) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(Res.string.back) ) } }, scrollBehavior = scrollBehavior ) } ) { innerPadding -> Column( modifier = Modifier .fillMaxSize() .padding(innerPadding) .windowInsetsPadding(WindowInsets.ime) .padding(horizontal = 24.dp) .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text( text = stringResource(Res.string.server_config_title), style = MaterialTheme.typography.headlineMedium ) Spacer(modifier = Modifier.height(8.dp)) Text( text = stringResource(Res.string.server_config_subtitle), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant ) Spacer(modifier = Modifier.height(32.dp)) OutlinedTextField( value = serverUrl, onValueChange = { serverUrl = it }, label = { Text(stringResource(Res.string.server_url_label)) }, placeholder = { Text(stringResource(Res.string.server_url_hint)) }, modifier = Modifier.fillMaxWidth(), singleLine = true ) Spacer(modifier = Modifier.height(16.dp)) Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { Checkbox( checked = httpsEnabled, onCheckedChange = { httpsEnabled = it } ) Spacer(modifier = Modifier.width(8.dp)) Text(stringResource(Res.string.https_enabled)) } Spacer(modifier = Modifier.height(32.dp)) Button( onClick = { isLoading = true scope.launch { val config = ServerConfigData(serverUrl, httpsEnabled) Config.updateServerConfig(config) // Ensure we're logged out when server config changes try { ApiClient.token?.let { token -> ApiClient.logout(token) } } catch (e: Exception) { // Ignore logout errors } // Clear API client state ApiClient.token = null ApiClient.user = null // Shutdown WebSocket (will reconnect on login) WebSocketManager.shutdown() // Navigate to login and wipe entire back stack navController.navigateAndWipeBackStack("login") } }, enabled = !isLoading && serverUrl.isNotBlank(), modifier = Modifier.fillMaxWidth() ) { Text(stringResource(Res.string.save_continue)) } } } }