package de.kif.backend.route

import de.kif.backend.authenticateOrRedirect
import de.kif.backend.repository.RoomRepository
import de.kif.backend.view.MainTemplate
import de.kif.backend.view.MenuTemplate
import de.kif.backend.view.TableTemplate
import de.kif.backend.view.respondMain
import de.kif.common.Search
import de.kif.common.model.Permission
import de.kif.common.model.Room
import io.ktor.application.call
import io.ktor.html.insert
import io.ktor.html.respondHtmlTemplate
import io.ktor.request.receiveParameters
import io.ktor.response.respondRedirect
import io.ktor.routing.Route
import io.ktor.routing.get
import io.ktor.routing.post
import io.ktor.util.toMap
import kotlinx.css.CSSBuilder
import kotlinx.css.Display
import kotlinx.html.*
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set

fun Route.room() {

    get("/rooms") {
        authenticateOrRedirect(Permission.ROOM) { user ->
            val search = call.parameters["search"] ?: ""
            val list = RoomRepository.all()

            respondMain {
                menuTemplate {
                    this.user = user
                    active = MenuTemplate.Tab.ROOM
                }
                content {
                    insert(TableTemplate()) {
                        searchValue = search

                        action {
                            a("/room/new") {
                                button(classes = "form-btn btn-primary") {
                                    +"Add room"
                                }
                            }
                        }

                        header {
                            th {
                                +"Name"
                            }
                            th {
                                +"Places"
                            }
                            th {
                                +"Projector"
                            }
                            th(classes = "action") {
                                +"Action"
                            }
                        }

                        for (u in list) {
                            val s = u.createSearch()
                            entry {
                                attributes["style"] = CSSBuilder().apply {
                                    display = if (Search.match(search, s)) Display.tableRow else Display.none
                                }.toString()
                                attributes["data-search"] = s.stringify()
                                attributes["data-edit"] = "room"
                                attributes["data-id"] = u.id.toString()

                                td {
                                    span {
                                        attributes["data-edit-type"] = "room-name"

                                        +u.name
                                    }
                                }
                                td {
                                    span {
                                        attributes["data-edit-type"] = "room-places"

                                        +u.places.toString()
                                    }
                                }
                                td {
                                    span {
                                        attributes["data-edit-type"] = "room-projector"

                                        +u.projector.toString()
                                    }
                                }
                                td(classes = "action") {
                                    a("/room/${u.id}") {
                                        i("material-icons") { +"edit" }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    get("/room/{id}") {
        authenticateOrRedirect(Permission.ROOM) { user ->
            val roomId = call.parameters["id"]?.toLongOrNull() ?: return@get
            val editRoom = RoomRepository.get(roomId) ?: return@get
            respondMain {
                menuTemplate {
                    this.user = user
                    active = MenuTemplate.Tab.ROOM
                }
                content {
                    h1 { +"Edit room" }
                    form(method = FormMethod.post) {
                        div("form-group") {
                            label {
                                htmlFor = "name"
                                +"Name"
                            }
                            input(
                                name = "name",
                                classes = "form-control"
                            ) {
                                id = "name"
                                placeholder = "Name"
                                value = editRoom.name
                            }
                        }
                        div("form-group") {
                            label {
                                htmlFor = "places"
                                +"Places"
                            }
                            input(
                                name = "places",
                                classes = "form-control",
                                type = InputType.number
                            ) {
                                id = "places"
                                placeholder = "Places"
                                value = editRoom.places.toString()

                                min = "0"
                                max = "1337"
                            }
                        }

                        div("form-switch-group") {
                            div("form-group form-switch") {
                                input(
                                    name = "projector",
                                    classes = "form-control",
                                    type = InputType.checkBox
                                ) {
                                    id = "projector"
                                    checked = editRoom.projector
                                }
                                label {
                                    htmlFor = "projector"
                                    +"Projector"
                                }
                            }

                            div("form-group form-switch") {
                                input(
                                    name = "internet",
                                    classes = "form-control",
                                    type = InputType.checkBox
                                ) {
                                    id = "internet"
                                    checked = editRoom.internet
                                }
                                label {
                                    htmlFor = "internet"
                                    +"Internet"
                                }
                            }

                            div("form-group form-switch") {
                                input(
                                    name = "whiteboard",
                                    classes = "form-control",
                                    type = InputType.checkBox
                                ) {
                                    id = "whiteboard"
                                    checked = editRoom.whiteboard
                                }
                                label {
                                    htmlFor = "whiteboard"
                                    +"Whiteboard"
                                }
                            }

                            div("form-group form-switch") {
                                input(
                                    name = "blackboard",
                                    classes = "form-control",
                                    type = InputType.checkBox
                                ) {
                                    id = "blackboard"
                                    checked = editRoom.blackboard
                                }
                                label {
                                    htmlFor = "blackboard"
                                    +"Blackboard"
                                }
                            }

                            div("form-group form-switch") {
                                input(
                                    name = "accessible",
                                    classes = "form-control",
                                    type = InputType.checkBox
                                ) {
                                    id = "accessible"
                                    checked = editRoom.accessible
                                }
                                label {
                                    htmlFor = "accessible"
                                    +"Accessible"
                                }
                            }
                        }

                        div("form-group") {
                            a("/room") {
                                button(classes = "form-btn") {
                                    +"Cancel"
                                }
                            }
                            button(type = ButtonType.submit, classes = "form-btn btn-primary") {
                                +"Save"
                            }
                        }
                    }
                    a("/room/${editRoom.id}/delete") {
                        button(classes = "form-btn btn-danger") {
                            +"Delete"
                        }
                    }
                }
            }
        }
    }

    post("/room/{id}") {
        authenticateOrRedirect(Permission.ROOM) { user ->
            val roomId = call.parameters["id"]?.toLongOrNull() ?: return@post
            val params = call.receiveParameters().toMap().mapValues { (_, list) ->
                list.firstOrNull()
            }
            var room = RoomRepository.get(roomId) ?: return@post

            params["name"]?.let { room = room.copy(name = it) }
            params["places"]?.let { room = room.copy(places = it.toIntOrNull() ?: 0) }
            params["projector"]?.let { room = room.copy(projector = it == "on") }
            params["internet"]?.let { room = room.copy(internet = it == "on") }
            params["whiteboard"]?.let { room = room.copy(whiteboard = it == "on") }
            params["blackboard"]?.let { room = room.copy(blackboard = it == "on") }
            params["accessible"]?.let { room = room.copy(accessible = it == "on") }

            RoomRepository.update(room)

            call.respondRedirect("/rooms")
        }
    }

    get("/room/new") {
        authenticateOrRedirect(Permission.ROOM) { user ->
            respondMain {
                menuTemplate {
                    this.user = user
                    active = MenuTemplate.Tab.ROOM
                }
                content {
                    h1 { +"Create room" }
                    form(method = FormMethod.post) {
                        div("form-group") {
                            label {
                                htmlFor = "name"
                                +"Name"
                            }
                            input(
                                name = "name",
                                classes = "form-control"
                            ) {
                                id = "name"
                                placeholder = "Name"
                                value = ""
                            }
                        }
                        div("form-group") {
                            label {
                                htmlFor = "places"
                                +"Places"
                            }
                            input(
                                name = "places",
                                classes = "form-control",
                                type = InputType.number
                            ) {
                                id = "places"
                                placeholder = "Places"
                                value = "0"

                                min = "0"
                                max = "1337"
                            }
                        }

                        div("form-switch-group") {
                            div("form-group form-switch") {
                                input(
                                    name = "projector",
                                    classes = "form-control",
                                    type = InputType.checkBox
                                ) {
                                    id = "projector"
                                    checked = false
                                }
                                label {
                                    htmlFor = "projector"
                                    +"Projector"
                                }
                            }

                            div("form-group form-switch") {
                                input(
                                    name = "internet",
                                    classes = "form-control",
                                    type = InputType.checkBox
                                ) {
                                    id = "internet"
                                    checked = false
                                }
                                label {
                                    htmlFor = "internet"
                                    +"Internet"
                                }
                            }

                            div("form-group form-switch") {
                                input(
                                    name = "whiteboard",
                                    classes = "form-control",
                                    type = InputType.checkBox
                                ) {
                                    id = "whiteboard"
                                    checked = false
                                }
                                label {
                                    htmlFor = "whiteboard"
                                    +"Whiteboard"
                                }
                            }

                            div("form-group form-switch") {
                                input(
                                    name = "blackboard",
                                    classes = "form-control",
                                    type = InputType.checkBox
                                ) {
                                    id = "blackboard"
                                    checked = false
                                }
                                label {
                                    htmlFor = "blackboard"
                                    +"Blackboard"
                                }
                            }

                            div("form-group form-switch") {
                                input(
                                    name = "accessible",
                                    classes = "form-control",
                                    type = InputType.checkBox
                                ) {
                                    id = "accessible"
                                    checked = false
                                }
                                label {
                                    htmlFor = "accessible"
                                    +"Accessible"
                                }
                            }
                        }

                        div("form-group") {
                            a("/room") {
                                button(classes = "form-btn") {
                                    +"Cancel"
                                }
                            }
                            button(type = ButtonType.submit, classes = "form-btn btn-primary") {
                                +"Create"
                            }
                        }
                    }
                }
            }
        }
    }

    post("/room/new") {
        authenticateOrRedirect(Permission.ROOM) { user ->
            val params = call.receiveParameters().toMap().mapValues { (_, list) ->
                list.firstOrNull()
            }

            val name = params["name"] ?: return@post
            val places = (params["places"] ?: return@post).toIntOrNull() ?: 0
            val projector = params["projector"] == "on"
            val internet = params["internet"] == "on"
            val whiteboard = params["whiteboard"] == "on"
            val blackboard = params["blackboard"] == "on"
            val accessible = params["accessible"] == "on"

            val room = Room(null, name, places, projector, internet, whiteboard, blackboard, accessible)

            RoomRepository.create(room)

            call.respondRedirect("/rooms")
        }
    }

    get("/room/{id}/delete") {
        authenticateOrRedirect(Permission.ROOM) { user ->
            val roomId = call.parameters["id"]?.toLongOrNull() ?: return@get

            RoomRepository.delete(roomId)

            call.respondRedirect("/rooms")
        }
    }
}
