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

import androidx.compose.runtime.*
import dev.inmo.jsuikit.elements.*
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.Attrs
import dev.inmo.micro_utils.common.compose.DefaultDisposableEffectResult
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.micro_utils.fsm.common.StatesMachine
import dev.inmo.postssystem.client.ui.fsm.CreatePostUIFSMState
import dev.inmo.postssystem.client.ui.fsm.UIFSMState
import dev.inmo.postssystem.client.utils.renderComposableAndLinkToContext
import dev.inmo.postssystem.features.content.client.ContentClientProvider
import dev.inmo.postssystem.features.content.common.Content
import dev.inmo.postssystem.services.posts.client.ui.create.PostCreateUIViewModel
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.StateFlow
import org.jetbrains.compose.web.dom.Div
import org.jetbrains.compose.web.dom.Text
import org.w3c.dom.HTMLElement

class PostCreateView(
    private val createPostCreateUIModel: PostCreateUIViewModel,
    private val contentClientProviders: List<ContentClientProvider>,
    private val uiScope: CoroutineScope
) : JSView<CreatePostUIFSMState>() {
    override suspend fun StatesMachine<in UIFSMState>.safeHandleState(
        htmlElement: HTMLElement,
        state: CreatePostUIFSMState
    ): UIFSMState? {
        val result = CompletableDeferred<UIFSMState?>()

        val contentProvidersList = mutableStateListOf<ContentClientProvider>()
        val statesList = mutableListOf<StateFlow<Content>>()

        renderComposableAndLinkToContext(htmlElement) {
            Flex(
                UIKitFlex.Alignment.Horizontal.Center
            ) {
                Div ({ include(UIKitWidth.Fixed.XLarge) }) {
                    contentProvidersList.forEachIndexed { i, renderer ->
                        Flex(UIKitWidth.Expand) {
                            Div(
                                {
                                    ref {
                                        val flow = renderer.drawNewContent(it)
                                        statesList.add(i, flow)
                                        DefaultDisposableEffectResult {
                                            statesList.removeAt(i)
                                        }
                                    }
                                }
                            )

                            DefaultButton("Remove") {
                                contentProvidersList.removeAt(i)
                            }
                        }
                    }
                    Label("Add content", Attrs.empty())
                    Dropdown {
                        DefaultNav {
                            contentClientProviders.forEach {
                                NavItemElement(
                                    attributesCustomizer = {
                                        onClick { _ ->
                                            contentProvidersList.add(it)
                                        }
                                    }
                                ) {
                                    Text(it.contentTypeNameForUser())
                                }
                            }
                        }
                    }
                    DefaultButton(
                        "Upload",
                        disabled = contentProvidersList.isEmpty()
                    ) {
                        it.preventDefault()
                        uiScope.launchSafelyWithoutExceptions {
                            createPostCreateUIModel.create(
                                statesList.map { it.value }
                            )
                        }
                    }
                }
            }
        }

        return result.await()
    }
}