package de.kif.frontend.views

import de.kif.common.formatDate
import de.kif.frontend.launch
import de.kif.frontend.repository.RoomRepository
import de.kif.frontend.repository.WorkGroupRepository
import de.kif.frontend.timezoneOffset
import de.westermann.kobserve.event.EventListener
import de.westermann.kwebview.View
import de.westermann.kwebview.async
import de.westermann.kwebview.components.*
import de.westermann.kwebview.createHtmlView
import de.westermann.kwebview.iterator
import org.w3c.dom.*
import kotlin.browser.document
import kotlin.dom.clear

fun initWorkGroupConstraints() {
    var index = 10000

    val constraints =
        document.getElementsByClassName("work-group-constraints")[0] as HTMLElement
    val addButton =
        View.wrap(document.getElementsByClassName("work-group-constraints-add")[0] as HTMLElement)
    val addList =
        ListView.wrap<View>(document.getElementsByClassName("work-group-constraints-add-list")[0] as HTMLElement)

    val referenceDate = constraints.dataset["reference"]?.toLongOrNull() ?: 0L

    addButton.onClick {
        addList.classList += "active"

        var listener: EventListener<*>? = null

        async {
            listener = Body.onClick.reference {
                addList.classList -= "active"
                listener?.detach()
            }
        }
    }

    fun updateDateView(inputGroup: HTMLElement, day: Int) {
        val date = referenceDate + (day * 1000 * 60 * 60 * 24)
        val dateName = formatDate(date, timezoneOffset)
        inputGroup.dataset["hint"] = dateName
    }

    addList.textView("Nur an Tag x") {
        onClick {
            constraints.appendChild(View.wrap(createHtmlView<HTMLDivElement>()) {
                classList += "input-group"
                html.appendChild(TextView("An Tag").apply {
                    classList += "form-btn"
                    onClick { this@wrap.html.remove() }
                }.html)
                html.appendChild(InputView(InputType.NUMBER).apply {
                    classList += "form-control"
                    html.name = "constraint-only-on-day-${index++}"
                    min = -1337.0
                    max = 1337.0
                    placeholder = "Tag"

                    updateDateView(this@wrap.html, value.toIntOrNull() ?: 0)
                    valueProperty.onChange {
                        updateDateView(this@wrap.html, value.toIntOrNull() ?: 0)
                    }
                }.html)
            }.html)
        }
    }
    addList.textView("Nicht an Tag x") {
        onClick {
            constraints.appendChild(View.wrap(createHtmlView<HTMLDivElement>()) {
                classList += "input-group"
                html.appendChild(TextView("Nicht an Tag").apply {
                    classList += "form-btn"
                    onClick { this@wrap.html.remove() }
                }.html)
                html.appendChild(InputView(InputType.NUMBER).apply {
                    classList += "form-control"
                    html.name = "constraint-not-on-day-${index++}"
                    min = -1337.0
                    max = 1337.0
                    placeholder = "Tag"

                    updateDateView(this@wrap.html, value.toIntOrNull() ?: 0)
                    valueProperty.onChange {
                        updateDateView(this@wrap.html, value.toIntOrNull() ?: 0)
                    }
                }.html)
            }.html)
        }
    }
    addList.textView("Wenn an Tag x, dann vor Zeit t") {
        onClick {
            constraints.appendChild(View.wrap(createHtmlView<HTMLDivElement>()) {
                classList += "input-group"
                html.appendChild(TextView("Vor Zeit").apply {
                    classList += "form-btn"
                    onClick { this@wrap.html.remove() }
                }.html)
                html.appendChild(InputView(InputType.NUMBER).apply {
                    classList += "form-control"
                    html.name = "constraint-only-before-time-day-${index}"
                    placeholder = "Tag (optional)"

                    min = -1337.0
                    max = 1337.0

                    updateDateView(this@wrap.html, value.toIntOrNull() ?: 0)
                    valueProperty.onChange {
                        updateDateView(this@wrap.html, value.toIntOrNull() ?: 0)
                    }
                }.html)
                html.appendChild(InputView(InputType.TEXT).apply {
                    classList += "form-control"
                    html.name = "constraint-only-before-time-${index++}"
                    placeholder = "HH:MM | Min"
                }.html)
            }.html)
        }
    }
    addList.textView("Wenn an Tag x, dann ab Zeit t") {
        onClick {
            constraints.appendChild(View.wrap(createHtmlView<HTMLDivElement>()) {
                classList += "input-group"
                html.appendChild(TextView("Nach Zeit").apply {
                    classList += "form-btn"
                    onClick { this@wrap.html.remove() }
                }.html)
                html.appendChild(InputView(InputType.NUMBER).apply {
                    classList += "form-control"
                    html.name = "constraint-only-after-time-day-${index}"
                    placeholder = "Tag (optional)"

                    min = -1337.0
                    max = 1337.0

                    updateDateView(this@wrap.html, value.toIntOrNull() ?: 0)
                    valueProperty.onChange {
                        updateDateView(this@wrap.html, value.toIntOrNull() ?: 0)
                    }
                }.html)
                html.appendChild(InputView(InputType.TEXT).apply {
                    classList += "form-control"
                    html.name = "constraint-only-after-time-${index++}"
                    placeholder = "HH:MM | Min"
                }.html)
            }.html)
        }
    }
    addList.textView("Wenn an Tag x, dann Zeitpunkt t") {
        onClick {
            constraints.appendChild(View.wrap(createHtmlView<HTMLDivElement>()) {
                classList += "input-group"
                html.appendChild(TextView("Zeitpunkt").apply {
                    classList += "form-btn"
                    onClick { this@wrap.html.remove() }
                }.html)
                html.appendChild(InputView(InputType.NUMBER).apply {
                    classList += "form-control"
                    html.name = "constraint-exact-time-day-${index}"
                    placeholder = "Tag (optional)"

                    min = -1337.0
                    max = 1337.0

                    updateDateView(this@wrap.html, value.toIntOrNull() ?: 0)
                    valueProperty.onChange {
                        updateDateView(this@wrap.html, value.toIntOrNull() ?: 0)
                    }
                }.html)
                html.appendChild(InputView(InputType.TEXT).apply {
                    classList += "form-control"
                    html.name = "constraint-exact-time-${index++}"
                    placeholder = "HH:MM | Min"
                }.html)
            }.html)
        }
    }
    addList.textView("Nicht zur selben Zeit wie AK x") {
        onClick {
            constraints.appendChild(View.wrap(createHtmlView<HTMLDivElement>()) {
                classList += "input-group"
                html.appendChild(TextView("Nicht parallel").apply {
                    classList += "form-btn"
                    onClick { this@wrap.html.remove() }
                }.html)

                val select = createHtmlView<HTMLSelectElement>()
                select.classList.add("form-control")
                select.name = "constraint-not-at-same-time-${index++}"

                launch {
                    val all = WorkGroupRepository.all()

                    val id = (select.options[select.selectedIndex] as? HTMLOptionElement)?.value

                    for (wg in all) {
                        val option = createHtmlView<HTMLOptionElement>()
                        option.value = wg.id.toString()
                        option.textContent = wg.name
                        if (option.value == id) {
                            option.selected = true
                        }
                        select.appendChild(option)
                    }
                }

                html.appendChild(select)
            }.html)
        }
    }
    addList.textView("Nachdem AK x stattgefunden hat") {
        onClick {
            constraints.appendChild(View.wrap(createHtmlView<HTMLDivElement>()) {
                classList += "input-group"
                html.appendChild(TextView("Nach AK").apply {
                    classList += "form-btn"
                    onClick { this@wrap.html.remove() }
                }.html)

                val select = createHtmlView<HTMLSelectElement>()
                select.classList.add("form-control")
                select.name = "constraint-only-after-work-group-${index++}"

                launch {
                    val all = WorkGroupRepository.all()

                    val id = (select.options[select.selectedIndex] as? HTMLOptionElement)?.value

                    for (wg in all) {
                        val option = createHtmlView<HTMLOptionElement>()
                        option.value = wg.id.toString()
                        option.textContent = wg.name
                        if (option.value == id) {
                            option.selected = true
                        }
                        select.appendChild(option)
                    }
                }

                html.appendChild(select)
            }.html)
        }
    }
    addList.textView("In Raum x") {
        onClick {
            constraints.appendChild(View.wrap(createHtmlView<HTMLDivElement>()) {
                classList += "input-group"
                html.appendChild(TextView("Raum").apply {
                    classList += "form-btn"
                    onClick { this@wrap.html.remove() }
                }.html)

                val select = createHtmlView<HTMLSelectElement>()
                select.classList.add("form-control")
                select.name = "constraint-room-${index++}"

                val id = (select.options[select.selectedIndex] as? HTMLOptionElement)?.value

                launch {
                    val all = RoomRepository.all()
                    select.clear()

                    for (room in all) {
                        val option = createHtmlView<HTMLOptionElement>()
                        option.value = room.id.toString()
                        option.textContent = room.name
                        if (option.value == id) {
                            option.selected = true
                        }
                        select.appendChild(option)
                    }
                }

                html.appendChild(select)
            }.html)
        }
    }

    for (child in constraints.children.iterator()) {
        if (child.classList.contains("input-group")) {
            val span = child.firstElementChild as HTMLElement

            span.addEventListener("click", org.w3c.dom.events.EventListener {
                child.remove()
            })

            for (e in child.children.iterator()) {
                if (e is HTMLInputElement && e.name.contains("-day-")) {
                    val input = InputView.wrap(InputType.NUMBER, e)

                    updateDateView(child, input.value.toIntOrNull() ?: 0)
                    input.valueProperty.onChange {
                        updateDateView(child, input.value.toIntOrNull() ?: 0)
                    }
                }
            }
        }
    }
}
