<!--
  - 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 Vue from 'vue';
    import {getUsers} from "~/domains/user/api";
    import OnlineClient from './OnlineClient';
    import UserAvatar from "@/components/user/UserAvatar";

    import { difference } from 'lodash';

    export default {
        components: {
            UserAvatar,
            OnlineClient
        },
        data() {
            return {
                meta: {
                    total: 0,
                    offset: 0,
                    limit: 50
                },
                items: [],
                itemsVisible: 3,
                resolved: {
                    items: []
                },
                userMap: {}
            }
        },
        created() {
            this.authApp = this.$socket.use('/');
            this.authApp.addEventListener('reconnect', this.handleReconnectEvent);
            this.authApp.addEventListener('contactOnline',this.handleOnlineEvent);
            this.authApp.addEventListener('contactOffline',this.handleOfflineEvent);

            this.load().then(r => r);
        },
        mounted() {
            this.itemsVisible = Math.floor(this.$refs.onlineList.clientWidth / 35) - 1;
        },
        computed: {
            ids() {
                return this.items.map(item => item.id);
            },
            resolvedIds() {
                return this.resolved.items.map(item => item.id);
            },

            computedUsersOnline() {
                return this.sortOnlineClients(this.items).slice(0, this.itemsVisible);
            },
            itemsHidden() {
                return this.meta.total - this.itemsVisible;
            }
        },
        methods: {
            handleReconnectEvent() {
                this.items = [];
                this.load().then(r => r);
            },
            handleOfflineEvent(data) {
                const index = this.items.findIndex(client => client.id === data.id);
                if(index !== -1) {
                    this.items.splice(index, 1);
                    this.meta.total--;
                }
            },
            handleOnlineEvent(data) {
                let clientFound = [];

                clientFound = this.items.filter(item => item.id === data.id && item.type === data.type);
                if(clientFound.length === 0) {
                    this.items.push(data);
                    this.meta.total++;
                    this.resolveUsers().then(r => r);
                }

            },

            //---------------------------------------------------------------------------------

            sortOnlineClients(items) {
                return items.sort((a, b) => {
                    if(a.meta.firstSeen === b.meta.firstSeen) {
                        return 0;
                    }

                    return a.meta.firstSeen < b.meta.firstSeen ? -1 : 1;
                });
            },

            //---------------------------------------------------------------------------------

            async load() {
                this.authApp.emit('contactsOnline', {}, (response) => {
                    if(response.success) {
                        const payload = response.data;

                        for(let key in payload.meta) {
                            if(!payload.meta.hasOwnProperty(key)) continue;

                            Vue.set(this.meta, key, payload.meta[key]);
                        }

                        this.items = payload.data.map(user => {
                            user.type = 'user';
                            user.data = undefined;
                            return user;
                        });

                        this.resolveUsers().then(r => r);
                    }
                });
            },

            //---------------------------------------------------------------------------------

            async resolveUsers() {
                const unresolvedUserIds = difference(this.ids, this.resolvedIds);

                if(unresolvedUserIds.length === 0) return;

                try {
                    const response = await getUsers({
                        filter: {
                            id: unresolvedUserIds
                        }
                    });

                    for(let i=0; i<response.data.length; i++) {
                        Vue.set(this.userMap, response.data[i].id, response.data[i]);
                        this.resolved.items.push(response.data[i]);
                    }
                } catch (e) {

                }
            }
        },
        beforeDestroy() {
            this.authApp.removeEventListener('reconnect', this.handleReconnectEvent);
            this.authApp.removeEventListener('contactOnline', this.handleOnlineEvent);
            this.authApp.removeEventListener('contactOffline', this.handleOfflineEvent);
        }
    }
</script>
<template>
    <div class="w-100">
        <div class="d-flex flex-row flex-nowrap justify-content-center align-items-center">
            <div class="">
                <h4 >
                    Kontakte
                </h4>

            </div>
            <div class="ml-auto">

            </div>
        </div>

        <div ref="onlineList" class="d-flex flex-row flex-wrap align-content-around">
            <div v-for="(client,key) in computedUsersOnline" :key="key" style="margin-right: 5px;">
                <online-client :client="client" :users="resolved.items" :user-map="userMap" />
            </div>
            <div v-if="itemsHidden > 0">
                <user-avatar :size="30" :name="itemsHidden.toString()" />
            </div>
        </div>
    </div>
</template>
