package alraune

import alraune.entity.*
import pieces100.*
import routine.sendJson
import java.util.*
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

class UserSearchWebApi(val req: HttpServletRequest, val resp: HttpServletResponse) {
    companion object {
        val path = "/api-search-users"
        val pageSize = AlConst.pageSize
    }

    class Response(val totalCount: Long, val items: List<Item>)
    class Item(val id: Long, val text: String)

    enum class Simulate {Nothing, NotSignedIn, LowLevelFuckup, RandomFuckYou}

    val simulate = Simulate.Nothing

    fun user() =
        if (simulate == Simulate.NotSignedIn) null
        else rctx0.al.maybeUser()

    fun fart() {
        class UserFacingError(message: String) : Exception(message)
        try {
            val user = user() ?: throw UserFacingError(t("TOTE", "Залогинься сперва"))
            if (user.kind != AlUserKind.Admin) throw UserFacingError(t("TOTE", "Тебе это, дружок, не положено"))
            if (simulate == Simulate.LowLevelFuckup) throw Exception("Testing low-level fuckup")
            if (simulate == Simulate.RandomFuckYou && Random().nextInt(2) == 1) throw UserFacingError("Fuck you, dear user")

            val params = GetParams()
            val q = params.q.let {
                it.get() ?: throw UserFacingError(t("TOTE", "Я хочу `${it.name}`"))
            }

            val m = User.Meta
            val boobs = PaginationBoobs(UsualPaginationPussy(
                itemClass = User::class, table = m.table, pageSize = pageSize,
                shitIntoWhere = {
                    it.text("and (")
                    it.text("        ${m.email} ilike", "$q%")
                    it.text("     or ${m.firstNameForSearch} ilike", "$q%")
                    it.text("     or ${m.lastNameForSearch} ilike", "$q%")
                    it.text(")")
                    it.text("and ${m.kind} =", AlUserKind.Writer)
                    it.text("and ${m.profileState} =", User.ProfileState.Approved)
                },
                shitOrderBy = {shitOrderById(it, params.ordering.get()!!)}
            ))
            boobs.fart()
            sendJson(resp, Response(totalCount = boobs.count, items = boobs.items.map {
                Item(id = it.id, text = it.textForUserPickerEtc())
            }))
        } catch (e: UserFacingError) {
            sendJson(resp, object {val error = e.message})
        }
    }
}













