$(function() {
    Post.init();
});

const Post =
{
    listURL: "",
    editURL: "",
    deleteURL: "",
    callback: "",
    code: "",
    bid: null,
    pid: null,
    uid: null,

    init: function() {
        const form = (
            document.getElementById("fPostView") ||
            document.getElementById("fPostWrite") ||
            document.getElementById("fPostEdit")
        );
        this.code = form.elements["code"].value;
        this.bid = form.elements["bid"].value;
        this.pid = form.elements["pid"].value;

        if(form.elements.hasOwnProperty("uid")) {
            this.uid = form.elements["uid"].value;
        }
        if(form.elements.hasOwnProperty("list_url")) {
            this.listURL = form.elements["list_url"].value;
        }
        if(form.elements.hasOwnProperty("edit_url")) {
            this.editURL = form.elements["edit_url"].value;
        }
        if(form.elements.hasOwnProperty("delete_url")) {
            this.deleteURL = form.elements["delete_url"].value;
        }

        this.callback = (this.listURL + "/" + String(this.pid));

        let captcha = document.querySelector('a[href="//captcha.org/captcha.html?laravel"]');
        if(captcha) {
            captcha.remove();
        }

        Post.setInitEditor();
    },

    // 첨부파일 입력란 아래에 파일 크기를 표시
    displayFileSize: function (object) {
        $(object).next().children().text(formatBytes(uploadFileSize(object)));
    },

    // 첨부한 파일의 크기 표시를 삭제
    removeFileSize: function (object) {
        $(object).next().children().text("0");
    },

    // tinyMCE 게시판 에디터로 커서 이동
    focusContent: function (id) {
        tinymce.execCommand('mceFocus', false, id);
    },

    // 입력 내용의 문자 통계 반환
    getStats: function (id) {
        let body = tinymce.get(id).getBody(), text = tinymce.trim(body.innerText || body.textContent);

        return {
            chars: text.length,
            words: text.split(/[\w\u2019\'-]+/).length
        };
    },

    // 금지 단어 확인
    filterSpamKeyword: function (subject, content) {
        let ret = {
            "subject": null,
            "content": null
        };
        $.ajax({
            headers: {'X-CSRF-TOKEN': CSRF},
            url: (BASE_URL + "/api/filterSpamKeyword"),
            type: "post",
            dataType: "json",
            async: false,
            cache: false,
            data: {subject: subject, content: content},
            success: function (res) {
                ret.subject = res.subject;
                ret.content = res.content;
            }
        });
        return ret;
    },

    // 등록/수정
    submit: function(e)
    {
        let form = document.getElementById(e.dataset.form);

        $(form).validate({
            onkeyup: false,
            onclick: false,
            onfocusout: false,
            showErrors: function (errorMap, errorList) {
                if (this.numberOfInvalids() && errorList.length > 0) {
                    alert(errorList[0].message);
                    $(errorList[0].element).focus();
                }
            },
            rules: {
                is_speaker: {number: true},
                is_notice: {number: true},
                is_secret: {number: true},
                category: {required: function(e) {
                        return (document.getElementById("category") && !$("#isSpeaker").is("checked") && !$("#isNotice").is("checked") && e.dataset.categoryRequired === "1");
                    }, number: true}, // 게시판 분류
                username: {required: "#username:enabled", minlength: 2, maxlength: 10},
                password: {required: "#password:enabled", minlength: 3, maxlength: 10},
                subject: {required: true},
                content: {"required_tinymce": true},
                captcha: {required: "#captcha:enabled"}, // Captcha 사용 여부

                // 게시판 Tag
                // submitHandler 처리

                // 게시판 Link
                // submitHandler 처리

                // 게시판 File
                // submitHandler 처리
             },
            messages: {
                is_speaker: {number: "전체공지 값은 숫자여야 합니다."},
                is_notice: {number: "공지 값은 숫자여야 합니다."},
                is_secret: {number: "비밀글 값은 숫자여야 합니다."},
                category: {required: "분류를 선택하세요.", number: "분류 값은 숫자여야 합니다."},
                username: {required: "이름을 입력하세요.", minlength: "이름을 두 글자 이상 입력하세요.", maxlength: "이름은 10자까지 입력 가능합니다."},
                password: {required: "비밀번호를 입력하세요.", minlength: "비밀번호는 3자 이상 입력하세요.", maxlength: "비밀번호는 10자까지 입력 가능합니다."},
                subject: {required: "제목을 입력하세요."},
                captcha: {required: "자동등록방지 문자를 입력하세요.", captchaKey: "자동등록방지 문자가 잘못되었습니다."},
            },
            submitHandler: function(form) {
                let subjectMinLength = Number(form.elements["subject_min_length"].value);
                let subjectMaxLength = Number(form.elements["subject_max_length"].value);
                let contentMinLength = Number(form.elements["content_min_length"].value);
                let contentMaxLength = Number(form.elements["content_max_length"].value);
                let uploadFileMaxSize = Number(form.elements["upload_file_max_size"].value);
                let inSubjectLength = Number(form.elements["subject"].value.length);
                let inContentLength = (tinymce.editors.length > 0 ? Number(Post.getStats("content").chars) : form.content.value.length);

                try
                {
                    let error = function(e) {throw new Error(e);};

                    // 제목, 내용 길이 확인
                    if (subjectMinLength > 0 && inSubjectLength < subjectMinLength) {
                        form.subject.focus();
                        error("제목은 최소 " + subjectMinLength + "글자 이상 입력해야 합니다.");
                    }else if (subjectMaxLength > 0 && inSubjectLength > subjectMaxLength) {
                        form.subject.focus();
                        error("제목은 최대 " + subjectMaxLength + "글자 이하 입력 가능합니다.");
                    }
                    if (contentMinLength > 0 && inContentLength < contentMinLength) {
                        Post.focusContent("content");
                        error("내용은 최소 " + contentMinLength + "글자 입력해야 합니다.");
                    }else if (contentMaxLength > 0 && inContentLength > contentMaxLength) {
                        Post.focusContent("content");
                        error("내용은 최대 " + contentMaxLength + "글자 입력 가능합니다.");
                    }

                    let spamKeywords = Post.filterSpamKeyword(form.subject.value, form.content.value);
                    if (spamKeywords.subject) {
                        form.subject.focus();
                        error("제목에 금지단어 ('" + spamKeywords.subject + "')가 포함 되어있습니다.");
                    }
                    if (spamKeywords.content) {
                        form.content.focus();
                        error("내용에 금지단어 ('" + spamKeywords.content + "')가 포함 되어있습니다.");
                    }

                    // Tag 개수 확인
                    let tags = document.getElementById("tags");
                    if(tags) {
                        if(tags.value.split(',').length > 10) {
                            alert("Tag 는 최대 10개 입력 가능합니다.");
                            return false;
                        }
                    }

                    // Link URL 형식인지 확인
                    let links = form.getElementsByClassName("form-control-url");
                    if(links.length > 0) {
                        for(let j in links) {
                            let link = links[j];
                            if(link.value && !isValidURL(link.value)) {
                                link.focus();
                                error("URL 형식이 잘못되었습니다.");
                                break;
                            }
                        }
                    }

                    // 첨부파일 크기 확인
                    if(uploadFileMaxSize > 0) {
                        let files = form.getElementsByClassName("form-control-file");
                        let byte = (uploadFileMaxSize * 1024 * 1024);

                        for(let i in files) {
                            let file = files[i];
                            if(file.value) {
                                let size = uploadFileSize(file);
                                if (size > byte) {
                                    file.value = null;
                                    Post.removeFileSize(file);
                                    error("첨부 가능한 파일의 최대 크기는 " + uploadFileMaxSize + "MB 입니다.");
                                    break;
                                }
                            }
                        }
                    }

                    showLoading();
                    return true;
                }catch(err) {
                    alert(err.message);
                    return false;
                }
            }
        });

        $(form).submit();
    },

    // 복사
    copy: function(e) {
        if (copyToClipboard(e.target.href)) {
            alert("게시글 주소가 복사 되었습니다.\n주소를 Ctrl + C 하여, 붙여 넣을 곳에 Ctrl + V 하세요.");
        }
        return false;
    },

    // 즐겨찾기
    bookmark: function(e)
    {
        const isActive = e.classList.contains("active");

        $.ajax({
            url: (this.callback + "/bookmark"),
            type: "post",
            cache: false,
            async: false,
            data: {bid: this.bid, pid: this.pid},
            dataType: "json",
            beforeSend: function (xhr) {
                if (!loginCheck()) {
                    return xhr.abort();
                }

                const message = (isActive ? "즐겨찾기 해제 하시겠습니까?" : "즐겨찾기 등록 하시겠습니까?");
                if (!confirm(message)) {
                    return false;
                }
            },
            success: function (res) {
                if (res.success) {
                    if (!isActive) {
                        alert("즐겨찾기 등록되었습니다.");
                        e.classList.add("active");
                    } else {
                        alert("즐겨찾기 해제되었습니다.");
                        e.classList.remove("active");
                    }
                } else {
                    alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
                }
            },
            error: function (xhr, status, err) {
                procErrorEvent(xhr, status, err);
            }
        });
        e.blur();
    },

    // 신고
    blame: function(e)
    {
        e.blur();

        if(!loginCheck()) {
            return false;
        }

        // 신고 접수 유효성
        $("#fPostBlame").validate({
            onkeyup: false,
            onclick: false,
            onfocusout: false,
            rules: {
                type: {required: true, contains: ['1', '2', '3', '4', '5', '6', '7', '8', '9']},
                reason: {required: true, normalizer: function (value) {return $.trim(value);}, maxlength: 1000}
            },
            messages: {
                type: {required: "신고 유형을 선택해주세요.", contains: "잘못된 요청입니다."},
                reason: {required: "신고 내용을 입력해주세요.", maxlength: "신고 내용은 {0}자까지 입력 가능합니다."}
            },
            showErrors: function (errorMap, errorList) {
                if (this.numberOfInvalids()) {
                    alert(errorList[0].message);
                    errorList[0].element.focus();
                }
            },
            submitHandler: function (form) {
                if (confirm("신고를 접수하시겠습니까?")) {
                    let formData = new FormData(form);
                    formData.append("bid", Post.bid);
                    formData.append("pid", Post.pid);

                    $.ajax({
                        url: (Post.callback + "/blame"),
                        type: "post",
                        cache: false,
                        async: false,
                        contentType: false,
                        processData: false,
                        data: formData,
                        dataType: "json",
                        beforeSend: function (xhr) {
                            if (!loginCheck()) {
                                xhr.abort();
                            }
                        },
                        success: function (res) {
                            if (res.success) {
                                alert("감사합니다. 신고가 접수되었습니다. 이용 규칙을 위반한 것으로 확인되면 게시글이 삭제됩니다.");
                            } else {
                                alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
                            }
                        },
                        error: function (xhr, status, err) {
                            procErrorEvent(xhr, status, err);
                        },
                        complete : function() {
                            $("#postBlameModal").modal('hide');
                        }
                    });
                }
            }
        });
    },

    // 수정
    edit: function(e)
    {
        e.blur();

        let href = this.editURL;
        if(!this.uid) { // 권한 확인
            const passwd = prompt("게시글 비밀번호 확인이 필요합니다.\n비밀번호를 입력해주세요.");
            if(!passwd) {
                return false;
            }
            href += "?passwd=" + encodeURIComponent(passwd.trim());
        }else{
            if (!loginCheck()) {
                return false;
            }
        }

        location.href = href;
    },

    // 삭제
    delete: function(e)
    {
        e.blur();

        $.ajax({
            url: this.deleteURL,
            type: "delete",
            data: {bid: this.bid, pid: this.pid, _method: "delete"},
            dataType: "json",
            beforeSend: function (xhr) {
                if (!Post.uid) { // 권한 확인
                    const passwd = prompt("게시글 비밀번호 확인이 필요합니다.\n비밀번호를 입력해주세요.");
                    if (!passwd) {
                        return false;
                    }
                    this.url += ("?passwd=" + encodeURIComponent(passwd.trim()));
                } else {
                    if (!loginCheck()) {
                        return xhr.abort();
                    }
                }

                if (!confirm("게시글을 삭제하시겠습니까?")) {
                    return false;
                }
            },
            success: function (res) {
                if (res.success) {
                    alert("게시글이 삭제되었습니다.");
                    location.replace(Post.listURL);
                } else {
                    alert(res.message);
                }
            },
            error: function (xhr, status, err) {
                procErrorEvent(xhr, status, err);
            }
        });
    },

    // 인쇄
    print: function()
    {
        let $container = $("#boardView").clone();
        let cssText = "";
        let cssLink = "";
        let style = document.getElementsByTagName("style");
        let link = document.getElementsByTagName("link");
        for (let i in style) {
            if(typeof style[i].innerHTML !== "undefined") {
                cssText += style[i].innerHTML;
            }
        }
        for (let i in link) {
            if(typeof link[i].outerHTML !== "undefined") {
                cssLink += link[i].outerHTML;
            }
        }

        let popupWindow = popupCenter(null, "_blank", 900, 680);
        if (popupWindow.focus) {
            popupWindow.focus();
        }

        let printHtml = '<!DOCTYPE html>' +
                        '<html lang="ko">' +
                        '<head>' +
                        cssLink +
                        '<style>' + cssText + '</style>' +
                        '</head>' +
                        '<body>' +
                        '<div id="boardView" class="container-fluid">' + $container.get(0).innerHTML + '</div>' +
                        '</body>' +
                        '</html>';

        popupWindow.document.write(printHtml);

        // 프린트 전
        popupWindow.onbeforeprint = function () {
            printHtml = popupWindow.document.body;
            printHtml.style.backgroundColor = "#fff";
            printHtml.style.padding = "0";
            printHtml.style.height = "initial";
            printHtml.style.width = "100%";
            printHtml.style.minWidth = "auto";
            printHtml.style.maxWidth = "initial";
            printHtml.parentNode.style.padding = "0";
            printHtml.parentNode.style.maxWidth = "initial";
            printHtml.getElementsByTagName("nav")[0].remove();
            printHtml.getElementsByTagName("blockquote")[0].style.border = "none";
            printHtml.getElementsByClassName("foot")[0].remove();
            popupWindow.document.body.innerHTML = printHtml.innerHTML;
        };

        // 프린트 후
        popupWindow.onafterprint = function () {
            popupWindow.document.body.innerHTML = "";
            popupWindow.document.write("");
        };

        popupWindow.document.close();
        popupWindow.focus();

        setTimeout(function () {
            popupWindow.print();
            popupWindow.close();
        }, 300);

        return false;
    },

    // 좋아요
    like: function(e)
    {
        e.blur();

        let bid = this.bid;
        let pid = this.pid;
        let type = e.value;

        $.ajax({
            url: (this.callback + "/like"),
            type: "post",
            cache: false,
            async: false,
            data: {bid: bid, pid: pid, type: type},
            dataType: "json",
            beforeSend: function (xhr) {
                if (!loginCheck()) {
                    xhr.abort();
                }
            },
            success: function (res) {
                if (res.success) {
                    Post.toggleLike(1, !Number(e.dataset.active));
                } else {
                    alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
                }
            },
            error: function (xhr, status, err) {
                procErrorEvent(xhr, status, err);
            }
        });
    },

    // 싫어요
    dislike: function(e)
    {
        e.blur();

        let bid = this.bid;
        let pid = this.pid;
        let type = e.value;

        $.ajax({
            url: (this.callback + "/dislike"),
            type: "post",
            cache: false,
            async: false,
            data: {bid: bid, pid: pid, type: type},
            dataType: "json",
            beforeSend: function (xhr) {
                if (!loginCheck()) {
                    xhr.abort();
                }
            },
            success: function (res) {
                if (res.success) {
                    Post.toggleLike(2, !Number(e.dataset.active));
                } else {
                    alert(res.message || "처리 중 오류가 발생하였습니다. 관리자에게 문의하십시오.");
                }
            },
            error: function (xhr, status, err) {
                procErrorEvent(xhr, status, err);
            }
        });
    },

    // 다운로드
    download: function (e)
    {
        let action = (this.callback + "/download");
        if(!this.uid) { // 권한 확인
            const passwd = prompt("게시글 비밀번호 확인이 필요합니다.\n비밀번호를 입력해주세요.");
            if(!passwd) {
                return false;
            }
            action += "?passwd=" + encodeURIComponent(passwd.trim());
        }else{
            if (!loginCheck()) {
                return false;
            }
        }

        let form = document.createElement("form");
        let inputHidden_1 = document.createElement("input");
        let inputHidden_2 = document.createElement("input");
        let inputHidden_3 = document.createElement("input");
        let inputHidden_4 = document.createElement("input");
        let iframe = document.createElement("iframe");
        iframe.setAttribute("name", "fr_an_post");
        iframe.setAttribute("width", "0");
        iframe.setAttribute("height", "0");
        iframe.setAttribute("hidden", "hidden");
        iframe.src = ("data:text/html;charset=utf-8," + encodeURI(""));

        form.method = "post";
        form.action = action;
        form.target = "fr_an_post";
        inputHidden_1.type = "hidden";
        inputHidden_1.name = "bid";
        inputHidden_1.value = this.bid;
        inputHidden_2.type = "hidden";
        inputHidden_2.name = "pid";
        inputHidden_2.value = this.pid;
        inputHidden_3.type = "hidden";
        inputHidden_3.name = "fid";
        inputHidden_3.value = e.dataset.fid;
        inputHidden_4.type = "hidden";
        inputHidden_4.name = "_token";
        inputHidden_4.value = CSRF;
        form.appendChild(inputHidden_1);
        form.appendChild(inputHidden_2);
        form.appendChild(inputHidden_3);
        form.appendChild(inputHidden_4);
        document.body.appendChild(iframe);
        document.body.appendChild(form);
        form.submit();

        return false;
    },

    // Link 이동
    link: function (e)
    {
        $.ajax({
            url: (this.callback + "/link"),
            type: "post",
            cache: false,
            async: false,
            data: {bid: this.bid, pid: this.pid, lid: e.dataset.lid},
            dataType: "json",
            success: function (res) {
                let a = document.createElement('a');
                a.href = res.href;
                a.target = "_blank";
                a.click();
            },
            error: function (xhr, status, err) {
                procErrorEvent(xhr, status, err);
            }
        });

        return false;
    },

    // 좋아요/싫어요 처리
    toggleLike: function(type, active) {
        let btnPostLike = document.getElementById("btnPostLike");
        let btnPostDisLike = document.getElementById("btnPostDislike");
        if(type === 1) {
            this.setLike(active);
            if(Number(btnPostDisLike.dataset.active)) {
                this.setDislike(false);
            }
        }else if(type === 2) {
            this.setDislike(active);
            if(Number(btnPostLike.dataset.active)) {
                this.setLike(false);
            }
        }
    },

    // 좋아요 갱신
    setLike: function(active) {
        let button = document.getElementById("btnPostLike");
        let rows = Number(button.dataset.rows);
        if (active) {
            rows = (rows + 1);
            button.innerHTML = '<i class="fas fa-thumbs-up"></i><span> ' + String(rows) + '</span>';
            button.dataset.active = "1";
        }else{
            rows = (rows > 0 ? rows - 1 : rows);
            button.innerHTML = '<i class="far fa-thumbs-up"></i><span> ' + String(rows) + '</span>';
            button.dataset.active = "0";
        }
        button.dataset.rows = rows;
        document.getElementById("txtPostLikeCnt").innerText = rows;
    },

    // 싫어요 갱신
    setDislike: function(active) {
        let button = document.getElementById("btnPostDislike");
        let rows = Number(button.dataset.rows);
        if (active) {
            rows = (rows + 1);
            button.innerHTML = '<i class="fas fa-thumbs-down"></i><span> ' + String(rows) + '</span>';
            button.dataset.active = "1";
        }else{
            rows = (rows > 0 ? rows - 1 : rows);
            button.innerHTML = '<i class="far fa-thumbs-down"></i><span> ' + String(rows) + '</span>';
            button.dataset.active = "0";
        }
        button.dataset.rows = rows;
        document.getElementById("txtPostDislikeCnt").innerText = rows;
    },

    // 게시글 QR 보기
    qrcode: function(e) {
        let $modalQRCode = $("#modalQRCode");
        $modalQRCode.find(".modal-header .modal-title").html(e.dataset.title);
        $modalQRCode.find(".modal-body").html('<br/><img src="https://chart.googleapis.com/chart?cht=qr&chld=H|2&chs=100&chl=' + encodeURIComponent(e.href) + '"/><br/><br/>QR Code를 스캔하시면 게시글을 확인하실 수 있습니다.');
        $modalQRCode.modal('toggle');
        return false;
    },

    // SNS 북 공유하기
    sns: function(e) {console.log(1);
        let linkURL = window.location.href;
        switch(e.dataset.target) {
            case "1":
                popupCenter( 'http://www.facebook.com/sharer.php?u=' + encodeURIComponent(linkURL), "Facebook share", 400, 500);
                break;
            case "2": // 트위터 공유하기
                let sendText = "Twitter share";
                popupCenter("https://twitter.com/intent/tweet?text=" + sendText + "&url=" + linkURL, "Twitter share", 550, 600);
                break;
            case "3": // 레딧 공유하기
                popupCenter("https://www.reddit.com/submit?url=" + encodeURIComponent(linkURL), "Reddit share", 700, 800);
                break;
        }
    },

    /*
     * 게시글 에디터 옵션 변경
     */
    setInitEditor: function () {
        if(tinyMCE.activeEditor) {
            let tinyMCEExtendSetting = {
                file_browser_url: (BASE_URL + "/board/" + this.code + "/uploader"),
            };

            tinymce.init(Object.assign(tinyMCE.activeEditor.settings, tinyMCEExtendSetting));
        }
    },
};

// 게시글 등록/수정 실행
$(document).on("click", "#btnPostSubmit", function() {
    Post.submit(this);
});

// 파일 용량 확인
$(document).on("change", "input.form-control-file", function() {
    Post.displayFileSize(this);
});

// 전체공지, 공지 둘중 하나만 체크
$(document).on("change", "input#isSpeaker, input#isNotice", function() {
    let $all = $("#isSpeaker");
    let $one = $("#isNotice");
    if (this.id === "isNotice" && $all.is(":checked")) {
        $all.prop("checked", false);
    } else if (this.id === "isSpeaker" && $one.is(":checked")) {
        $one.prop("checked", false);
    }
});

// QR-CODE 보기
$(document).on("click", "a#btnPostQRCode, a.btn-qr-code", function () {
    return Post.qrcode(this);
});

// 게시글 인쇄
$(document).on("click", "a#btnPostPrint", function () {
    return Post.print(this);
});

// 게시글 주소 복사
$(document).on("click", "a#btnPostCopy", function() {
    return Post.copy(this);
});

// 게시글 SNS 공유
$(document).on("click", "li.btn-post-sns", function() {
   Post.sns(this);
});

// 게시글 즐겨찾기
$(document).on("click", "#btnPostBookmark", function() {
    Post.bookmark(this);
});

// 게시글 신고
$(document).on("click", "#btnPostBlame", function() {
    Post.blame(this);
});

// 게시글 수정
$(document).on("click", "#btnPostEdit", function() {
    Post.edit(this);
});

// 게시글 삭제
$(document).on("click", "#btnPostDelete", function() {
    Post.delete(this);
});

// 게시글 좋아요
$(document).on("click", "#btnPostLike", function () {
    Post.like(this);
});

// 게시글 싫어요
$(document).on("click", "#btnPostDislike", function () {
    Post.dislike(this);
});

// 게시글 다운로드
$(document).on("click", "a.btn-file-download", function () {
    return Post.download(this);
});

// 게시글 Link 이동
$(document).on("click", "a.btn-site-url", function () {
    return Post.link(this);
});

// 게시글 신고 모달 열리면 초기화
$(document).on("show.bs.modal", "#postBlameModal", function(e) {
    let form = e.currentTarget.getElementsByTagName("form")[0];
    form.elements["type"].selectedIndex = 0;
    form.elements["reason"].value = "";

    if(!IS_USER) {
        return false;
    }
});

// 공지, 전체공지일 경우 문의 유형은 무시된다.
$(document).on("change", "#isSpeaker, #isNotice", function () {
    document.getElementById("categoryBox").style.display = (this.checked ? "none" : "table-row");
});
