package com.fabledsword.minstrel.auth.ui

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavHostController
import com.fabledsword.minstrel.auth.AuthStore
import com.fabledsword.minstrel.nav.Login
import com.fabledsword.minstrel.nav.ServerUrl
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject

// ─── State + VM ───────────────────────────────────────────────────────

data class ServerUrlFormState(
    val url: String = "",
    val saving: Boolean = false,
    val saved: Boolean = false,
    val errorMessage: String? = null,
)

@HiltViewModel
class ServerUrlViewModel @Inject constructor(
    private val authStore: AuthStore,
) : ViewModel() {

    private val internal = MutableStateFlow(
        // Pre-fill ONLY if the user has previously saved a real URL —
        // the DEFAULT_BASE_URL placeholder (`http://localhost:8080`) is
        // an internal HTTP-client fallback, not something a user
        // typed. Leaving the field empty lets the OutlinedTextField's
        // placeholder ("https://minstrel.example.com") show through
        // so the user can just type without first having to clear.
        ServerUrlFormState(
            url = authStore.baseUrl.value
                .takeIf { it != AuthStore.DEFAULT_BASE_URL }
                .orEmpty(),
        ),
    )
    val state: StateFlow<ServerUrlFormState> = internal.asStateFlow()

    fun setUrl(value: String) {
        internal.update { it.copy(url = value, errorMessage = null) }
    }

    fun submit() {
        val raw = internal.value.url.trim().trimEnd('/')
        if (raw.isEmpty()) {
            internal.update { it.copy(errorMessage = "Enter a server URL.") }
            return
        }
        if (!raw.startsWith("http://") && !raw.startsWith("https://")) {
            internal.update {
                it.copy(errorMessage = "URL must start with http:// or https://")
            }
            return
        }
        viewModelScope.launch {
            internal.update { it.copy(saving = true, errorMessage = null) }
            authStore.setBaseUrl(raw)
            internal.update { it.copy(saving = false, saved = true) }
        }
    }

    fun consumeSaved() {
        internal.update { it.copy(saved = false) }
    }
}

// ─── Screen ───────────────────────────────────────────────────────────

@Composable
fun ServerUrlScreen(
    navController: NavHostController,
    viewModel: ServerUrlViewModel = hiltViewModel(),
) {
    val state by viewModel.state.collectAsStateWithLifecycle()

    LaunchedEffect(state.saved) {
        if (state.saved) {
            navController.navigate(Login) {
                popUpTo(ServerUrl) { inclusive = true }
            }
            viewModel.consumeSaved()
        }
    }

    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colorScheme.background,
        contentColor = MaterialTheme.colorScheme.onBackground,
    ) {
        ServerUrlForm(
            state = state,
            onUrlChange = viewModel::setUrl,
            onSubmit = viewModel::submit,
        )
    }
}

@Composable
private fun ServerUrlForm(
    state: ServerUrlFormState,
    onUrlChange: (String) -> Unit,
    onSubmit: () -> Unit,
) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(24.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically),
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        Text(
            text = "Connect to your Minstrel",
            style = MaterialTheme.typography.headlineMedium,
            color = MaterialTheme.colorScheme.onBackground,
        )
        Text(
            text = "Enter the URL of your Minstrel server.",
            style = MaterialTheme.typography.bodyMedium,
            color = MaterialTheme.colorScheme.onSurfaceVariant,
        )
        OutlinedTextField(
            value = state.url,
            onValueChange = onUrlChange,
            modifier = Modifier.fillMaxWidth(),
            label = { Text("Server URL") },
            placeholder = { Text("https://minstrel.example.com") },
            singleLine = true,
            enabled = !state.saving,
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Uri,
                imeAction = ImeAction.Done,
            ),
            keyboardActions = KeyboardActions(onDone = { onSubmit() }),
        )
        if (state.errorMessage != null) {
            Text(
                text = state.errorMessage,
                color = MaterialTheme.colorScheme.error,
                style = MaterialTheme.typography.bodySmall,
            )
        }
        Button(
            onClick = onSubmit,
            enabled = !state.saving && state.url.isNotBlank(),
            modifier = Modifier.fillMaxWidth(),
        ) { Text("Continue") }
    }
}
