package com.ponzischeme89.memby.ui.setup

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
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.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.tv.material3.Text
import com.ponzischeme89.memby.R
import com.ponzischeme89.memby.ui.TvTextField
import com.ponzischeme89.memby.ui.UpdateButton
import com.ponzischeme89.memby.ui.theme.MembyMutedText
import com.ponzischeme89.memby.ui.theme.MembyOnSurface
import com.ponzischeme89.memby.ui.theme.MembySurface

/**
 * The sign-in form, with no dependency on the repository — so it can be screenshotted and
 * looked at without a server (`OnboardingScreenshotTest`). `SetupScreen` owns the
 * authentication and hands the state in.
 *
 * It sits on flat [MembySurface] like every other full-screen surface in the app. It used to
 * be a bordered translucent card floating on a radial gradient, which was the only place in
 * Memby that looked like that — and it is the *first* thing anyone sees, so it set an
 * expectation the rest of the app then contradicted. The panel earned nothing: there is
 * nothing behind it to be raised above.
 */
@Composable
fun SignInContent(
    username: String,
    password: String,
    onUsernameChange: (String) -> Unit,
    onPasswordChange: (String) -> Unit,
    onSubmit: () -> Unit,
    connecting: Boolean,
    error: String?,
    onBack: (() -> Unit)?,
    modifier: Modifier = Modifier,
    usernameFocus: FocusRequester = remember { FocusRequester() },
    passwordFocus: FocusRequester = remember { FocusRequester() },
    signInFocus: FocusRequester = remember { FocusRequester() },
    backFocus: FocusRequester = remember { FocusRequester() },
) {
    val addingViewer = onBack != null
    Box(
        modifier = modifier
            .fillMaxSize()
            .background(MembySurface)
            .padding(horizontal = 72.dp, vertical = 40.dp),
        contentAlignment = Alignment.Center,
    ) {
        Column(
            // The form is taller than the safe content area on some Android TVs, and a
            // scroll container is also what lets Compose lift the focused field above the
            // on-screen keyboard instead of clipping it.
            modifier = Modifier.width(560.dp).verticalScroll(rememberScrollState()),
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            Image(
                painter = painterResource(R.drawable.emby_logo),
                contentDescription = null,
                modifier = Modifier.size(52.dp),
            )
            Spacer(Modifier.height(20.dp))
            Text(
                if (addingViewer) "Add another viewer" else "Welcome to Memby",
                color = MembyOnSurface,
                fontSize = 30.sp,
                fontWeight = FontWeight.SemiBold,
            )
            Spacer(Modifier.height(8.dp))
            Text(
                if (addingViewer) {
                    "Their account is saved as another profile on this TV."
                } else {
                    "Sign in with your Emby account."
                },
                color = MembyMutedText,
                fontSize = 16.sp,
            )

            Spacer(Modifier.height(30.dp))
            TvTextField(
                label = "Username",
                value = username,
                onValueChange = onUsernameChange,
                focusRequester = usernameFocus,
                onNext = { passwordFocus.requestFocus() },
            )
            Spacer(Modifier.height(16.dp))
            TvTextField(
                label = "Password",
                value = password,
                onValueChange = onPasswordChange,
                isPassword = true,
                focusRequester = passwordFocus,
                downFocusRequester = signInFocus,
                onDone = onSubmit,
            )

            error?.let {
                Spacer(Modifier.height(16.dp))
                Text(it, color = SignInError, fontSize = 15.sp)
            }

            Spacer(Modifier.height(28.dp))
            Row(
                modifier = Modifier.fillMaxWidth(),
                // Centred under a centred form. End-aligned buttons were the last trace of
                // the card this screen used to be, and read as belonging to a dialog.
                horizontalArrangement = Arrangement.spacedBy(14.dp, Alignment.CenterHorizontally),
            ) {
                if (onBack != null) {
                    UpdateButton(
                        label = "Back",
                        primary = false,
                        enabled = !connecting,
                        onClick = onBack,
                        modifier = Modifier
                            .focusRequester(backFocus)
                            .focusProperties { right = signInFocus },
                    )
                }
                UpdateButton(
                    label = if (connecting) "Signing in…" else "Sign in",
                    primary = true,
                    enabled = !connecting,
                    onClick = onSubmit,
                    modifier = Modifier
                        .focusRequester(signInFocus)
                        .focusProperties { if (onBack != null) left = backFocus },
                )
            }
        }
    }
}

/** The one red in the app that means "this went wrong", matched to Settings' own notices. */
private val SignInError = Color(0xFFFF7777)
