package ru.mipt.spc

import kotlinx.coroutines.runBlocking
import kotlinx.html.*
import space.kscience.dataforge.data.DataTree
import space.kscience.dataforge.data.await
import space.kscience.dataforge.data.getByType
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.getIndexed
import space.kscience.dataforge.meta.string
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.plus
import space.kscience.dataforge.names.withIndex
import space.kscience.snark.*
import java.nio.file.Path
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set


//fun CssBuilder.magProgCss() {
//    rule(".magprog-body") {
//        rule(".magprog-header") {
//            display = Display.flex
//            alignItems = Align.center
//            justifyContent = JustifyContent.center
//            marginTop = 90.pt
//            marginLeft = 40.pt
//        }
//    }
//}

private val HtmlData.imagePath: String? get() = meta["image"]?.string ?: meta["image.path"].string
private val HtmlData.name: String get() = meta["name"].string ?: error("Name not found")

context(PageBuilder) class MagProgSection(
    val id: String,
    val title: String,
    val style: String,
    val content: FlowContent.() -> Unit,
)

context(PageBuilder) private fun wrapSection(
    id: String,
    title: String,
    sectionContent: FlowContent.() -> Unit,
): MagProgSection = MagProgSection(id, title, "wrapper style1 fullscreen fade-up") {
    div("inner") {
        h2 { +title }
        sectionContent()
    }
}

context(PageBuilder) private fun wrapSection(
    block: HtmlData,
    idOverride: String? = null,
): MagProgSection = wrapSection(
    idOverride ?: block.id,
    block.meta["section_title"]?.string ?: error("Section without title"),
) {
    htmlData(block)
}

private val CONTENT_NODE_NAME = Name.EMPTY//"content".asName()
private val INTRO_PATH: Name = CONTENT_NODE_NAME + "intro"
private val ENROLL_PATH: Name = CONTENT_NODE_NAME + "enroll"
private val CONTACTS_PATH: Name = CONTENT_NODE_NAME + "contacts"
private val PROGRAM_PATH: Name = CONTENT_NODE_NAME + "program"
private val RECOMMENDED_COURSES_PATH: Name = CONTENT_NODE_NAME + "recommendedCourses"
private val PARTNERS_PATH: Name = CONTENT_NODE_NAME + "partners"

context(PageBuilder) private fun FlowContent.programSection() {
    val programBlock = data.resolveHtml(PROGRAM_PATH)!!
    val recommendedBlock = data.resolveHtml(RECOMMENDED_COURSES_PATH)!!
    div("inner") {
        h2 { +"Учебная программа" }
        htmlData(programBlock)
        button(classes = "fit collapsible") {
            attributes["data-target"] = "recommended-courses-content"
            +"Рекомендованные курсы"
        }
        div(classes = "collapsible-content") {
            id = "recommended-courses-content"
            htmlData(recommendedBlock)
        }
    }
}

context(PageBuilder) private fun FlowContent.partners() {
    //val partnersData: Meta = resolve<Any>(PARTNERS_PATH)?.meta ?: Meta.EMPTY
    val partnersData: Meta = runBlocking { data.getByType<Meta>(PARTNERS_PATH)?.await() } ?: Meta.EMPTY
    div("inner") {
        h2 { +"Партнеры" }
        div("features") {
            partnersData.getIndexed("content".asName()).values.forEach { partner ->
                section {
                    a(href = partner["link"].string, target = "_blank") {
                        rel = "noreferrer"
                        val imagePath = partner["logo"].string?.let { resolveRef(it) }
                        img(
                            classes = "icon major",
                            src = imagePath,
                            alt = imagePath
                        ) {
                            h3 { +(partner["title"].string ?: "") }
                        }
                    }
                }
            }
        }
    }
}

//class Person(val data: HtmlData) : HtmlData by data {
//    val name: String by meta.string { error("Mentor name is not defined") }
//    val photo: String? by meta.string()
//}

context(PageBuilder) private fun FlowContent.team() {
    val team = data.findByContentType("magprog_team").values.sortedBy { it.order }

    div("inner") {
        h2 { +"Команда" }
        div("features") {
            team.forEach { member ->
                section {
                    a {
                        val imagePath = member.imagePath?.let { resolveRef(it) }
                        img(
                            classes = "icon major",
                            src = imagePath,
                            alt = imagePath
                        ) {
                            h3 { +member.name }
                            htmlData(member)
                        }
                    }
                }
            }
        }
    }

//    div("inner") {
//        h2 {
//            +"Команда"
//        }
//    }
//    team.forEach { member ->
//        section {
//            id = member.id
//            a(classes = "image") {
//                member.photo?.let { photoPath ->
//                    img(
//                        src = resolveRef(photoPath),
//                        alt = member.name
//                    ) {
//                        attributes["data-position"] = "center center"
//                    }
//                }
//            }
//
//            div("content") {
//                div("inner") {
//                    h3 {
//                        a(href = "#team_${member.id}") { +member.name }
//                    }
//                    htmlData(member)
//                }
//            }
//        }
//    }
}

