<!--
  - Copyright (c) 2022.
  - Author Peter Placzek (tada5hi)
  - For the full copyright and license information,
  - view the LICENSE file that was distributed with this source code.
  -->

<script>
import ChatConnectionStatus from "@/components/chat/connection/ChatConnectionStatus";
export default {
    components: {ChatConnectionStatus},
    props: {
        room: Object,
        socketStatusProperty: {
            type: Object,
            default: undefined
        }
    },
    data() {
        return {
            latency: '?',
            latencyInterval: undefined,

            socketStatus: {
                connecting: false,
                disconnecting: false,
                connected: false,
                error: undefined
            },
        }
    },
    created() {
        if(typeof this.socketStatusProperty !== 'undefined') {
            this.socketStatus = this.socketStatusProperty;
        }

        this.$chat.socket.onAny(this.socketHandler);
        this.calculateLatency();
    },
    beforeDestroy() {
        this.$chat.socket.offAny(this.socketHandler);
        clearInterval(this.latencyInterval);
    },
    methods: {
        async joinSocketRoom() {
            if(this.socketStatus.connecting) return;

            this.socketStatus.connecting = true;
            this.socketStatus.connected = false;
            this.socketStatus.error = undefined;

            this.$emit('updated', this.socketStatus);

            try {
                await this.$chat.joinRoom({
                    id: this.room.id,
                    contactId: this.room.contactId
                });

                this.socketStatus.connected = true;

            }  catch (e) {
                this.socketStatus.error = e.message;
            }

            this.socketStatus.connecting = false;

            this.$emit('updated', this.socketStatus);
        },
        async leaveSocketRoom() {
            if(this.socketStatus.disconnecting) return;

            this.socketStatus.disconnecting = true;
            this.socketStatus.error = undefined;

            this.$emit('updated', this.socketStatus);

            try {
                await this.$chat.leaveRoom(this.room.id);

                this.socketStatus.connected = false;
            }  catch (e) {
                this.socketStatus.error = e.message;
            }

            this.socketStatus.disconnecting = false;
            this.$emit('updated', this.socketStatus);
        },

        calculateLatency() {
            if(typeof this.latencyInterval !== 'undefined') return;

            const handler = () => {
                const start = Date.now();

                // volatile, so the packet will be discarded if the socket is not connected
                this.$chat.socket.volatile.emit("ping", () => {
                    this.latency = (Date.now() - start).toFixed();
                });
            };

            handler();

            this.latencyInterval = setInterval(handler, 5000);
        },

        socketHandler(event, data) {
            switch (event) {
                case 'connectionClose':
                    this.handleSocketConnectionCloseEvent(data);
                    break;
                case 'reconnect':
                    this.handleSocketReconnectEvent();
                    break;
            }
        },

        handleSocketConnectionCloseEvent(data) {
            if(data.payload.id !== this.room.id) return;

            this.socketStatus.connected = false;
            this.socketStatus.connecting = false;
            this.socketStatus.disconnecting = false;
        },
        handleSocketReconnectEvent() {
            this.socketStatus.connected = true;
            this.socketStatus.error = undefined;
            this.socketStatus.connecting = false;
            this.socketStatus.disconnecting = false;
        },
    },
    computed: {
        inTransition() {
            return this.socketStatus.busy || this.socketStatus.connecting || this.socketStatus.disconnecting
        }
    }
}
</script>
<template>
    <div>
        <h6 class="title"><i class="fa fa-signal"></i> Status</h6>

        <chat-connection-status :socket-status="socketStatus" />

        <hr />

        <h6><i class="fa fa-network-wired"></i> Latenz</h6>

        <template v-if="socketStatus.connected">
            <span class="text-success">{{latency}}</span> ms
        </template>
        <template v-else>
            <div class="alert alert-info alert-sm">
                Du bist nicht mit dem Chat verbunden...
            </div>
        </template>

        <hr />

        <button v-if="!socketStatus.connected" type="button" class="btn btn-sm btn-primary" @click.prevent="joinSocketRoom" :disabled="inTransition">
            Verbindung aufbauen
        </button>
        <button v-if="socketStatus.connected" type="button" class="btn btn-sm btn-warning" @click.prevent="leaveSocketRoom" :disabled="inTransition">
            Verbindung trennen
        </button>
    </div>
</template>
