// @ts-check

var utils = require("../lib/utils")

;(function () {
    var request = context.request()
    var url = request.query("url")
    var noCache = request.query("noCache")

    var trace_id = context.debug.sentryTraceId()
    function addSentryTrace(content) {
        return content.replace(
            "</head>",
            '<meta name="sentry-trace" content="' + trace_id + '" /></head>'
        )
    }

    context.response.header("sentry-trace", trace_id)

    if (url) {
        var comment = ""

        url = url.split("?")[0]
        comment += "url: " + url

        if (url && url.length > 1) {
            url = url.replace(/\/$/, "")
        }
        if (url == "/noindex" || !url) {
            url = "/" // see .htaccess
        }

        var cache =
            !noCache &&
            context.db.find("ssr", {
                filter: {
                    path: url,
                },
            })

        if (cache && cache.length) {
            // use cache
            throw {
                status: 200,
                html: addSentryTrace(cache[0].content),
            }
        }

        // validate url
        var status = 200

        var pNorender = false
        var pNotfound = false

        var pR = utils.ssrValidatePath(url)
        if (pR < 0) {
            pNotfound = true
        } else if (!pR) {
            pNorender = true
        }

        var head = ""
        var html = ""
        var error = ""

        comment += ", path: " + url

        var cacheIt = false
        if (pNorender) {
            html = "<!-- NO SSR RENDERING -->"
        } else if (pNotfound) {
            status = 404
            html = "404 NOT FOUND"
        } else {
            try {
                // if error, output plain html without prerendering

                // @ts-ignore
                context.ssrCache = {}
                // @ts-ignore
                context.ssrFetch = function (endpoint, options) {
                    var data
                    if (
                        endpoint == "product" ||
                        endpoint == "category" ||
                        endpoint == "country" ||
                        endpoint == "content"
                    ) {
                        var _options = Object.assign({}, options)

                        if (_options.sort) _options.sort = [_options.sort]

                        try {
                            /*console.log(
                                "SSR",
                                endpoint,
                                JSON.stringify(_options)
                            )*/
                            var goSlice = context.db.find(
                                endpoint,
                                _options || {}
                            )
                            // need to deep copy, so shift and delete on pure js is possible
                            data = JSON.parse(JSON.stringify(goSlice))
                        } catch (e) {
                            console.log("ERROR", JSON.stringify(e))
                            data = []
                        }
                    } else {
                        console.log("SSR forbidden", endpoint)
                        data = []
                    }

                    var count = (data && data.length) || 0
                    if (options && count == options.limit) {
                        // read count from db
                        count = context.db.count(endpoint, _options || {})
                    }
                    var r = { data: data, count: count }

                    // @ts-ignore
                    context.ssrCache[
                        utils.obj2str({ endpoint: endpoint, options: options })
                    ] = r

                    return r
                }

                // @ts-ignore
                var app = require("../lib/app.server")

                var rendered = app.default.render({
                    url: url,
                })
                head = rendered.head
                html = rendered.html

                head +=
                    "\n\n" +
                    "<script>window.__SSR_CACHE__ = " +
                    // @ts-ignore
                    JSON.stringify(context.ssrCache) +
                    "</script>"

                // status from webapp
                // @ts-ignore
                if (context.is404) {
                    status = 404
                } else {
                    cacheIt = true
                }
            } catch (e) {
                utils.log(e.message)
                utils.log(e.stack)
                error = "error: " + e.message + "\n\n" + e.stack
            }
        }

        var tpl = context.fs.readFile("templates/spa.html")
        tpl = tpl.replace("<!--HEAD-->", head)
        tpl = tpl.replace("<!--HTML-->", html)
        tpl = tpl.replace(
            "<!--SSR.ERROR-->",
            error ? "<!--" + error + "-->" : ""
        )
        tpl = tpl.replace(
            "<!--SSR.COMMENT-->",
            comment ? "<!--" + comment + "-->" : ""
        )

        if (cacheIt && !noCache) {
            // save cache
            context.db.create("ssr", {
                path: url,
                content: tpl,
            })
        }

        tpl.replace(
            "</head>",
            '<meta name="sentry-trace" content="' + trace_id + '" /></head>'
        )

        throw {
            status: status,
            html: addSentryTrace(tpl),
        }
    } else {
        var auth = context.user.auth()
        if (!auth || auth.role !== 0) {
            // only admins are allowed
            throw {
                status: 403,
                message: "invalid auth",
                auth: auth,
            }
        }
    }
})()

/*
require("../lib/hook.test")
console.log("hook test ende")
throw {
    status: 500,
    msg: "TEST",
}
*/
