package no.svorka.mcms.ui

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import no.svorka.mcms.core.ApiConfiguration

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LoginScreen(app: AppState, onOpenSettings: () -> Unit) {
    var email by rememberSaveable { mutableStateOf(app.savedEmail ?: "") }
    // Plain remember (not rememberSaveable) and never pre-filled: keep the password
    // out of the on-disk saved-instance Bundle and off a potentially shared screen.
    var password by remember { mutableStateOf("") }
    var remember by rememberSaveable { mutableStateOf(true) }
    var phase by remember { mutableStateOf<LoadPhase>(LoadPhase.Idle) }
    val scope = rememberCoroutineScope()

    Scaffold(topBar = {
        TopAppBar(
            title = { Text("PON Go") },
            actions = { IconButton(onClick = onOpenSettings) { Icon(Icons.Filled.Settings, contentDescription = "Settings") } },
        )
    }) { padding ->
        Column(Modifier.padding(padding).padding(16.dp).fillMaxSize()) {
            OutlinedTextField(
                value = email, onValueChange = { email = it }, label = { Text("Email") }, singleLine = true,
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email),
                modifier = Modifier.fillMaxWidth(),
            )
            Spacer(Modifier.height(8.dp))
            OutlinedTextField(
                value = password, onValueChange = { password = it }, label = { Text("Password") }, singleLine = true,
                visualTransformation = PasswordVisualTransformation(),
                modifier = Modifier.fillMaxWidth(),
            )
            Row(verticalAlignment = Alignment.CenterVertically) {
                Checkbox(checked = remember, onCheckedChange = { remember = it })
                Text("Remember me")
            }
            app.configuration?.host?.let {
                Text("Connecting to $it", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
            }
            Spacer(Modifier.height(16.dp))
            Button(
                onClick = {
                    phase = LoadPhase.Loading
                    scope.launch {
                        phase = try { app.signIn(email, password, remember); LoadPhase.Loaded }
                        catch (e: Throwable) { LoadPhase.Failed(e.uiMessage()) }
                    }
                },
                enabled = email.isNotBlank() && password.isNotBlank() && phase != LoadPhase.Loading,
                modifier = Modifier.fillMaxWidth(),
            ) {
                if (phase == LoadPhase.Loading) CircularProgressIndicator(Modifier.size(20.dp), strokeWidth = 2.dp)
                else Text("Sign in")
            }
            (phase as? LoadPhase.Failed)?.let {
                Spacer(Modifier.height(8.dp))
                Text(it.message, color = MaterialTheme.colorScheme.error, style = MaterialTheme.typography.bodySmall)
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(app: AppState, initialSetup: Boolean, onClose: () -> Unit) {
    var url by rememberSaveable { mutableStateOf(app.configuration?.baseUrl ?: "https://") }
    var dbId by rememberSaveable { mutableStateOf(app.configuration?.databaseId ?: "") }
    var testPhase by remember { mutableStateOf<LoadPhase>(LoadPhase.Idle) }
    var testResult by remember { mutableStateOf<String?>(null) }
    var saveError by remember { mutableStateOf<String?>(null) }
    val scope = rememberCoroutineScope()

    fun makeConfig(): ApiConfiguration? {
        val base = ApiConfiguration.normalizedBaseUrl(url) ?: return null
        return ApiConfiguration(baseUrl = base, databaseId = dbId.ifBlank { null })
    }
    val canSave = ApiConfiguration.normalizedBaseUrl(url) != null

    Scaffold(topBar = {
        TopAppBar(
            title = { Text(if (initialSetup) "Set up connection" else "Settings") },
            navigationIcon = { if (!initialSetup) TextButton(onClick = onClose) { Text("Close") } },
            actions = {
                TextButton(
                    enabled = canSave,
                    onClick = {
                        val config = makeConfig()
                        if (config == null) { saveError = "Enter a valid https:// URL." }
                        else { saveError = null; app.configure(config); if (!initialSetup) onClose() }
                    },
                ) { Text("Save") }
            },
        )
    }) { padding ->
        Column(
            Modifier.padding(padding).padding(16.dp).fillMaxSize().verticalScroll(rememberScrollState()),
            verticalArrangement = Arrangement.spacedBy(12.dp),
        ) {
            OutlinedTextField(
                value = url, onValueChange = { url = it }, label = { Text("Server URL (HTTPS)") }, singleLine = true,
                supportingText = { Text("Host or origin, e.g. mcms.lab.svorka.net — HTTPS is required and “/api” is appended automatically.") },
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri),
                modifier = Modifier.fillMaxWidth(),
            )
            OutlinedTextField(
                value = dbId, onValueChange = { dbId = it }, label = { Text("Database ID (optional)") }, singleLine = true,
                modifier = Modifier.fillMaxWidth(),
            )

            Button(
                enabled = canSave && testPhase != LoadPhase.Loading,
                onClick = {
                    val config = makeConfig() ?: return@Button
                    testPhase = LoadPhase.Loading; testResult = null
                    scope.launch {
                        try { testResult = app.probe(config); testPhase = LoadPhase.Loaded }
                        catch (e: Throwable) { testResult = e.uiMessage(); testPhase = LoadPhase.Failed(e.uiMessage()) }
                    }
                },
            ) {
                if (testPhase == LoadPhase.Loading) CircularProgressIndicator(Modifier.size(18.dp), strokeWidth = 2.dp)
                else Text("Test connection")
            }
            testResult?.let {
                val isErr = testPhase is LoadPhase.Failed
                Text(it, color = if (isErr) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onSurfaceVariant,
                    style = MaterialTheme.typography.bodySmall)
            }
            saveError?.let { Text(it, color = MaterialTheme.colorScheme.error) }

            if (!initialSetup) {
                Spacer(Modifier.height(8.dp))
                OutlinedButton(onClick = { scope.launch { app.signOut() } }) { Text("Sign out") }
            }
        }
    }
}
