


<template>
    <div class="ui_chat_body" v-cloak>
        <chat-startup v-if="isScreen('Startup')"
            v-bind:connection="connection"
            v-bind:service-id="serviceId"
            v-bind:lang-id="langId"
            v-bind:preview="preview"
            v-bind:email="email"
            v-bind:user-name="userName"
            v-bind:user-id="userId"
            v-bind:chat-message="initialChatMessage"
            v-bind:message="startUpMessage"
            v-bind:during-congestion-time="automaticDuringCongestionTime"
            v-bind:during-congestion-message="duringCongestionMessage"
            v-bind:queue-count="queueCount"
            v-on:accepted="onAccepted"
            v-on:chat-started="onChatStarted"
            v-on:error="onChatStartError"
        >
        </chat-startup>
        <chat-room v-else-if="isScreen('ChatRoom')"
                   v-bind:connection="connection"
                   v-bind:service-id="serviceId"
                   v-bind:lang-id="langId"
                   v-bind:preview="preview"
                   v-bind:chat-room="chatRoom"
                   v-on:finish="onConfirmFinish"
                   v-on:finished="onFinished"
                   v-on:expired="onExpired"
                   v-on:show-user-info="onShowUserInfo"
                   v-on:show-chat-log-sender="onShowChatLogSender"
                   v-on:heavy-traffic="onHeavyTraffic"
        >
        </chat-room>
        <questionnaire v-else-if="isScreen('Questionnaire')"
                       v-bind:connection="connection"
                       v-bind:service-id="serviceId"
                       v-bind:lang-id="langId"
                       v-bind:preview="preview"
                       v-bind:chat-room="chatRoom"
                       v-on:questionnaire-sent="onQuestionnaireSent"
        >
        </questionnaire>
        <user-info v-else-if="isScreen('UserInfo')"
                   v-bind:connection="connection"
                   v-bind:service-id="serviceId"
                   v-bind:lang-id="langId"
                   v-bind:preview="preview"
                   v-bind:chat-room="chatRoom"
                   v-on:close="onUserInfoClosed"
        >
        </user-info>
        <chat-log-sender v-else-if="isScreen('ChatLogSender')"
                         v-bind:connection="connection"
                         v-bind:service-id="serviceId"
                         v-bind:lang-id="langId"
                         v-bind:preview="preview"
                         v-bind:chat-room="chatRoom"
                         v-on:close="onChatLogSenderClosed"
        >
        </chat-log-sender>
        <exit-confirm v-else-if="isScreen('ExitConfirm')"
                      v-bind:connection="connection"
                      v-bind:service-id="serviceId"
                      v-bind:lang-id="langId"
                      v-bind:preview="preview"
                      v-bind:chat-room="chatRoom"
                      v-on:finished="onFinished"
                      v-on:cancel="onCancelFinish"
        ></exit-confirm>
        <div v-else class="ui_chat_invalid_message" v-html="treatStatusMessage">
        </div>
        <audio id="js-new_arrival_message" src="https://chatbotserv.com/sound/ユーザ受信音.mp3" preload="metadata"></audio>
    </div>
</template>

