<template>
  <div :class="{'questions--chat': isChat, 'questions--loading': loading}">
    <div v-show="nodes.length" class="questions__items">
      <ul v-for="(node, index) in nodes" :key="index">
        <li>
          <comment v-if="! node.deactivated_at" :comment="node" :controller="controller" v-on:remove="remove"></comment>
        </li>
      </ul>
    </div>
    <comment-form v-if="$root.store.user.id && ! replyTo" :controller="controller"></comment-form>
  </div>
</template>

<script type="text/javascript">
    import Comment from './Comment';
    import CommentForm from './CommentForm';
    import {api} from "../js/modules/api";

    export default {
        name: 'comments',
        props: ['objType', 'objId', 'isChat'],
        data() {
            return {
                loading: false,
                replyTo: null,
                nodes: [],
                controller: this,
                flatComments: {},
            }
        },
        methods: {
            reply(comment) {
                this.replyTo = comment;
            },
            cancelReply(){
                this.replyTo = null;
            },
            addHeart(){
                this.add('❤');
            },
            add(content){
                let vm = this;
                this.loading = true;
                let request = api.addObjComment(this.objId, this.objType, {
                    content: content,
                    author: this.$root.store.user.id,
                    parent: this.replyTo && this.replyTo.id,
                });
                request.then((response) => {
                    vm.loading = false;
                    vm.onAdd(response.data);
                    if(vm.replyTo){
                        vm.cancelReply();
                    }
                }).catch(() => {
                    vm.loading = false;
                });
            },
            remove(comment){
                if(! confirm('Удалить комментарий?')){
                    return;
                }
                let vm = this;
                this.loading = true;
                let request = api.removeObjComment(comment.id);
                request.then((response) => {
                    vm.loading = false;
                    vm.onRemove(comment);
                });
            },
            onAdd(comment){
                if(this.flatComments[comment.id]){
                    return;
                }
                const method = this.isChat ? 'push' : 'unshift';
                if(comment.parent){
                    this.flatComments[comment.parent].children[method](comment);
                }
                else{
                    this.nodes[method](comment);
                }
                this.flatComments[comment.id] = comment;
            },
            onRemove(comment){
                let comments = [];
                if(comment.parent){
                    comments = this.flatComments[comment.parent].children;
                }
                else{
                    comments = this.nodes;
                }
                let index = comments.findIndex((c) => +c.id === +comment.id);
                if(index === -1){
                    return;
                }
                comments.splice(index, 1);
                delete this.flatComments[comment.id];
            },
            connectToPusher(){
                let vm = this;
                // Enable pusher logging - don't include this in production
                Pusher.logToConsole = true;

                let pusher = new Pusher(this.$root.store.pusherKey, {
                  cluster: 'eu',
                  encrypted: true
                });

                let channel = pusher.subscribe('comments_' + this.objType + '_' + this.objId);
                channel.bind('add', this.onAdd);
                channel.bind('delete', this.onRemove);
            }
        },
        mounted() {
            let vm = this;
            this.loading = true;
            let request = api.getObjComments(this.objId, this.objType, this.isChat ? 'update_at' : '-update_at');
            request
                .then((response) => {
                    vm.loading = false;
                    vm.nodes = response.data;
                    vm.connectToPusher();
                })
                .catch(() => {
                    vm.loading = false;
                });
        },
        components: {
            Comment,
            CommentForm
        }
    }
</script>

