/**
 * Creates a div
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_div(className, ...content) {
    const item = document.createElement("div")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Creates a paragraph
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_p(className, ...content) {
    const item = document.createElement("p")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Creates a h1
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_h1(className, ...content) {
    const item = document.createElement("h1")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Creates a h2
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_h2(className, ...content) {
    const item = document.createElement("h2")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Creates a h3
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_h3(className, ...content) {
    const item = document.createElement("h3")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Creates a h4
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_h4(className, ...content) {
    const item = document.createElement("h4")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Creates a h5
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_h5(className, ...content) {
    const item = document.createElement("h5")
    if (className) { item.className = className }
    item.append(...content)
    return item
}

/**
 * Creates a button
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_button(className, ...content) {
    const item = document.createElement("button")
    if (className) { item.className = className }
    item.append(...content)
    return item
}

/**
 * Creates a img
 * @param {string} className the class string for the element
 * @param {string} src the url for the image
 * @param {string} alt alternate text if the image does not load
 */
function ui_img(className, src, alt = "") {
    const item = document.createElement("img")
    if (className) { item.className = className }
    item.src = src
    item.alt = alt
    return item
}

/**
 * Creates a span
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */

function ui_span(className, ...content) {
    const item = document.createElement("span")
    if (className) { item.className = className }
    item.append(...content)
    return item
}

/**
 * Creates a form
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_form(className, ...content) {
    const item = document.createElement("form")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Creates a lable
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_label(className, ...content) {
    const item = document.createElement("label")
    if (className) { item.className = className }
    item.append(...content)
    return item
}

/**
 * Creates a input
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_input(className, ...content) {
    const item = document.createElement("input")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Marks the the input as requried
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 * @returns 
 */
function ui_input_password(className, ...content) {
    const item = ui_input(className, ...content)
    item.required = true
    item.type = "password"
    return item
}


/**
 * Marks the the input as requried and adds a reveal pw button
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 * @returns 
 */
function ui_input_password_reveal(className, ...content) {
    const pw = ui_input_password("", ...content)
    pw.style.width = "100%"
    const span = ui_span("material-symbols-outlined button inline-icon", "visibility")
    span.title = "Show Password"
    span.onclick = (e) => {
        const input = e.target.parentNode.parentNode.firstElementChild.firstElementChild
        if (input.type === "password") {
            input.type = "text"
            e.target.innerHTML = "visibility_off"
            e.target.title = "Hide Password"
        } else {
            input.type = "password"
            e.target.innerHTML = "visibility"
            e.target.title = "Show Password"
        }
        console.log(input.type)

    }
    const table = document.createElement("table")
    const tr = document.createElement("tr")
    let td = document.createElement("td")
    td.style.width = "100%"
    td.appendChild(pw)
    td.style.paddingRight = "10px"
    tr.appendChild(td)
    td = document.createElement("td")
    td.appendChild(span)
    tr.appendChild(td)
    table.appendChild(tr)
    const div = ui_div(className, table)

    //div.style.backgroundColor="red"
    return div
}



/**
 * Marks the the input as requried
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 * @returns 
 */
function ui_input_email(className, ...content) {
    const item = ui_input(className, ...content)
    item.required = true
    item.type = "email"
    return item
}

/**
 * Creates a br
 */
function ui_br() {
    const item = document.createElement("br")
    return item
}

/**
 * Creates an ordered list
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_ol(className, ...content) {
    const item = document.createElement("ol")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Creates an unordered list
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_ul(className, ...content) {
    const item = document.createElement("ul")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Creates a list item
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */

