<template>
    <div class="fm d-flex flex-column"
         v-bind:class="{ 'fm-full-screen': fullScreen }">
        <navbar></navbar>
        <div class="fm-body">
            <notification></notification>
            <context-menu></context-menu>
            <modal v-if="showModal"></modal>
            <template v-if="windowsConfig === 1">
                <left-manager class="col"
                              manager="left"></left-manager>
            </template>
            <template v-else-if="windowsConfig === 2">
                <folder-tree class="col-4 col-md-3"></folder-tree>
                <left-manager class="col-8 col-md-9"
                              manager="left"></left-manager>
            </template>
            <template v-else-if="windowsConfig === 3">
                <left-manager class="col-12 col-sm-6"
                              manager="left"
                              v-on:click.native="selectManager('left')"
                              v-on:contextmenu.native="selectManager('left')">
                </left-manager>
                <right-manager class="col-12 col-sm-6"
                               manager="right"
                               v-on:click.native="selectManager('right')"
                               v-on:contextmenu.native="selectManager('right')">
                </right-manager>
            </template>
        </div>
        <info-block></info-block>
    </div>
</template>

<script>
/* eslint-disable import/no-duplicates, no-param-reassign */
import { mapState } from 'vuex';
// Axios
import HTTP from './http/axios';
import EventBus from './eventBus';
// Components
import Navbar from './components/blocks/Navbar.vue';
import FolderTree from './components/tree/FolderTree.vue';
import LeftManager from './components/manager/Manager.vue';
import RightManager from './components/manager/Manager.vue';
import Modal from './components/modals/Modal.vue';
import InfoBlock from './components/blocks/InfoBlock.vue';
import ContextMenu from './components/blocks/ContextMenu.vue';
import Notification from './components/blocks/Notification.vue';

export default {
    name: 'FileManager',
    components: {
        Navbar,
        FolderTree,
        LeftManager,
        RightManager,
        Modal,
        InfoBlock,
        ContextMenu,
        Notification,
    },
    computed: {
        ...mapState('fm', {
            windowsConfig: state => state.settings.windowsConfig,
            activeManager: state => state.settings.activeManager,
            showModal: state => state.modal.showModal,
            fullScreen: state => state.settings.fullScreen,
        }),
    },
    created() {
        // initiate Axios settings - baseUrl and headers
        this.$store.commit('fm/settings/initAxiosSettings');

        // add axios request interceptor
        this.requestInterceptor();

        // add axios response interceptor
        this.responseInterceptor();

        // initialize app settings
        this.$store.dispatch('fm/initializeApp');

        /**
         * todo Keyboard event
         */
        /*
        window.addEventListener('keyup', (event) => {
          event.preventDefault();
          event.stopPropagation();
    
          EventBus.$emit('keyMonitor', event);
        });
        */
    },
    methods: {
        /**
         * Add axios request interceptor
         */
        requestInterceptor() {
            HTTP.interceptors.request.use((config) => {
                // overwrite base url
                config.baseURL = this.$store.getters['fm/settings/baseUrl'];

                // overwrite headers
                config.headers = this.$store.getters['fm/settings/headers'];

                // loading spinner +
                this.$store.commit('fm/messages/addLoading');

                return config;
            }, (error) => {
                // loading spinner -
                this.$store.commit('fm/messages/subtractLoading');
                // Do something with request error
                return Promise.reject(error);
            });
        },

        /**
         * Add axios response interceptor
         */
        responseInterceptor() {
            HTTP.interceptors.response.use((response) => {
                // loading spinner -
                this.$store.commit('fm/messages/subtractLoading');

                // create notification, if find message text
                if (Object.prototype.hasOwnProperty.call(response.data, 'result')) {
                    if (response.data.result.message) {
                        // show notification
                        EventBus.$emit('addNotification', response.data.result);

                        // set action result
                        this.$store.commit('fm/messages/setActionResult', response.data.result);
                    }
                }

                return response;
            }, (error) => {
                // loading spinner -
                this.$store.commit('fm/messages/subtractLoading');

                // set error message
                this.$store.commit('fm/messages/setError', error);

                const errorMessage = {
                    status: 'error',
                    message: '',
                };

                // add message
                if (error.response) {
                    errorMessage.message = error.response.data.message || error.response.statusText;
                } else if (error.request) {
                    errorMessage.message = error.request.statusText || 'Network error';
                } else {
                    errorMessage.message = error.message;
                }

                // show notification
                EventBus.$emit('addNotification', errorMessage);

                return Promise.reject(error);
            });
        },

        /**
         * Select manager (when shown 2 file manager windows)
         * @param managerName
         */
        selectManager(managerName) {
            if (this.activeManager !== managerName) {
                this.$store.commit('fm/setActiveManager', managerName);
            }
        },
    },
};
</script>