package dev.inmo.postssystem.client.fsm.ui

import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import dev.inmo.jsuikit.elements.*
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.Attrs
import dev.inmo.postssystem.client.ui.fsm.*
import dev.inmo.postssystem.features.auth.client.ui.*
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.fsm.common.StatesMachine
import dev.inmo.postssystem.client.utils.renderComposableAndLinkToContext
import kotlinx.browser.document
import kotlinx.coroutines.*
import kotlinx.dom.*
import org.jetbrains.compose.web.attributes.InputType
import org.jetbrains.compose.web.dom.Form
import org.jetbrains.compose.web.dom.Text
import org.w3c.dom.*

class AuthView(
    private val viewModel: AuthUIViewModel,
    private val uiScope: CoroutineScope
) : JSView<AuthUIFSMState>() {

    override suspend fun StatesMachine<in UIFSMState>.safeHandleState(
        htmlElement: HTMLElement,
        state: AuthUIFSMState
    ): UIFSMState? {
        val completion = CompletableDeferred<UIFSMState?>()

        val usernameState = mutableStateOf("")
        val passwordState = mutableStateOf("")
        val usernameDisabled = mutableStateOf(true)
        val passwordDisabled = mutableStateOf(true)
        val errorText = mutableStateOf<String?>(null)

        val root = htmlElement.appendElement("div") {
            addClass(*UIKitWidth.Fixed.Medium.classes, *UIKitText.Alignment.Center.classes)
        }
        val composition = renderComposableAndLinkToContext(root) {
            val authBtnDisabled = usernameState.value.isBlank() || passwordState.value.isBlank()
            console.log(authBtnDisabled)

            Card(
                Attrs(UIKitWidth.Fixed.Medium),
                footerAttrs = Attrs(UIKitText.Alignment.Center),
                footer = {
                    DefaultButton("Authorise", UIKitButton.Type.Primary, disabled = authBtnDisabled) {
                        it.nativeEvent.preventDefault()
                        val serverUrl = document.location ?.run { "$hostname:$port" }
                        if (serverUrl != null) {
                            uiScope.launchSafelyWithoutExceptions { viewModel.initAuth(serverUrl, usernameState.value, passwordState.value) }
                        }
                    }
                }
            ) {
                CardTitle { Text("Log in") }

                TextField(
                    InputType.Text,
                    usernameState,
                    disabledState = usernameDisabled
                )
                TextField(
                    InputType.Password,
                    passwordState,
                    disabledState = passwordDisabled
                )

                if (errorText.value != null) {
                    Label(errorText.value.toString(), Attrs(UIKitLabel.Error, UIKitMargin.Small.Bottom))
                }
            }
        }

        val viewJob = viewModel.currentState.subscribeSafelyWithoutExceptions(uiScope) {
            when (it) {
                is InitAuthUIState -> {
                    usernameDisabled.value = false
                    passwordDisabled.value = false

                    errorText.value = when (it.showError) {
                        ServerUnavailableAuthUIError -> "Сервер недоступен"
                        AuthIncorrectAuthUIError -> "Данные некорректны"
                        null -> null
                    }
                }
                LoadingAuthUIState -> {
                    usernameDisabled.value = true
                    passwordDisabled.value = true
                    errorText.value = null
                }
                AuthorizedAuthUIState -> {
                    completion.complete(state.from)
                }
            }
        }
        return completion.await().also {
            composition.dispose()
            viewJob.cancel()
        }
    }
}
