class QuickTalk {
    constructor(opt) {
        this.options = opt;
        if (typeof this.options.target === "string") {
            this.options.target = document.getElementById(this.options.target);
        }
        if (typeof this.options.page && typeof this.options.page === "string") {
            this.options.page = document.getElementById(this.options.page);
        }
        this.preview_on = false;
        this.instant_compose = undefined;
        let editor = document.createElement("div");
        let compose_button = document.createElement("button");
        compose_button.setAttribute("class", "quick-talk-compose-button");
        compose_button.textContent = "Write a comment";
        this.options.target.appendChild(compose_button);
        this.options.target.appendChild(editor);
        let container = this.load_thread(this.options.target);
        compose_button.addEventListener("click", (event) => {
            if (this.instant_compose) {
                this.instant_compose.parentNode.removeChild(this.instant_compose);
            }
            this.instant_compose = this.compose(editor, 0, true, (data) => {
                this.show_comment(container, data, true).scrollIntoView();
            });
        });
    }
    request(uri, data, callback) {
        let xhttp = new XMLHttpRequest();
        xhttp.open("POST", uri, true);
        xhttp.setRequestHeader("Content-type", "application/json");
        xhttp.onreadystatechange = () => {
            if (xhttp.readyState == 4) {
                if (xhttp.status == 200) {
                    if (callback) {
                        callback(JSON.parse(xhttp.responseText));
                    }
                }
                else {
                    this.error(xhttp.statusText);
                }
            }
        };
        if (data) {
            xhttp.send(JSON.stringify(data));
        }
        else {
            xhttp.send();
        }
    }
    set_status(type, msg) {
        if (this.status_el) {
            this.status_el.innerHTML = type + ": " + msg;
        }
        else {
            console.log(type + ": " + msg);
        }
    }
    clear_status() {
        this.status_el.innerHTML = "";
    }
    info(msg) {
        this.set_status("INFO", msg);
    }
    error(obj) {
        console.log(obj);
        this.set_status("ERROR", obj.toString());
    }
    compose(at, cid, auto_hide, callback) {
        let preview = document.createElement("div");
        preview.setAttribute("class", "quick-talk-preview");
        preview.style.display = "none";
        let container = document.createElement("div");
        container.setAttribute("class", "quick-talk-compose");
        let name = document.createElement("input");
        name.value = "Name";
        name.addEventListener("focus", (event) => {
            if (name.value == "Name") {
                name.value = "";
            }
        });
        name.addEventListener("blur", (event) => {
            if (name.value.trim() == "") {
                name.value = "Name";
            }
        });
        let email = document.createElement("input");
        email.value = "Email";
        email.addEventListener("focus", (event) => {
            if (email.value == "Email") {
                email.value = "";
            }
        });
        email.addEventListener("blur", (event) => {
            if (email.value.trim() == "") {
                email.value = "Email";
            }
        });
        let ta = document.createElement("textarea");
        ta.onkeydown = (e) => {
            if (e.keyCode === 9) {
                // tab was pressed
                // get caret position/selection
                var val = ta.value, start = ta.selectionStart, end = ta.selectionEnd;
                // set textarea value to: text before caret + tab + text after caret
                ta.value =
                    val.substring(0, start) + "    " + val.substring(end);
                // put caret at right position again
                ta.selectionStart = ta.selectionEnd = start + 4;
                // prevent the focus lose
                return false;
            }
        };
        let footer = document.createElement("div");
        footer.setAttribute("class", "quick-talk-compose-footer");
        this.status_el = document.createElement("div");
        let bt_preview = document.createElement("button");
        bt_preview.textContent = "Preview";
        bt_preview.addEventListener("click", (event) => {
            let md = { data: ta.value };
            if (!this.preview_on && ta.value.trim() != "") {
                this.request(this.options.api_uri + "/preview", md, (ret) => {
                    if (ret.result) {
                        ta.style.display = "none";
                        preview.innerHTML = ret.result;
                        preview.style.display = "block";
                        bt_preview.textContent = "Edit";
                        this.preview_on = !this.preview_on;
                    }
                    else {
                        this.error(ret.error);
                    }
                });
            }
            else {
                ta.style.display = "block";
                preview.style.display = "none";
                bt_preview.textContent = "Preview";
                this.preview_on = !this.preview_on;
            }
        });
        let bt_submit = document.createElement("button");
        bt_submit.textContent = "Send";
        bt_submit.addEventListener("click", (event) => {
            this.clear_status();
            if (name.value.trim() == "" ||
                name.value.trim() == "Name" ||
                email.value.trim() == "" ||
                email.value.trim() == "Email" ||
                ta.value.trim() == "") {
                this.info("Please enter all the fields");
                return;
            }
            // check for email
            let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
            if (!re.test(String(email.value).toLowerCase()))
                return this.info("Email is not correct");
            // send the post request
            let data = {
                page: {
                    uri: this.options.uri,
                },
                comment: {
                    name: name.value,
                    email: email.value,
                    rid: cid,
                    content: ta.value,
                },
            };
            if (this.options.author) {
                data.author =
                    this.options.author.first + "@" + this.options.author.last;
            }
            this.request(this.options.api_uri + "/post", data, (ret) => {
                if (ret.result) {
                    // TODO: more check goes here
                    name.value = "Name";
                    email.value = "Email";
                    ta.value = "";
                    if (auto_hide) {
                        at.removeChild(container);
                        this.instant_compose = undefined;
                    }
                    if (callback) {
                        callback(ret.result);
                    }
                }
                else {
                    this.error(ret.error);
                }
            });
        });
        footer.appendChild(this.status_el);
        footer.appendChild(bt_preview);
        footer.appendChild(bt_submit);
        container.appendChild(name);
        container.appendChild(email);
        container.appendChild(ta);
        container.appendChild(preview);
        container.appendChild(footer);
        at.appendChild(container);
        if (this.options.page) {
            this.options.page.scrollTop = container.offsetTop - this.options.page.offsetTop;
        }
        
        //container.scrollIntoView();
        return container;
    }
    load_thread(at) {
        let container = document.createElement("div");
        container.setAttribute("class", "quick-talk-comment-thread");
        at.appendChild(container);
        this.request(this.options.api_uri, { page: this.options.uri }, (ret) => {
            if (ret.result) {
                ret.result.forEach((comment) => {
                    this.show_comment(container, comment, true);
                });
            }
            else {
                this.error(ret.error);
            }
            if (this.options.onload) {
                this.options.onload();
            }
        });
        return container;
    }
    show_comment(at, comment, show_footer) {
        let container = document.createElement("div");
        container.setAttribute("class", "quick-talk-comment");
        let header = document.createElement("div");
        header.setAttribute("class", "quick-talk-comment-header");
        let username = document.createElement("span");
        username.setAttribute("class", "quick-talk-comment-user");
        let time = document.createElement("span");
        time.setAttribute("class", "quick-talk-comment-time");
        let content = document.createElement("div");
        content.setAttribute("class", "quick-talk-comment-content");
        username.innerHTML = comment.name;
        let date = new Date(parseInt(comment.time) * 1000);
        time.innerHTML = `on ${date.getDate()}/${date.getMonth()}/${date.getFullYear()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}, wrote:`;
        content.innerHTML = comment.content;
        header.appendChild(username);
        header.appendChild(time);
        container.appendChild(header);
        container.appendChild(content);
        let sub_comments = document.createElement("div");
        sub_comments.setAttribute("class", "quick-talk-sub-comment");
        if (comment.children && comment.children.length > 0) {
            comment.children.forEach((cmt) => {
                this.show_comment(sub_comments, cmt, false);
            });
        }
        container.appendChild(sub_comments);
        if (show_footer) {
            let footer = document.createElement("div");
            footer.setAttribute("class", "quick-talk-comment-footer");
            let span = document.createElement("span");
            span.innerText = "Reply";
            footer.appendChild(span);
            let editor = document.createElement("div");
            footer.appendChild(editor);
            span.addEventListener("click", (event) => {
                if (this.instant_compose) {
                    this.instant_compose.parentNode.removeChild(this.instant_compose);
                }
                this.instant_compose = this.compose(editor, parseInt(comment.id), true, (data) => {
                    this.show_comment(sub_comments, data, false).scrollIntoView();
                });
            });
            container.appendChild(footer);
        }
        at.appendChild(container);
        return container;
    }
}