


<template>
    <div class="ui_chatbot_container">
        <div class="ui_chatbot_chat_area">
            <template v-for="(data, index) in contents">
                <answer v-bind:id="'answer-' + index" class="answer" v-bind:key="index" v-if="data.type === 'answer'"
                        v-bind:answer="data"></answer>
                <question class="question" v-bind:key="index" v-else-if="data.type === 'question'" v-bind:question="data.text"></question>
                <choice-list v-else-if="data.type === 'choice'"
                             v-bind:key="index"
                             v-bind:choice_list="data.list"
                             v-bind:connection="connection"
                             v-on:selected="onSelected"></choice-list>
                <questionnaire v-else-if="data.type === 'questionnaire'"
                               class="answer"
                               v-bind:id="'answer-' + index"
                               v-bind:key="index"
                               v-bind:message="data.text"
                               v-bind:questionnaire-thumbs-up-label="questionnaireThumbsUpLabel"
                               v-bind:questionnaire-thumbs-down-label="questionnaireThumbsDownLabel"
                               v-bind:answer-id="data.id"
                               v-bind:keyword="data.keyword"
                               v-on:questionnaire="onQuestionnaire"></questionnaire>
                <contact-us-via-chat v-else-if="data.type === 'contact_us'"
                                     v-bind:message="data.text"
                                     v-bind:contact-us-via-chat-label="contactUsViaChatLabel"
                                     v-on:move-chat="$emit('move-chat')"
                                     ></contact-us-via-chat>
            </template>
        </div>
        <div class="ui_chatbot_actions">
            <input type="text" class="ui_chatbot_keyword"
                    maxlength="100"
                   v-bind:placeholder="keywordPlaceholder"
                   v-bind:readonly="inputReadonly"
                   v-model="keyword"
                   @keypress="onEnter">
            <div v-bind:class="buttonClass" @click="onInputKeyword">{{ sendLabel }}</div>
        </div>
    </div>
</template>

