////
// The scrollback shows your history of interacting with the shell.
// input, output, etc

import { scrollback, $$ } from "./dom.js"
import { randomId } from "../shared/utils.js"
import type { CommandOutput } from "../shared/types.js"

type InputStatus = "waiting" | "streaming" | "ok" | "error"

export function autoScroll() {
    // requestAnimationFrame(() => scrollback.scrollTop = scrollback.scrollHeight - scrollback.clientHeight)
    // scrollback.scrollTop = scrollback.scrollHeight - scrollback.clientHeight
}

export function insert(node: HTMLElement) {
    scrollback.append(node)
}

export function addInput(id: string, input: string) {
    const parent = $$("li.input")
    const status = $$("span.status.yellow", "•")
    const content = $$("span.content", input)
    parent.append(status, content)
    parent.dataset.id = id

    insert(parent)
    scrollback.scrollTop = scrollback.scrollHeight - scrollback.clientHeight
}

export function setStatus(id: string, status: InputStatus) {
    const statusEl = document.querySelector(`[data-id="${id}"].input .status`)
    if (!statusEl) return

    statusEl.className = ""

    switch (status) {
        case "waiting":
            statusEl.classList.add("yellow")
            break
        case "streaming":
            statusEl.classList.add("purple")
            break
        case "ok":
            statusEl.classList.add("green")
            break
        case "error":
            statusEl.classList.add("red")
            break
    }
}

export function addOutput(id: string, output: CommandOutput) {
    const item = $$("li")
    item.classList.add("output")
    item.dataset.id = id || randomId()

    const [format, content] = processOutput(output)

    if (format === "html")
        item.innerHTML = content
    else
        item.textContent = content

    const input = document.querySelector(`[data-id="${id}"].input`)
    if (input instanceof HTMLLIElement)
        input.parentNode!.insertBefore(item, input.nextSibling)
    else
        insert(item)

    autoScroll()
}

export function addErrorMessage(message: string) {
    addOutput("", { html: `<span class="red">${message}</span>` })
}


export function appendOutput(id: string, output: CommandOutput) {
    const item = document.querySelector(`[data-id="${id}"].output`)

    if (!item) {
        console.error(`output id ${id} not found`)
        return
    }

    const [format, content] = processOutput(output)

    if (format === "html")
        item.innerHTML += content
    else
        item.textContent += content

    autoScroll()
}

export function replaceOutput(id: string, output: CommandOutput) {
    const item = document.querySelector(`[data-id="${id}"].output`)

    if (!item) {
        console.error(`output id ${id} not found`)
        return
    }

    const [format, content] = processOutput(output)

    if (format === "html")
        item.innerHTML = content
    else
        item.textContent = content

    autoScroll()
}

function processOutput(output: CommandOutput): ["html" | "text", string] {
    let content = ""
    let html = false

    if (typeof output === "string") {
        content = output
    } else if (Array.isArray(output)) {
        content = output.join(" ")
    } else if ("html" in output) {
        html = true
        content = output.html
        if (output.script) eval(output.script)
    } else if ("text" in output) {
        content = output.text
        if (output.script) eval(output.script)
    } else if ("script" in output) {
        eval(output.script!)
    } else {
        content = JSON.stringify(output)
    }

    return [html ? "html" : "text", content]
}
