package de.kif.backend.route

import de.kif.backend.Configuration
import de.kif.backend.repository.RoomRepository
import de.kif.backend.repository.ScheduleRepository
import de.kif.backend.view.respondMain
import de.kif.common.formatTimeDiff
import de.kif.common.model.Schedule
import io.ktor.routing.Route
import io.ktor.routing.get
import kotlinx.css.CSSBuilder
import kotlinx.css.Color
import kotlinx.html.*
import java.util.*
import kotlin.math.max
import kotlin.math.min

data class BoardSchedule(
    val schedule: Schedule,
    val startTime: Int,
    val endTime: Int
)

suspend fun getUpcoming(limit: Int = 8): List<Schedule> {
    val now =
        ((Date().time + Configuration.Schedule.offset) / (1000 * 60)).toInt() -
                (Configuration.Schedule.referenceDate.time / (1000 * 60))
    return ScheduleRepository.all()
        .map {
            BoardSchedule(
                it,
                it.getAbsoluteStartTime(),
                it.getAbsoluteEndTime()
            )
        }
        .filter { it.endTime > now }
        .partition { it.startTime < now }.let { (running, upcoming) ->
            running.sortedBy { it.endTime } + upcoming.sortedBy { it.startTime }
        }
        .take(limit)
        .map { it.schedule }
}

fun Route.board() {
    get("/brett") {
        val scheduleList = getUpcoming()

        val now = Date()
        val referenceTime = Configuration.Schedule.referenceDate.time
        val timeOffset = Configuration.Schedule.offset

        val refDate = Configuration.Schedule.referenceDate

        val refDay = refDate.time / (1000 * 60 * 60 * 24)
        val todayDay = now.time / (1000 * 60 * 60 * 24)
        val day = (todayDay - refDay).toInt()

        val list = ScheduleRepository.getByDay(day)
        val rooms = RoomRepository.all()
        val schedules = list.groupBy { it.room }.mapValues { (_, it) ->
            it.associateBy {
                it.time
            }
        }

        var max = 0
        var min = 24 * 60
        for (s in list) {
            max = max(max, s.time + s.workGroup.length)
            min = min(min, s.time)
        }

        if (min > max) {
            val h1 = max
            max = min
            min = h1
        }

        if (true) {
            min = min(min, 0)
            max = max(max, 24 * 60)
        }

        min = (min / 60 - 1) * 60
        max = (max / 60 + 2) * 60

        val nowLocale = now.time + timeOffset
        respondMain(true, true) { theme ->
            content {
                div("board") {
                    div("board-header") {
                        div("board-running") {
                            attributes["data-reference"] = referenceTime.toString()

                            for (schedule in scheduleList) {
                                val startTime = ((schedule.getAbsoluteStartTime() * 60 * 1000) + referenceTime)
                                val endTime = ((schedule.getAbsoluteEndTime() * 60 * 1000) + referenceTime)

                                var classes = "board-schedule"
                                if (nowLocale in startTime..endTime) {
                                    classes += " board-schedule-running"
                                }

                                div(classes) {
                                    attributes["data-id"] = schedule.id.toString()

                                    div("board-schedule-color") {
                                        span("bsc") {
                                            attributes["style"] = CSSBuilder().apply {
                                                val c = schedule.workGroup.track?.color
                                                if (c != null) {
                                                    backgroundColor = Color(c.toString())
                                                }
                                            }.toString()
                                        }
                                    }

                                    div("board-schedule-time") {

                                        attributes["data-start-time"] = startTime.toString()
                                        attributes["data-end-time"] = endTime.toString()

                                        if (startTime >= nowLocale) {
                                            +"Start ${formatTimeDiff(startTime, nowLocale)}"
                                        } else {
                                            +"Ende ${formatTimeDiff(endTime, nowLocale)}"
                                        }
                                    }

                                    div("board-schedule-name") {
                                        +schedule.workGroup.name
                                    }

                                    div("board-schedule-room") {
                                        +schedule.room.name
                                    }

                                    div("board-schedule-clock") {
                                        i("material-icons") { +"alarm" }
                                    }
                                }
                            }
                        }
                        div("board-logo") {
                            img("KIF 47.0", "/static/images/logo.svg")
                            div("board-header-date") {
                                attributes["data-now"] = (now.time - timeOffset).toString()
                            }
                        }
                    }
                    div("board-content") {
                        div("board-calendar calendar") {
                            renderCalendar(
                                CalendarOrientation.ROOM_TO_TIME,
                                day,
                                min,
                                max,
                                rooms,
                                schedules
                            )
                        }
                        div("board-twitter") {
                            unsafe {
                                raw(
                                    """
                                <a
                                    class="twitter-timeline"
                                    href="${Configuration.Twitter.timeline}"
                                    data-chrome="transparent noheader nofooter"
                                    data-theme="${if (theme.dark) "dark" else "light"}"
                                    data-link-color="${theme.primaryColor}"
                                    data-cards="hidden"
                                    data-lang="de"
                                    data-dnt="true"
                                >Twitter wall</a>
                                <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
                            """.trimIndent()
                                )
                            }
                        }
                    }
                }
            }
        }
    }
}