<script>
module.exports = {
    name: "ChatbotBody",
    props: [
        "connection", "service-id", "lang-id", "preview", 'force-emergency', 'is-show-tab',
        "send-label", "keyword-placeholder", "questionnaire-thumbs-up-label", "questionnaire-thumbs-down-label",
        "contact-us-via-chat-label",
    ],
    components: {
        'answer': httpVueLoader('https://chatbotserv.com/client/chatbotvue/answer/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
        'question': httpVueLoader('https://chatbotserv.com/client/chatbotvue/question/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
        'choice-list': httpVueLoader('https://chatbotserv.com/client/chatbotvue/choicelist/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
        'questionnaire': httpVueLoader('https://chatbotserv.com/client/chatbotvue/questionnaire/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
        'contact-us-via-chat': httpVueLoader('https://chatbotserv.com/client/chatbotvue/contactusviachat/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
    },
    data: function() {
        return {
            contents: [],
            keyword: '',
            last_answer: 0,
        }
    },
    created: function() {
        this.refresh();

        this.connection.onclose(this.onDisconnected);

        window.addEventListener('resize', this.onWindowResized);
    },
    mounted: function () {
        this.setMaxHeight();
    },
    destroyed: function () {
        window.removeEventListener('resize', this.onWindowResized);
    },
    methods: { // 省略形式(アロー関数)だと、内部から呼び出せない
        onWindowResized: function () {
            this.setMaxHeight();
        },
        setMaxHeight: function () {
            let vh;
            if (this.isShowTab) {
                vh = window.innerHeight - 33 - 74 - 5 - 4;
            } else {
                vh = window.innerHeight - 3 - 74 - 5 - 4;
            }
            const el = document.querySelector('.ui_chatbot_chat_area');
            el.style.setProperty('max-height', `${vh}px`);
        },
        onDisconnected: function () {
        this.connection.start()
                .then(function() {
                }.bind(this));
        },
        refresh: function () {
            this.contents = [];
            this.keyword = '';
            this.last_answer = 0;
            this.connection.invoke('GetInitialInfo', this.serviceId, this.langId, this.preview, this.forceEmergency)
                .then(function(data) {
                    if (data.value.emergency_message.length > 0) {
                        this.contents.push({
                            type: 'answer',
                            sub_type: 'emergency',
                            text: data.value.emergency_message,
                            is_emergency: true
                        });
                    }
                    this.contents.push({
                        type: 'answer',
                        sub_type: 'message',
                        text: data.value.initial_message,
                    });
                    if (data.value.list.length > 0) {
                        this.contents.push({
                            type: 'choice',
                            list: data.value.list
                        });
                    }
                }.bind(this))
                .catch(function(error) {
                    console.log(error);
                })
            ;
        },
        onSelected: function(choice_data) {
            this.contents.push({
                type: 'question',
                text: choice_data.text,
                id: choice_data.id,
            });
            // ここで「・・・」の回答を表示して、データを取得する
            this.contents.push({
                type: 'answer',
                sub_type: 'message',
                text: '',
                is_thinking: true,
            });
            this.last_answer = this.contents.length - 1;
            this.connection.invoke('Search', this.serviceId, this.langId, this.preview, choice_data.id, choice_data.text)
                .then(function(data) {
                    // 「・・・」の置き換え
                    this.contents.slice(-1)[0].text = data.value.answer.header;
                    this.contents.slice(-1)[0].is_thinking = false;
                    // 回答を追加(あれば)
                    if (data.value.answer.body.length > 0) {
                        this.contents.push({
                            type: 'answer',
                            sub_type: 'answer',
                            text: data.value.answer.body
                        });
                    }
                    // 関連メッセージを追加(あれば)
                    if (data.value.answer.footer.length > 0) {
                        this.contents.push({
                            type: 'answer',
                            sub_type: 'message',
                            text: data.value.answer.footer
                        });
                    }
                    // 関連項目の表示
                    if (data.value.relations !== undefined && data.value.relations.length > 0) {
                        this.contents.push({
                            type: 'choice',
                            list: data.value.relations,
                        });
                    }
                    // アンケート表示
                    this.contents.push({
                        type: 'questionnaire',
                        text: data.value.questionnaire,
                        keyword: '',
                        id: data.value.answer.id,
                    });
                    this.scrollToLastAnswer();
                }.bind(this))
                .catch(function(error) {
                    console.log(error);
                });
        },
        onInputKeyword: function() {
            const paramKeyword = this.$sanitize(this.trimText(this.keyword));
            if (paramKeyword.length > 0 && 100 >= paramKeyword.length) {
                // NGワード検索
                this.searchNGWord(paramKeyword, function () {
                    this.contents.push({
                        type: 'question',
                        text: paramKeyword,
                        id: 0
                    });
                    // ここで「・・・」の回答を表示して、データを取得する
                    this.contents.push({
                        type: 'answer',
                        sub_type: 'message',
                        text: '',
                        is_thinking: true,
                    });
                    this.last_answer = this.contents.length - 1;
                    this.connection.invoke('Search', this.serviceId, this.langId, this.preview, 0, paramKeyword)
                        .then(function(data) {
                            // 「・・・」の置き換え
                            this.contents.slice(-1)[0].text = data.value.answer.header;
                            this.contents.slice(-1)[0].is_thinking = false;
                            // 回答を追加(あれば)
                            if (data.value.answer.body.length > 0) {
                                this.contents.push({
                                    type: 'answer',
                                    sub_type: 'answer',
                                    text: data.value.answer.body
                                });
                            }
                            // 関連メッセージを追加(あれば)
                            if (data.value.answer.footer.length > 0) {
                                this.contents.push({
                                    type: 'answer',
                                    sub_type: 'message',
                                    text: data.value.answer.footer
                                });
                            }
                            // 関連項目の表示
                            if (data.value.relations !== undefined && data.value.relations.length > 0) {
                                this.contents.push({
                                    type: 'choice',
                                    list: data.value.relations,
                                });
                            }
                            // アンケート表示
                            if (data.value.questionnaire !== undefined) {
                                this.contents.push({
                                    type: 'questionnaire',
                                    text: data.value.questionnaire,
                                    keyword: paramKeyword,
                                    id: data.value.answer.id,
                                });
                            }
                            this.scrollToLastAnswer();
                        }.bind(this))
                        .catch(function(error) {
                            console.log(error);
                        });
                }.bind(this));
                this.keyword = '';
            } else {
                this.keyword = '';
            }
        },
        onEnter: function(e) {
            if (e.which === 13) {
                this.onInputKeyword();
            }
        },
        onQuestionnaire: function(flg, word, answerId, keyword) {
            if (word.length > 0) {
                this.contents.push({
                    type: 'question',
                    text: word,
                    id: 0
                });
            }
            // アンケート
            // アンケートデータを送信・メッセージ取得する
            this.contents.push({
                type: 'answer',
                sub_type: 'questionnaire',
                text: '',
                is_thinking: true,
            });
            let count = 0;
            if (this.$cookie.get('questionnaire_thumbs_down_count') != null) {
                count = parseInt(this.$cookie.get('questionnaire_thumbs_down_count'));
            }
            this.last_answer = this.contents.length - 1;
            this.connection.invoke('Questionnaire', this.serviceId, this.langId, this.preview, flg, answerId, keyword, count)
                .then(function(data) {
                    // 「・・・」の置き換え
                    this.contents.slice(-1)[0].text = data.value.questionnaire_replay;
                    this.contents.slice(-1)[0].is_thinking = false;

                    if (!flg) {
                        const validChat = data.value.chat_show_message.length > 0;
                        this.$emit('questionnaire-thumbs-down', validChat);
                        // アンケート「いいえ」を選択されたイベントを発生
                        if (validChat) {
                            this.contents.push({
                                type: 'contact_us',
                                text: data.value.chat_show_message,
                            });
                        }
                    }
                    this.scrollToLastAnswer();
                }.bind(this))
                .catch(function(error) {
                    console.log(error);
                });
        },
        searchNGWord: function (keyword, callback) {
            this.connection.invoke('SearchNGWord', this.serviceId, this.langId, this.preview, keyword)
                .then(function (data) {
                    if (data.value.result) {
                        callback();
                    } else {
                        // 警告メッセージを表示する
                        this.contents.push({
                            type: 'answer',
                            sub_type: 'ng_word',
                            text: data.value.message,
                            is_emergency: true,
                        });
                        this.scrollToLast();
                    }
                }.bind(this))
                .catch(function (error) {
                    console.log(error);                        
                });
        },
        scrollToLastAnswer: function() {
            setTimeout(function () {
                const elAnswer = document.querySelector('#answer-' + this.last_answer);
                if (elAnswer) {
                    const chat_area = document.querySelector('.ui_chatbot_chat_area');
                    const top = (elAnswer.getBoundingClientRect().top - chat_area.getBoundingClientRect().top) -
                        chat_area.style.paddingTop.replace('px', '') - chat_area.style.paddingBottom.replace('px', '') -
                        chat_area.style.marginTop.replace('px', '') - chat_area.style.marginBottom.replace('px', '');
                    // console.log('last_answer:' + this.last_answer + ', answer top:' + top + ', scrollTop:' + $('.chat-area').scrollTop() +
                    //     ', scrollHeight:' + $('.chat-area')[0].scrollHeight + ', offsetHeight:' + $('.chat-area')[0].offsetHeight);
                    this.scrollTo(chat_area, top + chat_area.scrollTop - 10, 500);
                }
            }.bind(this), 100);
        },
        scrollToLast: function () {
            setTimeout(function () {
                const elAnswer = document.querySelector('.answer:last-child');
                if (elAnswer) {
                    const chat_area = document.querySelector('.ui_chatbot_chat_area');
                    const top = (elAnswer.getBoundingClientRect().top - chat_area.getBoundingClientRect().top) -
                        chat_area.style.paddingTop.replace('px', '') - chat_area.style.paddingBottom.replace('px', '') -
                        chat_area.style.marginTop.replace('px', '') - chat_area.style.marginBottom.replace('px', '');
                    // console.log('last_answer:' + this.last_answer + ', answer top:' + top + ', scrollTop:' + $('.chat-area').scrollTop() +
                    //     ', scrollHeight:' + $('.chat-area')[0].scrollHeight + ', offsetHeight:' + $('.chat-area')[0].offsetHeight);
                    this.scrollTo(chat_area, top + chat_area.scrollTop - 10, 500);
                }
            }.bind(this), 100);
        },
        // スクロールアニメーション
        // https://gist.github.com/andjosh/6764939
        scrollTo: function(element, to = 0, duration = 1000, scrollToDone = null) {
            const start = element.scrollTop;
            const change = to - start;
            const increment = 20;
            let currentTime = 0;

            // t = current time
            // b = start value
            // c = change in value
            // d = duration
            const easeInOutQuad = function (t, b, c, d) {
                t /= d/2;
                if (t < 1) return c/2*t*t + b;
                t--;
                return -c/2 * (t*(t-2) - 1) + b;
            };

            const animateScroll = (() => {
                currentTime += increment;
                element.scrollTop = easeInOutQuad(currentTime, start, change, duration);
                if (currentTime < duration) {
                    setTimeout(animateScroll, increment);
                } else {
                    if (scrollToDone) scrollToDone();
                }
            });

            animateScroll();
        },
    },
    computed: {
        buttonClass: function () {
            return this.connection.connectionState === 'Connected' ? 'ui_chatbot_button' : 'ui_chatbot_button disabled';
        },
        inputReadonly: function () {
            return this.connection.connectionState !== 'Connected';
        },
    },
    watch: {
        isShowTab: function () {
            this.setMaxHeight();
        },
    },
}
</script>

<style scoped>
.ui_chatbot_chat_area {
    padding: 0;
    margin: 1px 0 1px 0;
    text-align: right;
    font-size: 14px;
    width: 100%;
    background: white;
    overflow: auto;
    overflow-y: scroll;
    height: 450px;
}
.ui_chatbot_container {
    display: grid;
    grid-template-rows: 1fr 41px;
}

@media only screen and (max-width: 1024px) {
    .ui_chatbot_chat_area {
        /*
         * 画面の高さ - ui_chatbot_actionsの高さ - ui_chattool_header(タブ)の高さ - ui_chattool_bodyのpadding-bottom - ui_chattool_onのpadding
         */
        height: calc(var(--vh, 1vh) * 100) - 33px - 74px - 5px - 4px !important;
    }
}

@media only screen and (max-width: 480px) {
    .ui_chatbot_chat_area {
        /*
         * 画面の高さ - ui_chatbot_actionsの高さ - ui_chattool_header(タブ)の高さ - ui_chattool_bodyのpadding-bottom - ui_chattool_onのpadding
         */
        height: calc(var(--vh, 1vh) * 100) - 33px - 74px - 5px - 4px !important;
    }
}
@media only screen and (max-width: 767px) {
    .ui_chatbot_chat_area {
        /*
         * 画面の高さ - ui_chatbot_actionsの高さ - ui_chattool_header(タブ)の高さ - ui_chattool_bodyのpadding-bottom - ui_chattool_onのpadding
         */
        height: calc(var(--vh, 1vh) * 100) - 33px - 74px - 5px - 4px !important;
    }
}
@media only screen and (max-width: 1023px) {
    .ui_chatbot_chat_area {
        /*
         * 画面の高さ - ui_chatbot_actionsの高さ - ui_chattool_header(タブ)の高さ - ui_chattool_bodyのpadding-bottom - ui_chattool_onのpadding
         */
        height: calc(var(--vh, 1vh) * 100) - 33px - 74px - 5px - 4px !important;
    }
}
.ui_chatbot_actions {
    display: flex;
}
.ui_chatbot_keyword {
    margin: 0;
    max-width: 100%;
    -webkit-box-flex: 1;
    flex: 1 0 auto;
    outline: 0;
    -webkit-tap-highlight-color: rgba(255,255,255,0);
    text-align: left;
    line-height: 1.21428571em;
    padding: .67857143em 1em;
    background: #fff;
    border: 1px solid rgba(34,36,38,.15);
    color: rgba(0,0,0,.87);
    border-radius: .28571429rem;
    box-shadow: none;
    width: 0!important;
    letter-spacing: 0em;
    overflow: visible;

    -webkit-writing-mode: horizontal-tb !important;
    text-rendering: auto;
    word-spacing: normal;
    text-transform: none;
    text-indent: 0px;
    text-shadow: none;
    display: inline-block;
    -webkit-rtl-ordering: logical;
    cursor: text;
    font: 400 16px Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;
}
.ui_chatbot_keyword ::selection {
    background-color: rgba(100,100,100,.4);
    color: rgba(0,0,0,.87);    
}
.ui_chatbot_button {
    cursor: pointer;
    padding: 0.78571429em 1.5em 0.78571429em;
    margin: 0;
    display: flex;
    -webkit-box-align: center;
    align-items: center;
    -webkit-box-flex: 0;
    flex: 0 0 auto;
    min-height: 1em;
    outline: none;
    border: none;
    text-transform: none;
    text-shadow: none;
    font-weight: bold;
    font-size: 16px;
    line-height: 1em;
    font-style: normal;
    text-align: center;
    text-decoration: none;
    box-shadow: 0px 0px 0px 1px transparent inset, 0px 0em 0px 0px rgb(34 36 38 / 15%) inset;
    user-select: none;
    transition: opacity 0.1s ease, background-color 0.1s ease, color 0.1s ease, box-shadow 0.1s ease, background 0.1s ease, -webkit-box-shadow 0.1s ease;
    -webkit-tap-highlight-color: transparent;
    background: #E0E1E2 none;
    color: rgba(0, 0, 0, 0.6);
    border-radius: 0 .28571429rem .28571429rem 0;
}
.ui_chatbot_button.disabled {
    cursor: default;
    opacity: .45!important;
    background-image: none!important;
    -webkit-box-shadow: none!important;
    box-shadow: none!important;
    pointer-events: none!important;
}
</style>
