package dev.inmo.postssystem.client

import dev.inmo.postssystem.client.ui.fsm.*
import dev.inmo.micro_utils.fsm.common.managers.DefaultStatesManagerRepo
import kotlinx.browser.window
import kotlinx.serialization.StringFormat
import org.w3c.dom.*
import org.w3c.dom.url.URL

private fun History.refreshHistory(
    states: Iterable<UIFSMState>,
) {
    val currentUrl = window.location.pathname
    val params = states.mapNotNull<UIFSMState, Pair<String, String>> {
        when (it) {
            is AuthUIFSMState -> null
            is CreatePostUIFSMState -> null
        }
    }
    pushState(
        null,
        "Posts System",
        "$currentUrl${params.joinToString("&", "?") { "${it.first}=${it.second}" }}"
    )
}

private fun takeStates(initialState: UIFSMState): List<UIFSMState> {
    val params = (URL(window.location.href)).searchParams
    val additionalStates = listOfNotNull<UIFSMState>()

    return additionalStates + listOfNotNull(
        if (additionalStates.isEmpty()) {
            initialState
        } else {
            null
        }
    )
}



class JSUIFSMStatesRepo(
    private val history: History,
    private val initialState: UIFSMState = DefaultAuthUIFSMState
) : DefaultStatesManagerRepo<UIFSMState> {
    private val statesMap = mutableMapOf<String, UIFSMState>()

    init {
        val states = takeStates(initialState)
        states.forEach {
            statesMap[it.context] = it
        }
    }

    override suspend fun getContextState(context: Any): UIFSMState? {
        return when (context) {
            is String -> statesMap[context]
            else -> null
        }
    }

    override suspend fun contains(context: Any): Boolean = when (context) {
        is String -> statesMap.contains(context)
        else -> super.contains(context)
    }

    override suspend fun getStates(): List<UIFSMState> = statesMap.values.toList()

    override suspend fun removeState(state: UIFSMState) {
        statesMap.remove((state.context as? String) ?: return)
        history.refreshHistory(statesMap.values)
    }

    override suspend fun set(state: UIFSMState) {
        console.log(state)
        statesMap[state.context] = state
        history.refreshHistory(statesMap.values)
    }
}