<script>
module.exports = {
    name: "ChatBody",
    props: [
        "service-id", "lang-id", "preview", 'is-show',
    ],
    components: {
        'chat-startup': httpVueLoader('https://chatbotserv.com/client/chatvue/chatstartup/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
        'chat-room': httpVueLoader('https://chatbotserv.com/client/chatvue/chatroom/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
        'questionnaire': httpVueLoader('https://chatbotserv.com/client/chatvue/questionnaire/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
        'user-info': httpVueLoader('https://chatbotserv.com/client/chatvue/userinfo/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
        'chat-log-sender': httpVueLoader('https://chatbotserv.com/client/chatvue/chatlogsender/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
        'exit-confirm': httpVueLoader('https://chatbotserv.com/client/chatvue/exitconfirm/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1'),
    },
    data: function() {
        return {
            screen: '',
            connection: null,
            email: null,
            userName: null,
            userId: null,
            initialChatMessage: null,
            startUpMessage: null,
            initialEmail: null,
            initialUserName: null,
            initialUserId: null,
            chatRoom: null,
            statusMessage: `Chat&#x6E96;&#x5099;&#x4E2D;...`,  // [Message] 準備中...
            automaticDuringCongestionTime: 0,
            duringCongestionMessage: '',
            chatRoomId: null,
            queueCount: 0,
            visibilityType: null,
            isVisibility: false,
        }
    },
    created: function() {
        let visibilityChange;
        if (typeof document.hidden !== "undefined") {
          this.visibilityType = "hidden";
          visibilityChange = "visibilitychange";
        } else if (typeof document.msHidden !== "undefined") {
          this.visibilityType = "msHidden";
          visibilityChange = "msvisibilitychange";
        } else if (typeof document.webkitHidden !== "undefined") {
          this.visibilityType = "webkitHidden";
          visibilityChange = "webkitvisibilitychange";
        }

        document.addEventListener(visibilityChange, this.onVisibilityChange, false);

        this.isVisibility = true;

		if (window.Notification) {
			if (window.Notification.permission === 'denied' || window.Notification.permission === 'default') {
				window.Notification.requestPermission();
			}
		}
    },
    methods: { // 省略形式(アロー関数)だと、内部から呼び出せない
        onVisibilityChange: function () {
            if (document[this.visibilityType]) {
                this.isVisibility = false;
            } else {
                this.isVisibility = true;
            }
        },
        onReconnected: function () {
            this.connection.off('ReceiveMessageFromSupport', this.onReceiveMessageFromSupport);
            this.connection.off('AcceptedOtherChatRoom', this.onAcceptedOtherChatRoom);
            this.connection.on('ReceiveMessageFromSupport', this.onReceiveMessageFromSupport);
            this.connection.on('AcceptedOtherChatRoom', this.onAcceptedOtherChatRoom);
            // 再接続になった時は、ChatRoomに再入室する
            this.checkStatus();
        },
        onDisconnected: function () {
            // disconnectになった場合は自分で再接続して、ChatRoomに再入室する
            this.connection.off('ReceiveMessageFromSupport', this.onReceiveMessageFromSupport);
            this.connection.off('AcceptedOtherChatRoom', this.onAcceptedOtherChatRoom);
            this.connection.start()
                .then(function() {
                    this.connection.on('ReceiveMessageFromSupport', this.onReceiveMessageFromSupport);
                    this.connection.on('AcceptedOtherChatRoom', this.onAcceptedOtherChatRoom);
                    this.checkStatus();
                }.bind(this));
        },
        onChatStarted: function (chat_room_id, queue_count) {
            this.chatRoomId = chat_room_id;
            this.$cookie.set('ChatRoomId', this.chatRoomId);
            this.queueCount = queue_count;
        },
        onChatStartError: function (message) {
            this.screen = '';
            this.statusMessage = message;
        },
        onAcceptedOtherChatRoom: function (data) {
            if (this.chatRoomId !== null && this.chatRoomId !== data.value.chat_room_id) {
                if (this.queueCount > 1) {
                    this.queueCount -= 1;
                }
            }
        },
        onAccepted: function (chat_room) {
            this.chatRoom = chat_room;
            this.screen = 'ChatRoom';
        },
        onConfirmFinish: function (chat_room) {
            this.chatRoom = chat_room;
            this.screen = 'ExitConfirm';
        },
        onCancelFinish: function (data) {
            this.returnChatRoom(data);
        },
        onFinished: function (chat_room) {
            this.chatRoom = chat_room;
            this.screen = 'Questionnaire';
            // cookieからChatRoomIdとChat表示のための情報を削除
            this.$cookie.delete('ChatRoomId');
            this.$cookie.delete('questionnaire_thumbs_down_count');
        },
        onExpired: function (chat_room) {
            this.screen = '';
            this.statusMessage = `Chat&#x306F;&#x7D42;&#x4E86;&#x3057;&#x307E;&#x3057;&#x305F;&#x3002;`; // [Message] Chatが終了したときのメッセージ
            // cookieからChatRoomIdとChat表示のための情報を削除
            this.$cookie.delete('ChatRoomId');
            this.$cookie.delete('questionnaire_thumbs_down_count');
        },
        onQuestionnaireSent: function () {
            this.screen = '';
            this.$emit('chat-finished');
        },
        onShowUserInfo: function () {
            this.screen = 'UserInfo';
        },
        onShowChatLogSender: function () {
            this.screen = 'ChatLogSender';
        },
        onUserInfoClosed: function (data) {
            this.returnChatRoom(data);
        },
        onChatLogSenderClosed: function (data) {
            this.returnChatRoom(data);
        },
        returnChatRoom: function (data) {
            // この時点で新規メッセージがきたり、Chatが終了しているかもしれないので確認
            if (data.value.result) {
                if (data.value.is_block) {
                    this.screen = '';
                    this.setDelayMessage(data);
                } else if (data.value.chat_room !== null) {
                    this.chatRoom = data.value.chat_room;
                    this.screen = 'ChatRoom';
                } else {
                    // 既に閉じている場合は、有効期限切れとして扱う
                    // this.onFinished(this.chatRoom);
                    this.screen = '';
                    this.statusMessage = `Chat&#x306F;&#x7D42;&#x4E86;&#x3057;&#x307E;&#x3057;&#x305F;&#x3002;`; // [Message] Chatが終了したときのメッセージ
                    // cookieからChatRoomIdとChat表示のための情報を削除
                    this.$cookie.delete('ChatRoomId');
                    this.$cookie.delete('questionnaire_thumbs_down_count');
                }
            } else {
                this.screen = '';
                this.statusMessage = data.value.message;
            }
        },
        onHeavyTraffic: function (data) {
            this.screen = '';
            this.setDelayMessage(data);
        },
        onReceiveMessageFromSupport: function () {
            // 新着通知
            this.$emit('new-arrival-message');

            document.getElementById('js-new_arrival_message').play();

            if (!this.isVisibility) {
                // 画面非表示の時のみNotificationで通知
                if (window.Notification) {
                    if (window.Notification.permission !== 'denied' && window.Notification.permission !== 'default') {
                        const icon = 'https://chatbotserv.com/client/chatvue/faceicon/ja/4f391516-6cdf-4ead-a467-0007a7e0bfe1';
                        const notification = new Notification(`GemForex Chat`, {
                            body: `新着メッセージがあります`,
                            icon: icon,
                        });
                        notification.onclick = function () {
                            window.focus();
                        };
                        setTimeout(notification.close.bind(notification), 5000);
                    }
                }
            }
        },
        checkStatus: function () {
            // cookieからChatのUuidを取得して、あれば送信すること（途中のチャットを再開するために）
            const room_id = this.$cookie.get('ChatRoomId');
            this.connection.invoke('CheckStatus', this.serviceId, this.langId, this.preview, room_id,
                    this.initialEmail, this.initialUserName, this.initialUserId, false)
                .then(function(data) {
                    if (data.value.result) {
                        if (data.value.is_block) {
                            this.setDelayMessage(data);
                        } else if (this.isScreen('Questionnaire')) {
                            // 直前までアンケート画面であれば、そのままの状態で表示する
                        } else {
                            if (data.value.chat_room !== null) {
                                if (data.value.chat_room.acceptedById === null) {
                                    // まだChatが受け入れられていない
                                    this.screen = 'Startup';
                                    this.email = data.value.chat_room.email;
                                    this.userName = data.value.chat_room.userName;
                                    this.userId = data.value.chat_room.userId;
                                    this.initialChatMessage = data.value.chat_room.logs[0].contents;
                                    this.startUpMessage = data.value.message;
                                    this.automaticDuringCongestionTime = data.value.settings.automaticDuringCongestionTime;
                                    this.duringCongestionMessage = data.value.settings.duringCongestionMessage;
                                    this.chatRoomId = data.value.chat_room.uuid;
                                    this.queueCount = data.value.queue_count;
                                } else {
                                    // 途中のChatを表示する
                                    this.chatRoom = data.value.chat_room;
                                    if (!this.isScreen('UserInfo') && !this.isScreen('ChatLogSender')) {
                                        this.screen = 'ChatRoom';
                                    }
                                }
                            } else {
                                this.screen = 'Startup';
                            }
                        }
                    } else {
                        this.statusMessage = data.value.message;
                    }
                }.bind(this))
                .catch(function(error) {
                    console.log(error);
                });
        },
        setDelayMessage: function (data) {
            this.statusMessage = data.value.message;
            // 少し置いてから、メッセージを表示する
            setTimeout(function () {
                this.statusMessage = data.value.status_message;
            }.bind(this), 2000);
        },
    },
    computed: {
        isScreen: function () {
            return function (name) {
                return name === this.screen;
            }.bind(this);
        },
        treatStatusMessage: function() {
            if (this.statusMessage.length > 0) {
                let result = this.replaceCustomLinks(this.statusMessage);
                const a_tag_pattern = new RegExp("<a.*?</a>", 'g');
                let a_tags = [];
                for (const match of result.matchAll(a_tag_pattern)) {
                    a_tags.push(match[0]);
                }
                let other_than_a_tag = result.split(/<a.*?<\/a>/g);
                other_than_a_tag = other_than_a_tag.filter(Boolean);    
                for (let i = 0; i < other_than_a_tag.length; i++) {
                    other_than_a_tag[i] = other_than_a_tag[i].replace(/(https?:\/\/[^\s]*)/g, `<a href='$1' target='_blank'>$1</a>`);
                }
                if (a_tags.length === 0) {
                    result = other_than_a_tag[0];
                } else if (result.startsWith(a_tags[0])) {
                    result = a_tags[0];
                    for (let i = 0; i < other_than_a_tag.length; i++) {
                        if (other_than_a_tag[i].length > 0) {
                            result += other_than_a_tag[i];
                        }
                        if (a_tags.length > (i + 1)) {
                            result += a_tags[i + 1];
                        }
                    }
                } else {
                    result = other_than_a_tag[0];
                    for (let i = 0; i < a_tags.length; i++) {
                        result += a_tags[i];
                        if (other_than_a_tag.length > (i + 1)) {
                            result += other_than_a_tag[i + 1];
                        }
                    }
                }
                return result;
            }
            return '';
        },
    },
    watch: {
        isShow: function (val) {
            if (val) {
                // 初回のみコネクション作成
                if (this.connection === null) {
                    setTimeout(function () {
                        if (this.screen === '' && this.statusMessage === `Chat&#x6E96;&#x5099;&#x4E2D;...`) {
                            this.statusMessage = `Chat&#x306E;&#x8868;&#x793A;&#x306B;&#x5931;&#x6557;&#x3057;&#x307E;&#x3057;&#x305F;&#x3002;&#x518D;&#x5EA6;&#x8AAD;&#x307F;&#x8FBC;&#x307F;&#x76F4;&#x3057;&#x3066;&#x304F;&#x3060;&#x3055;&#x3044;&#x3002;`; // [Message] Chatの表示に失敗しました。再度読み込み直してください。
                        }
                    }.bind(this), 5000);

                    // Chat用のコネクション作成
                    this.connection = new signalR.HubConnectionBuilder()
                        .withUrl("https://chatbotserv.com/chathub")
                        .withAutomaticReconnect({
                            nextRetryDelayInMilliseconds: function () {
                                return 5000;
                            },
                        })
                        .build();
                    this.connection.start()
                        .then(function() {
                            this.connection.onclose(this.onDisconnected);
                            this.connection.onreconnected(this.onReconnected);

                            this.connection.on('ReceiveMessageFromSupport', this.onReceiveMessageFromSupport);
                            this.connection.on('AcceptedOtherChatRoom', this.onAcceptedOtherChatRoom);

                            this.checkStatus();
                        }.bind(this));
                }
            }
        },
    },
}
</script>

<style scoped>
.ui_chat_body {
    width: 100%;
    height: 500px;
}
.ui_chat_invalid_message {
    padding: 0 10px;
    margin: 1px 0 1px 0;
    font-size: 1em;
    width: 100%;
    height: 496px;
    background: white;
    text-align: center;

    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;

    box-sizing: border-box;

    white-space: pre-wrap;
}

@media only screen and (max-width: 1024px) {
    .ui_chat_body {
        height: 100% !important;
    }
    .ui_chat_invalid_message {
        height: 100% !important;
    }
}

@media only screen and (max-width: 480px) {
    .ui_chat_body {
        height: 100% !important;
    }
    .ui_chat_invalid_message {
        height: 100% !important;
    }
}
@media only screen and (max-width: 767px) {
    .ui_chat_body {
        height: 100% !important;
    }
    .ui_chat_invalid_message {
        height: 100% !important;
    }
}
@media only screen and (max-width: 1023px) {
    .ui_chat_body {
        height: 100% !important;
    }
    .ui_chat_invalid_message {
        height: 100% !important;
    }
}
</style>