const Review =
{
    listURL: (BASE_URL + "/api/movie/review/latest"),
    saveURL: (BASE_URL + "/movie/review"),
    mode: "", // write, modify, delete
    mid: 0,
    rid: 0,
    total: 0,
    page: 1,
    perPage: 10,
    contentLengthLimit: 1000,
    writeForm: null,
    blameForm: null,
    rateYo: null,

    init: function ()
    {
        this.setData();

        let mainImg = document.getElementById("btnMainImgEnlargement");
        if(mainImg) {
            mainImg.onclick = function () {
                popupCenter(this.value, this.title);
            };
        }

        // 평균 평점
        let avgRate = document.getElementById("movieAvgRate");
        if(avgRate) {
            $("#movieAvgRate").rateYo({
                spacing: "1px",
                multiColor: {
                    "startColor": "#F39C12",
                    "endColor": "#E74C3C"
                },
                rating: (avgRate.dataset.rate || 0),
                maxValue: 10,
                numStars: 5,
                readOnly: true,
                starWidth: "18px"
            });
        }

        // 평점·후기 등록/수정
        this.rateYo = $("#rateYo #reviewRate").rateYo({
            spacing: "5px",
            maxValue: 10,
            numStars: 5,
            multiColor: {
                "startColor": "#F39C12",
                "endColor": "#E74C3C"
            },
            halfStar: true,
            onChange: function (rate) {
                Review.writeForm.elements["rate"].value = rate;
                document.getElementById("reviewValue").innerText = rate;
            },
            onSet: function (rate) {
                Review.writeForm.elements["rate"].value = rate;
                document.getElementById("reviewValue").innerText = rate;
            }
        });
    },

    // Movie 정보 설정
    setData: function() {
        let data = document.querySelector("[data-mid]");
        if(data) {
            this.mid = data.dataset.mid;

            this.writeForm = document.getElementById("fMovieReviewWrite");
            if(this.writeForm) {
                this.writeForm.elements["mid"].value = this.mid;
            }

            this.blameForm = document.getElementById("fMovieReviewBlame");
            if(this.blameForm) {
                this.blameForm.elements["mid"].value = this.mid;
            }
        }
    },

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

    latest: function() {
        let listURL = (this.listURL + "/" + this.mid);

        $("#movieReviewList").load(listURL, function (response, status, xhr) {
            let total = $('input[name="total"]').val()

            if (total) { // 댓글 수 표시
                $("#movieReviewTotal").text(total);
            }

            Review.total = total;
        });
    },

    write: function(e)
    {
        e.target.blur();

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

        this.mode = "write";
        this.writeForm.elements["mode"].value = this.mode;
    },

    modify: function(e)
    {
        e.target.blur();

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

        let data = e.target.parentNode.parentNode;
        this.mid = data.dataset.mid;
        this.rid = data.dataset.rid;
        this.mode = "modify";
        this.rateYo.rateYo("rating", data.dataset.rate);
        this.writeForm.elements["mid"].value = this.mid;
        this.writeForm.elements["rid"].value = this.rid;
        this.writeForm.elements["mode"].value = this.mode;
        this.writeForm.elements["content"].value = data.dataset.content;
        this.checkByte();

        if(data.dataset.name) {
            $("dt > h4", this.writeForm).text(data.dataset.name)
        }
    },

    remove: function(e)
    {
        e.target.blur();

        if (confirm("정말 삭제 하시겠습니까?")) {
            let data = e.target.parentNode.parentNode;
            this.mid = data.dataset.mid;
            this.rid = data.dataset.rid;
            this.mode = "delete";
            let url = (this.saveURL + "/" + this.rid);

            $.ajax({
                url: url,
                type: 'delete',
                cache: false,
                async: false,
                data: {mid: this.mid, rid: this.rid, mode: this.mode},
                dataType: 'json',
                beforeSend: function (xhr) {
                    if (!loginCheck()) {
                        xhr.abort();
                    }
                },
                success: function (res) {
                    if (res.success) {
                        alert("감상 후기가 삭제되었습니다.");
                        location.reload();
                    } else {
                        alert(res.message);
                    }
                },
                error: function (xhr, status, err) {
                    procErrorEvent(xhr, status, err);
                }
            });
        }
        return false;
    },

    like: function(e)
    {
        e.target.blur();

        let btn = null;
        if (e.target.tagName !== "BUTTON") {
            btn = e.target.parentNode;
        } else {
            btn = e.target;
        }

        if (btn.classList.contains('active')) {
            alert("이미 공감 하셨습니다.");
            return false;
        }

        this.mid = btn.dataset.mid;
        this.rid = btn.dataset.rid;
        let url = (this.saveURL + "/like");

        $.ajax({
            url: url,
            type: 'post',
            cache: false,
            async: false,
            data: {mid: this.mid, rid: this.rid},
            dataType: 'json',
            beforeSend: function (xhr) {
                if (!loginCheck()) {
                    xhr.abort();
                }
            },
            success: function (res) {
                if (res.success) {
                    btn.classList.add("active");
                    btn.getElementsByTagName("em")[0].innerText = res.like;
                } else {
                    alert(res.message);
                }
            },
            error: function (xhr, status, err) {
                procErrorEvent(xhr, status, err);
            }
        });
        return false;
    },

    dislike: function(e)
    {
        e.target.blur();

        let btn = null;
        if (e.target.tagName !== "BUTTON") {
            btn = e.target.parentNode;
        } else {
            btn = e.target;
        }

        if (btn.classList.contains('active')) {
            alert("이미 비공감 하셨습니다.");
            return false;
        }

        this.mid = btn.dataset.mid;
        this.rid = btn.dataset.rid;
        let url = (this.saveURL + "/dislike");

        $.ajax({
            url: url,
            type: 'post',
            cache: false,
            async: false,
            data: {mid: this.mid, rid: this.rid},
            dataType: 'json',
            beforeSend: function (xhr) {
                if (!loginCheck()) {
                    xhr.abort();
                }
            },
            success: function (res) {
                if (res.success) {
                    btn.classList.add("active");
                    btn.getElementsByTagName("em")[0].innerText = res.dislike;
                } else {
                    alert(res.message);
                }
            },
            error: function (xhr, status, err) {
                procErrorEvent(xhr, status, err);
            }
        });
        return false;
    },

    validate: function(e)
    {
        let form = e.target;

        $(form).validate({
            onkeyup: false,
            onclick: false,
            onfocusout: false,
            rules: {
                mode: {required: true, contains: ["write", "modify"]},
                rate: {required: true, min: 1, max: 10},
                content: {required: true, minlength: 1, maxlength: 1000}
            },
            messages: {
                mode: {required: "처리중 오류가 발생하였습니다.", contains: "잘못된 요청입니다."},
                rate: {required: "평점을 선택해주세요.", min: "평점을 선택해주세요.", max: "평점은 최대 10점 입니다."},
                content: {required: "감상평을 입력해주세요.", minlength: "감상평을 입력해주세요.", maxlength: "감상평은 최대 1000자 입력 가능합니다."}
            },
            showErrors: function (errorMap, errorList) {
                if (this.numberOfInvalids()) {
                    alert(errorList[0].message);
                    errorList[0].element.focus();
                    e.disabled = false;
                }
            },
            submitHandler: function (form) {
                let rid = form.elements["rid"].value;
                let mode = form.elements["mode"].value;
                let content = form.elements["content"].value;
                let spamKeyword = Review.filterSpamKeyword(content); // 금지 단어 검사
                if (spamKeyword) {
                    alert("내용에 금지어 ('" + spamKeyword + "')가 포함 되어있습니다.");
                    form.elements["content"].focus();
                    return false;
                }

                // 감상평 후기 등록
                let formData = $(form).serializeArray();

                // 버튼 비활성화
                form.elements["btn_review_submit"].disabled = true;
                form.elements["btn_review_cancel"].disabled = true;

                let url = Review.saveURL;
                let type = "post"

                if(mode === "modify") {
                    url = (url + "/" + rid);
                    type = "put"
                }

                $.ajax({
                    headers: {'X-CSRF-TOKEN': CSRF},
                    url: url,
                    type: type,
                    cache: false,
                    async: true,
                    data: formData,
                    dataType: 'json',
                    beforeSend: function (xhr) {
                        if (!loginCheck()) {
                            xhr.abort();
                        }
                        showLoading();
                    },
                    success: function (res) {
                        if (res.success) {
                            if(mode === "write") {
                                alert("감상 후기가 등록되었습니다.");
                            }else{
                                alert("감상 후기가 수정되었습니다.");
                            }
                            location.reload();
                        }else{
                            alert(res.message);
                        }
                        Review.reset();
                    },
                    error: function (xhr, status, err) {
                        procErrorEvent(xhr, status, err);
                    },
                    complete: function() {
                        hideLoading();
                    }
                });
                return false;
            }
        });

        $(form).submit();
        return false;
    },

    reset: function()
    {
        this.rid = "";
        this.mode = "";
        this.total = 0;
        this.page = 1;
        let modal = bootstrap.Modal.getInstance(
            document.querySelector("#movieReviewWriteModal")
        );
        modal.hide();

        this.writeForm.elements["rid"].value = "";
        this.writeForm.elements["mode"].value = "";
        this.writeForm.elements["content"].value = "";
        this.writeForm.elements["btn_review_submit"].disabled = false;
        this.writeForm.elements["btn_review_cancel"].disabled = false;
        document.getElementById("reviewContentLength").innerText = "0";

        Review.rateYo.rateYo("rating", 0);
    },

    // 평점 별 생성
    general: function(id) {
        let config = {
            spacing: "1px",
            multiColor: {
                "startColor": "#F39C12",
                "endColor": "#E74C3C"
            },
            rating: 0,
            maxValue: 10,
            numStars: 5,
            readOnly: true,
            starWidth: "17px",
        };
        $("#" + id + " dl > dt > var").each(function(index, item) {
            config.rating = item.dataset.rate;
            $(item).rateYo(config);
        });
    },

    // 글자수 확인
    checkByte: function() {
        checkByte("reviewContent", "reviewContentLength", Review.contentLengthLimit);
    },

    // 정렬 처리
    sort: function(e) {
        let form = document.getElementById("fMovieReviewIndex");
        let params = new URLSearchParams({sort: e.target.value});

        location.href = (form.action + "?" + params.toString());
    },

    // 평점·후기 신고
    blame: function(e)
    {
        e.target.blur();

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

        $("#fMovieReviewBlame").validate({
            onkeyup: false,
            onclick: false,
            onfocusout: false,
            rules: {
                blame_type: {required: true, contains: ['1', '2', '3', '4', '5', '6', '7', '8', '9']},
                blame_reason: {required: true, normalizer: function (value) {return $.trim(value);}, maxlength: 1000}
            },
            messages: {
                blame_type: {required: "신고 유형을 선택해주세요.", contains: "잘못된 요청입니다."},
                blame_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 data = e.target.parentNode.parentNode;
                    form.elements["mid"].value = data.dataset.mid;
                    form.elements["rid"].value = data.dataset.rid;
                    let formData = $(form).serializeArray();
                    let url = (Review.saveURL + "/blame");

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

// 감상 후기 글자 수 입력
$(document).on('keydown keyup', "textarea#reviewContent", Review.checkByte);

// 평점·후기 등록/수정 처리
$(document).on("submit", "#fMovieReviewWrite", Review.validate);

// 평점·후기 등록 모달
$(document).on("click", "#btnMovieReviewWrite", function(e) {
    Review.write(e);
});

// 평점·후기 수정 모달
$(document).on("click", ".btn-review-modify", function(e) {
    Review.modify(e);
});

// 평점·후기 삭제
$(document).on("click", ".btn-review-remove", function(e) {
    Review.remove(e);
});

// 평점·후기 신고
$(document).on("click", ".btn-review-blame", function(e) {
    Review.blame(e);
});

// 평점·후기 모달 열리면 초기화
$(document).on("show.bs.modal", "#movieReviewWriteModal", function(e) {
    Review.reset(e);
});

// 평점·후기 모달 닫히면 초기화
$(document).on("hidden.bs.modal", "#movieReviewWriteModal", function(e) {
    Review.reset(e);
});

// 평점·후기 공감
$(document).on("click", "button.btn-review-like", function(e) {
    Review.like(e);
});

// 평점·후기 비공감
$(document).on("click", "button.btn-review-dislike", function(e) {
    Review.dislike(e);
});

// 평점·후기 정렬
$(document).on("change", "select#sort", function(e) {
    Review.sort(e);
});