function ui_li(className, ...content) {
    const item = document.createElement("li")
    if (className) { item.className = className }
    item.append(...content)
    return item
}
/**
 * Creates a anchor (link)
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_a(className, href, ...content) {
    const item = document.createElement("a")
    if (className) { item.className = className }
    item.append(...content)
    item.href = href
    return item
}

// ----------- AUTH FORMS -------------
function ui_sign_in_form(resolve = () => { }, reject = () => { }) {
    const form = ui_form("auth-container ui-inline-block")
    const email_input = ui_input_email("ui-input ui-full-width mb2")
    const password_input = ui_input_password("ui-input ui-full-width")
    const submit = ui_btn("Sign In")
    const error_message = ui_div("ui-bg-clear error-message ")
    submit.classList.add("mt3")
    submit.onclick = (e) => {
        e.preventDefault()
        submit.replaceChildren(ui_loading())
        submit.disabled = true
        error_message.replaceChildren()

        firebase.auth.signInWithEmailAndPassword(firebase.auth.getAuth(), email_input.value, password_input.value)
            .then((userCredential) => {
                submit.replaceChildren("Sign In")
                submit.disabled = false
                resolve(userCredential)
            })
            .catch((error) => {
                error_message.replaceChildren(error.code)
                submit.replaceChildren("Sign In")
                submit.disabled = false
                reject(error)
            });
    }
    form.append(
        ui_h2("center", "Sign In"), 
        ui_label("", "Email"), ui_br(), email_input, ui_br(),
        ui_label("", "Password"), ui_br(), password_input, ui_br(),
        submit,
        error_message,
    )
    return form
}

function ui_sign_up_form(resolve = () => { }, reject = () => { }) {
    const form = ui_form("auth-container ui-inline-block")
    const email = ui_input_email("ui-input ui-full-width mb2")
    const password_1 = ui_input_password("ui-input ui-full-width")
    const password_2 = ui_input_password("ui-input ui-full-width")
    const error_message = ui_div("error-message ui-bg-clear")
    const submit = ui_btn("Sign Up")
    submit.classList.add("mt3")
    submit.onclick = (e) => {
        e.preventDefault()
        error_message.replaceChildren()
        if (password_1.value !== password_2.value) {
            error_message.replaceChildren("Passowrds do not match")
            form.append(error_message)
            return
        }
        // only do this if we pass the validation
        submit.replaceChildren(ui_loading())
        submit.disabled = true
        firebase.auth.createUserWithEmailAndPassword(firebase.auth.getAuth(), email.value, password_1.value)
            .then((userCredential) => {
                submit.replaceChildren("Sign Up")
                submit.disabled = false
                resolve(userCredential)
            })
            .catch((error) => {
                error_message.replaceChildren(error.code)
                submit.replaceChildren("Sign Up")
                submit.disabled = false
                reject(error)
            })
    }
    form.append(
        ui_h2("center", "Sign Up"),
        ui_label("", "Email"), ui_br(), email, ui_br(),
        ui_label("", "Password"), ui_br(), password_1, ui_br(),
        ui_label("", "Verify Password"), ui_br(), password_2, ui_br(),
        submit,
        error_message,
    )
    return form
}

function ui_auth_form(resolve = () => { }, reject = () => { }) {
    let showSignIn = true
    const container = ui_div("center")
    const error_message = ui_div("error-message ui-bg-clear")
    const signInWithGoogle = ui_div("ui-google-sign-in-buttton",
        ui_span("ui-icon",),
        ui_span("ui-button-text", "GOOGLE")
    )
    signInWithGoogle.onclick = () => {
        const auth = firebase.auth.getAuth();
        const provider = new firebase.auth.GoogleAuthProvider();
        firebase.auth.signInWithPopup(auth, provider)
            .then(userCredential => {
                resolve(userCredential)
            })
            .catch(err => {
                console.error("error", err)
                reject(userCredential)
                error_message.replaceChildren(err.code)
            });
    }
    const signInButton = ui_button("ui-button-link", "Have an account? Sign in")
    signInButton.onclick = () => {
        showSignIn = true
        renderContainer()
    }
    const signUpButton = ui_button("ui-button-link", "Don't have an account? Sign up")
    signUpButton.onclick = () => {
        showSignIn = false
        renderContainer()
    }

    const renderContainer = () => {
        container.replaceChildren(
            (showSignIn ? ui_sign_in_form(resolve, reject) : ui_sign_up_form(resolve, reject)),
            ui_br(),
            ui_div("auth-container ui-inline-block",
                ui_div("center my3 ui-card-subtitle", "Or Sign In With"),
                ui_div("center",
                    signInWithGoogle,
                ),
                error_message,
            ),
            ui_div("my3"),
            (showSignIn ? signUpButton : signInButton),
        )
        return container
    }
    return renderContainer()
}


// ---------- END AUTH FORMS ----------

function ui_loading() {
    return ui_span("material-symbols-outlined spin", "sync")
}

/**
 * Creates a div as a flex container. uses the `ui-flex` and `ui-flex-wrap` classes
 * @param {string} className the class string for the element
 * @param {string|HTMLElement} content items that get appended to this element as children
 */
