package de.tsschulz.timeclock.ui.auth

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
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.defaultMinSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import de.tsschulz.timeclock.ui.components.TcBrandTitle
import de.tsschulz.timeclock.ui.components.TcButton
import de.tsschulz.timeclock.ui.components.TcTextField
import de.tsschulz.timeclock.ui.model.ButtonVariant
import de.tsschulz.timeclock.ui.theme.TcColors
import de.tsschulz.timeclock.ui.theme.TcRadius
import de.tsschulz.timeclock.ui.theme.TcSpacing

/**
 * Layout und Farben an die Web-Loginseite angelehnt (`Login.vue`: `.auth-page`, Navbar, `.auth-form-container`).
 */
@Composable
fun LoginScreen(
    state: AuthUiState,
    onLogin: (email: String, password: String, action: String) -> Unit,
    onGoogleLogin: () -> Unit,
    onLinkExistingGoogleAccount: (email: String, password: String) -> Unit,
    onRetryBootstrap: () -> Unit,
    modifier: Modifier = Modifier,
) {
    var email by rememberSaveable { mutableStateOf("") }
    var password by rememberSaveable { mutableStateOf("") }
    var linkEmail by rememberSaveable { mutableStateOf("") }
    var linkPassword by rememberSaveable { mutableStateOf("") }

    BoxWithConstraints(
        modifier = modifier
            .fillMaxSize()
            .background(TcColors.Background),
    ) {
        val useWideFormRows = maxWidth >= 560.dp
        val formHorizontalPadding = if (maxWidth < 420.dp) 24.dp else 48.dp
        val formVerticalPadding = if (maxWidth < 420.dp) 24.dp else 40.dp

        Column(Modifier.fillMaxSize()) {
            LoginTopBar()

            Box(
                modifier = Modifier
                    .weight(1f)
                    .fillMaxWidth()
                    .padding(horizontal = TcSpacing.Xxl, vertical = TcSpacing.WebContainer),
                contentAlignment = Alignment.Center,
            ) {
                Column(
                    modifier = Modifier
                        .widthIn(max = 900.dp)
                        .fillMaxWidth()
                        .verticalScroll(rememberScrollState()),
                    horizontalAlignment = Alignment.CenterHorizontally,
                ) {
                    Column(
                        modifier = Modifier
                            .fillMaxWidth()
                            .shadow(4.dp, RoundedCornerShape(TcRadius.AuthPanel), clip = false)
                            .background(TcColors.FormSurface, RoundedCornerShape(TcRadius.AuthPanel))
                            .border(BorderStroke(1.dp, TcColors.Border), RoundedCornerShape(TcRadius.AuthPanel)),
                    ) {
                        Box(
                            modifier = Modifier
                                .fillMaxWidth()
                                .background(
                                    TcColors.FormHeaderBg,
                                    RoundedCornerShape(topStart = TcRadius.AuthPanel, topEnd = TcRadius.AuthPanel),
                                )
                                .padding(vertical = 12.dp),
                            contentAlignment = Alignment.Center,
                        ) {
                            Text(
                                text = "Einloggen",
                                color = TcColors.Text,
                                fontSize = 25.6.sp,
                                fontWeight = FontWeight.Medium,
                                textAlign = TextAlign.Center,
                            )
                        }
                        HorizontalDivider(color = TcColors.Border, thickness = 1.dp)

                        Column(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(horizontal = formHorizontalPadding, vertical = formVerticalPadding),
                            verticalArrangement = Arrangement.spacedBy(16.dp),
                        ) {
                            if (state.bootstrapping) {
                                Text(
                                    text = "Sitzung wird geprüft…",
                                    color = TcColors.TextMuted,
                                    fontSize = 14.sp,
                                    modifier = Modifier.fillMaxWidth(),
                                    textAlign = TextAlign.Center,
                                )
                            } else {
                                state.bootstrapWarn?.let { msg ->
                                    AuthErrorBanner(message = msg)
                                    Row(
                                        modifier = Modifier.fillMaxWidth(),
                                        horizontalArrangement = Arrangement.Center,
                                    ) {
                                        TcButton(
                                            text = "Erneut versuchen",
                                            variant = ButtonVariant.Primary,
                                            onClick = onRetryBootstrap,
                                        )
                                    }
                                }

                                state.error?.let { AuthErrorBanner(message = it) }

                                if (!state.oauthPendingToken.isNullOrBlank()) {
                                    if (linkEmail.isBlank()) linkEmail = state.oauthPendingEmail.orEmpty()
                                    Text(
                                        text = "Für ${state.oauthPendingEmail ?: "dieses Google-Konto"} existiert bereits ein Account. Melden Sie sich mit dem bestehenden Account an, um ihn zu verknüpfen.",
                                        color = TcColors.Text,
                                        fontSize = 14.sp,
                                    )
                                    AuthFormRow(label = "E-Mail-Adresse", horizontal = useWideFormRows) {
                                        TcTextField(label = "", value = linkEmail, onValueChange = { linkEmail = it }, showLabel = false)
                                    }
                                    AuthFormRow(label = "Passwort", horizontal = useWideFormRows) {
                                        TcTextField(label = "", value = linkPassword, onValueChange = { linkPassword = it }, isPassword = true, showLabel = false)
                                    }
                                    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
                                        TcButton(
                                            text = if (state.loginInProgress) "Wird verknüpft…" else "Bestehenden Account verknüpfen",
                                            variant = ButtonVariant.Primary,
                                            onClick = { onLinkExistingGoogleAccount(linkEmail, linkPassword) },
                                        )
                                    }
                                } else {
                                    AuthFormRow(
                                        label = "E-Mail-Adresse",
                                        horizontal = useWideFormRows,
                                    ) {
                                        TcTextField(
                                            label = "",
                                            value = email,
                                            onValueChange = { email = it },
                                            placeholder = "Ihre E-Mail-Adresse eingeben",
                                            showLabel = false,
                                        )
                                    }
                                    AuthFormRow(
                                        label = "Passwort",
                                        horizontal = useWideFormRows,
                                    ) {
                                        TcTextField(
                                            label = "",
                                            value = password,
                                            onValueChange = { password = it },
                                            placeholder = "Ihr Passwort eingeben",
                                            isPassword = true,
                                            showLabel = false,
                                        )
                                    }

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

                                    Row(
                                        modifier = Modifier.fillMaxWidth(),
                                        horizontalArrangement = Arrangement.Center,
                                    ) {
                                        TcButton(
                                            text = if (state.loginInProgress) "Wird eingeloggt…" else "Einloggen",
                                            variant = ButtonVariant.Primary,
                                            onClick = { onLogin(email, password, "0") },
                                            modifier = Modifier.defaultMinSize(minWidth = 140.dp),
                                            contentPadding = PaddingValues(horizontal = 24.dp, vertical = 10.dp),
                                        )
                                    }

                                    OAuthDivider()

                                    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
                                        TcButton(
                                            text = "Mit Google anmelden",
                                            variant = ButtonVariant.Default,
                                            onClick = onGoogleLogin,
                                            modifier = Modifier.defaultMinSize(minWidth = 220.dp),
                                            contentPadding = PaddingValues(horizontal = 24.dp, vertical = 10.dp),
                                        )
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

@Composable
private fun OAuthDivider() {
    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(TcSpacing.Md),
    ) {
        HorizontalDivider(modifier = Modifier.weight(1f), color = TcColors.Border)
        Text("oder", color = TcColors.DividerText, fontSize = 14.sp)
        HorizontalDivider(modifier = Modifier.weight(1f), color = TcColors.Border)
    }
}

@Composable
private fun LoginTopBar() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .shadow(2.dp)
            .background(TcColors.Navbar)
            .border(BorderStroke(1.dp, TcColors.BorderSoft))
            .padding(horizontal = TcSpacing.WebContainer, vertical = TcSpacing.Md),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        TcBrandTitle()
    }
}

@Composable
private fun AuthErrorBanner(message: String) {
    Text(
        text = message,
        color = TcColors.AuthErrorText,
        fontSize = 14.sp,
        modifier = Modifier
            .fillMaxWidth()
            .background(TcColors.AuthErrorBg, RoundedCornerShape(TcRadius.Medium))
            .border(BorderStroke(1.dp, TcColors.AuthErrorBorder), RoundedCornerShape(TcRadius.Medium))
            .padding(12.dp),
    )
}

@Composable
private fun AuthFormRow(
    label: String,
    horizontal: Boolean,
    content: @Composable () -> Unit,
) {
    if (horizontal) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.spacedBy(16.dp),
        ) {
            Text(
                text = label,
                color = Color333,
                fontWeight = FontWeight.Medium,
                fontSize = 14.sp,
                modifier = Modifier.width(192.dp),
            )
            Box(modifier = Modifier.weight(1f)) {
                content()
            }
        }
    } else {
        Column(modifier = Modifier.fillMaxWidth()) {
            Text(
                text = label,
                color = Color333,
                fontWeight = FontWeight.Medium,
                fontSize = 14.sp,
                modifier = Modifier.padding(bottom = TcSpacing.Sm),
            )
            content()
        }
    }
}

private val Color333 = androidx.compose.ui.graphics.Color(0xFF333333)