context(PageBuilder) private fun FlowContent.mentors() {
    val mentors = data.findByContentType("magprog_mentor").entries.sortedBy { it.value.id }

    div("inner") {
        h2 {
            +"Научные руководители"
        }
    }
    mentors.forEach { (name, mentor) ->
        section {
            id = mentor.id
            val ref = resolvePageRef("mentor-${mentor.id}")
            a(classes = "image", href = ref) {
                mentor.imagePath?.let { photoPath ->
                    img(
                        src = resolveRef(photoPath),
                        alt = mentor.name
                    ) {
                        attributes["data-position"] = "center center"
                    }
                }
            }

            div("content") {
                div("inner") {
                    h2 {
                        a(href = ref) { +mentor.name }
                    }
                    val info = data.resolveHtml(name.withIndex("info"))
                    if (info != null) {
                        htmlData(info)
                    }
                }
            }
        }
    }
}

context(PageBuilder) internal fun HTML.magProgHead(title: String) {
    head {
        this.title = title
        meta {
            charset = "utf-8"
        }
        meta {
            name = "viewport"
            content = "width=device-width, initial-scale=1, user-scalable=no"
        }
        link {
            rel = "stylesheet"
            href = resolveRef("assets/css/main.css")
        }
        link {
            rel = "shortcut icon"
            href = resolveRef("images/favicon-32x32.png")
        }
        noScript {
            link {
                rel = "stylesheet"
                href = resolveRef("assets/css/noscript.css")
            }
        }
    }
}

context(PageBuilder) internal fun BODY.magProgFooter() {
    footer("wrapper style1-alt") {
        id = "footer"
        div("inner") {
            ul("menu") {
                li { +"""SPC. All rights reserved.""" }
                li {
                    +"""Design:"""
                    a {
                        href = "http://html5up.net"
                        +"""HTML5 UP"""
                    }
                }
            }
        }
    }
    script {
        src = resolveRef("assets/js/jquery.min.js")
    }
    script {
        src = resolveRef("assets/js/jquery.scrollex.min.js")
    }
    script {
        src = resolveRef("assets/js/jquery.scrolly.min.js")
    }
    script {
        src = resolveRef("assets/js/browser.min.js")
    }
    script {
        src = resolveRef("assets/js/breakpoints.min.js")
    }
    script {
        src = resolveRef("assets/js/util.js")
    }
    script {
        src = resolveRef("assets/js/main.js")
    }
}

private val HtmlData.mentorPageId get() = "mentor-${id}"

internal fun SiteBuilder.spcMaster(dataPath: Path, prefix: Name = "magprog".asName()) {

    val magProgData: DataTree<Any> = snark.readDirectory(dataPath.resolve("content"))

    route(prefix, magProgData, setAsRoot = true) {
        assetDirectory("assets", dataPath.resolve("assets"))
        assetDirectory("images", dataPath.resolve("images"))

        page {
            val sections = listOf<MagProgSection>(
                wrapSection(data.resolveHtml(INTRO_PATH)!!, "intro"),
                MagProgSection(
                    id = "partners",
                    title = "Партнеры",
                    style = "wrapper style3 fullscreen fade-up"
                ) {
                    partners()
                },
                // section(props.data.partners),
                MagProgSection(
                    id = "mentors",
                    title = "Научные руководители",
                    style = "wrapper style2 spotlights",
                ) {
                    mentors()
                },
                MagProgSection(
                    id = "program",
                    title = "Учебная программа",
                    style = "wrapper style3 fullscreen fade-up"
                ) {
                    programSection()
                },
                wrapSection(data.resolveHtml(ENROLL_PATH)!!, "enroll"),
                wrapSection(id = "contacts", title = "Контакты") {
                    htmlData(data.resolveHtml(CONTACTS_PATH)!!)
                    team()
                }
            )

            magProgHead("Магистратура \"Научное программирование\"")
            body("is-preload magprog-body") {
                section {
                    id = "sidebar"
                    div("inner") {
                        nav {
                            ul {
                                li {
                                    a(classes = "spc-home", href = "/") {
                                        i("fa fa-home") {
                                            attributes["aria-hidden"] = "true"
                                        }
                                        +"SPC"
                                    }
                                }
                                sections.forEach { section ->
                                    li {
                                        a(href = "#${section.id}") {
                                            +section.title
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                div {
                    id = "wrapper"
                    sections.forEach { sec ->
                        section(sec.style) {
                            id = sec.id
                            with(sec) { content() }
                        }
                    }
                }
                magProgFooter()
            }
        }


        val mentors = data.findByContentType("magprog_mentor").values.sortedBy {
            it.order
        }

        mentors.forEach { mentor ->
            page(mentor.mentorPageId.asName()) {

                magProgHead("Научное программирование: ${mentor.name}")
                body("is-preload") {
                    header {
                        id = "header"
                        a(classes = "title") {
                            href = "$homeRef#mentors"
                            +"Научные руководители"
                        }
                        nav {
                            ul {
                                mentors.forEach {
                                    li {
                                        a {
                                            href = resolvePageRef(it.mentorPageId)
                                            +it.name.substringAfterLast(" ")
                                        }
                                    }
                                }
                            }
                        }
                    }
                    div {
                        id = "wrapper"
                        section("wrapper") {
                            id = "main"
                            div("inner") {
                                h1("major") { +mentor.name }
                                val imageClass = mentor.meta["image.position"].string ?: "left"
                                span("image $imageClass") {
                                    mentor.imagePath?.let { photoPath ->
                                        img(
                                            src = resolveRef(photoPath),
                                            alt = mentor.name
                                        )
                                    }
                                }
                                htmlData(mentor)
                            }
                        }
                    }
                    magProgFooter()
                }
            }
        }
    }
}