function ui_flex(className, ...content) {
    const flex_container = ui_div(`ui-flex ui-flex-wrap ${className}`, ...content)
    return flex_container
}

/**
 * creates a basic card
 * @param head_content content in the head
 * @param body_content content in the body
 */
function ui_card(head_content, ...body_content) {
    const card = document.createElement("div")
    card.className = "card"

    if (head_content) {
        const card_head = document.createElement("div")
        card_head.className = "card-head"
        card_head.append(head_content)
        card.append(card_head)
    }

    const card_body = document.createElement("div")
    card_body.className = "card-body max-height-300"
    card_body.append(...body_content);
    card.append(card_body)

    return card
}

/**
 * the head for a card
 * @param {string} title title of the card head
 * @param {string} subtitle a subtitle, which is smaller font size than the title
 * @returns 
 */
function ui_card_head(title, subtitle) {
    const card_head = ui_div()
    card_head.append(
        ui_div("ui-card-title", title),
        ui_div("ui-card-subtitle", subtitle)
    )
    return card_head
}

/**
 * 
 * @param {string|Node} content the content for this ui element
 */
function ui_card_body_item(...content) {
    const item = document.createElement("div")
    item.className = "card-body-item"
    item.append(...content)
    return item
}

function ui_header(...content) {
    const item = document.createElement("p")
    item.className = "header-text clickable"
    item.append(...content)
    return item
}
function ui_content(...content) {
    const item = document.createElement("p")
    item.className = "content-text"
    item.append(...content)
    return item
}

function ui_grid(...content) {
    return ui_div("ui-grid-container ui-grid-columns-2", ...content)
}

function ui_grid_item(...content) {
    return ui_div("ui-grid-item", ...content)
}

function ui_inline_block(...content) {
    return ui_div("ui-inline-block", ...content)
}

/**
 * stylized button (primary)
 * @param {string} btn_text text inside the button
 * @returns 
 */
function ui_btn(btn_text) {
    return ui_button("ui-button primary ui-full-width", btn_text)
}
/**
 * stylized button (error)
 * @param {string} btn_text text inside the button
 * @returns 
 */
function ui_btn_error(btn_text) {
    return ui_button("ui-button error ui-full-width", btn_text)
}
/**
 * stylized button (info)
 * @param {string} btn_text text inside the button
 * @returns 
 */
function ui_btn_info(btn_text) {
    return ui_button("ui-button info ui-full-width", btn_text)
}

/**
 * returns a string with the first value in uppercase
 * @param string 
 * @returns 
 */
function ui_first_letter_upper_case(string) {
    return string[0].toUpperCase() + string.slice(1);
}

/**
 * Creates a modal window, including the overlay
 * @param title    Text to show in the title bar
 * @param body     a div element that containt the body
 * @param resolve  the function to call when clicking the close x
 */
function ui_modal(title, body, resolve) {
    const modal = ui_div("modal modal-content p3 auth-container-in-modal", body)
    const table = document.createElement("table")
    const tr = document.createElement("tr")
    let td = document.createElement("td")
    td.style.width = "100%"
    td.innerHTML = title
    tr.appendChild(td)
    td = document.createElement("td")
    let span = document.createElement("span")
    span.classList.add("material-symbols-outlined")
    span.classList.add("button")
    span.classList.add("inline-icon")
    span.onclick = (event) => {
        let elem = event.target
        while (elem.className !== 'overlay') {
            elem = elem.parentNode
        }
        elem.remove()
        resolve(null)
    }
    span.innerHTML = "close"
    td.appendChild(span)
    tr.appendChild(td)

    table.appendChild(tr)

    table.style.width = "100%"
    const title_bar = ui_div("modal-title", table)

    const overlay = ui_div("overlay")
    overlay.id = "overlay"
    overlay.append(ui_div("modal-page", ui_div("modal", title_bar, modal)))

    return overlay
}


// grading card
function ui_feedback_pane(title, message, isError = false) {
    return ui_div("feedback-pane",
        ui_div(`feedback-header${isError ? "-error" : ""}`, title),
        ui_div("feedback-body", message)
    )
}

async function ui_message_box(message, title = "System Message", buttons = ["OK", "Cancel"]) {
    // an awaitable dialog box
    const value = await new Promise(
        (resolve, reject) => {
            document.body.append(ui_modal(title, ui_message_box_form(message, buttons, resolve), resolve))
        }
    )
    return value

    // currently only used here, but could be used elsewhere.  then we will move it out of this fn
    function ui_message_box_form(message, button_labels, resolve = () => { }, reject = () => { }) {
        const form = ui_form("auth-container ui-inline-block")
        const buttons = []
        for (const label of button_labels) {
            const btn = ui_btn(label)
            btn.classList.add("mt3")
            btn.onclick = (e) => {
                e.preventDefault()
                tag("overlay").remove()
                resolve(label)
            }
            buttons.push(btn)
        }

        form.append(
            ui_p("", message),
            ...buttons
        )
        return form
    }

}


async function ui_input_box(message, title = "Enter Data", default_value = "", placeholder = "", buttons = ["OK", "Cancel"]) {
    // an awaitable dialog box
    const value = await new Promise(
        (resolve, reject) => {
            document.body.append(ui_modal(title, ui_message_box_form(message, default_value, placeholder, buttons, resolve), resolve))
            tag("input-box-input").focus()
        }
    )
    return value

    // currently only used here, but could be used elsewhere.  then we will move it out of this fn
    function ui_message_box_form(message, default_value, placeholder, button_labels, resolve = () => { }, reject = () => { }) {
        const form = ui_form("auth-container ui-inline-block")
        const buttons = []
        for (const label of button_labels) {
            const btn = ui_btn(label)
            btn.classList.add("mt3")
            btn.onclick = (e) => {
                e.preventDefault()
                tag("overlay").remove()
                if (label === button_labels[0]) {
                    resolve(e.target.parentNode.querySelector(".ui-input").value)
                } else (
                    resolve(undefined)
                )

            }
            buttons.push(btn)
        }
        const input=ui_input("ui-input ui-full-width")
        input.id="input-box-input"
        if(default_value){input.value=default_value}
        if(placeholder){input.placeholder=placeholder}
        const body=ui_div("")
        body.innerHTML=message
        form.append(
            body,
            input,
            ...buttons
        )
        return form
    }

}




/**
 * Creates a div with class name "message". 
 * Used for putting up those handy message cards on the top right side of the screen.
 * @param {string | HTMLElement} elements 
 * @returns 
 */
function ui_message(...elements) {
    return ui_div("message", ...elements)
}

/**
 * Creates a message card similar to message() func in system.js but better thanks to ui_ framework
 * @param {"error" | "info" | ""} message_type  empty string means success
 * @param {string} message_title 
 * @param {string | HTMLElement} message_body 
 * @param {number} ttl_in_seconds zero (0) means do not automatically remove
 * @returns 
 */
function ui_message_card(message_type, message_title, message_body, ttl_in_seconds = 0) {
    const close_span = ui_span("material-symbols-outlined button", "close")
    close_span.onclick = () => close_message(close_span)

    const the_title = (message_title
        ? ui_div(`msg-head ${message_type}`,
            message_title,
            ui_div("msg-ctrl",
                close_span
            )
        )
        : ""
    )



    const msg = ui_div("message",
        the_title,
        ui_div("msg-body",
            message_body
        )
    )


    if (ttl_in_seconds > 0) {
        wait(ttl_in_seconds).then(() => msg.remove())
    }
    return msg
}

/**
 * Creates a UI message and waits for the given
 * promise to complete before removing the UI message
 * @param {Promise} promise 
 * @param {HTMLElement} success 
 * @param {HTMLElement} error 
 */
async function ui_server_heart_beat(promise, success, err_content) {
    const content = ui_message(
        ui_div("center",
            ui_message_card("", "", ui_loading(""))
        ),
    )
    tag("message-center").appendChild(content) // display the content on the screen
    try {
        await promise
        content.replaceChildren(success)
    } catch (e) {
        console.error(e)
        content.replaceChildren(err_content)
    }
    await wait(4)
    content.remove()
}

function ui_test() {
    ui_server_heart_beat(
        wait(5),
        ui_message_card("", "Saved", "successfullyt saved yoiur data"),
        ui_message_card("error", "Could not save", "Unable to save your data to the cloud. Don't worry, your data is cached to this machine. Check your internet connection and try again.")
    )
}
//ui_span("material-symbols-outlined","check_circle")