<template>
  <div
    class="fm d-flex flex-column"
    v-bind:class="{ 'fm-full-screen': fullScreen }"
  >
    <navbar />
    <div class="fm-body">
      <notification />
      <context-menu />
      <modal v-if="showModal" />
      <template v-if="windowsConfig === 1">
        <left-manager class="col" manager="left" />
      </template>
      <template v-else-if="windowsConfig === 2">
        <folder-tree class="col-4 col-md-3" />
        <left-manager class="col-8 col-md-9" manager="left" />
      </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 />
  </div>
</template>

<script>
import { mapState } from "vuex";
// Axios
import request from "@/utils/axios";
import EventBus from "@/utils/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";
// Mixins
import translate from "@/utils/translate";

export default {
  name: "FileManager",
  mixins: [translate],
  components: {
    Navbar,
    FolderTree,
    LeftManager,
    RightManager,
    Modal,
    InfoBlock,
    ContextMenu,
    Notification,
  },
  data() {
    return {
      interceptorIndex: {
        request: null,
        response: null,
      },
      settings: {
        headers: {
          // axios headers
          "X-Requested-With": "XMLHttpRequest",
          Authorization: `Bearer ${window.sessionStorage.getItem(
            "Authorization"
          )}`,
        },
        baseUrl: "/api/v1/file-manager/", // overwrite base url Axios
        windowsConfig: 2, // overwrite config
        lang: "zh_CN", // set language
      },
    };
  },
  created() {
    // disk and path
    const params = this.$route.params;
    if (params.directory) {
      window.sessionStorage.setItem("DISK_ROOT", params.directory)
    }

    // manual settings
    this.$store.commit("fm/settings/manualSettings", this.settings);

    // initiate Axios
    this.$store.commit("fm/settings/initAxiosSettings");
    this.requestInterceptor();
    this.responseInterceptor();

    // initialize app settings
    this.$store.dispatch("fm/initializeApp", { directory: params.directory });

    /**
     * todo Keyboard event
     */
    /*
    window.addEventListener('keyup', (event) => {
      event.preventDefault();
      event.stopPropagation();

      EventBus.$emit('keyMonitor', event);
    });
    */

  },
  destroyed() {
    // reset state
    this.$store.dispatch("fm/resetState");

    // delete events
    EventBus.$off(["contextMenu", "addNotification"]);

    // eject interceptors
    request.interceptors.request.eject(this.interceptorIndex.request);
    request.interceptors.response.eject(this.interceptorIndex.response);
  },
  computed: {
    ...mapState("fm", {
      windowsConfig: (state) => state.settings.windowsConfig,
      activeManager: (state) => state.settings.activeManager,
      showModal: (state) => state.modal.showModal,
      fullScreen: (state) => state.settings.fullScreen,
    }),
  },
  methods: {
    /**
     * Add axios request interceptor
     */
    requestInterceptor() {
      this.interceptorIndex.request = request.interceptors.request.use(
        (config) => {
          // overwrite base url and headers
          config.baseURL = this.$store.getters["fm/settings/baseUrl"];
          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");
          return Promise.reject(error);
        }
      );
    },

    /**
     * Add axios response interceptor
     */
    responseInterceptor() {
      this.interceptorIndex.response = request.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) {
              const message = {
                status: response.data.result.status,
                message: Object.prototype.hasOwnProperty.call(
                  this.lang.response,
                  response.data.result.message
                )
                  ? this.lang.response[response.data.result.message]
                  : response.data.result.message,
              };

              // show notification
              EventBus.$emit("addNotification", message);

              // set action result
              this.$store.commit("fm/messages/setActionResult", message);
            }
          }

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

          const errorMessage = {
            status: 0,
            message: "",
          };

          const errorNotificationMessage = {
            status: "error",
            message: "",
          };

          // add message
          if (error.response) {
            errorMessage.status = error.response.status;

            if (error.response.data.message) {
              const trMessage = Object.prototype.hasOwnProperty.call(
                this.lang.response,
                error.response.data.message
              )
                ? this.lang.response[error.response.data.message]
                : error.response.data.message;

              errorMessage.message = trMessage;
              errorNotificationMessage.message = trMessage;
            } else {
              errorMessage.message = error.response.statusText;
              errorNotificationMessage.message = error.response.statusText;
            }
          } else if (error.request) {
            errorMessage.status = error.request.status;
            errorMessage.message = error.request.statusText || "Network error";
            errorNotificationMessage.message =
              error.request.statusText || "Network error";
          } else {
            errorMessage.message = error.message;
            errorNotificationMessage.message = error.message;
          }

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

          // show notification
          EventBus.$emit("addNotification", errorNotificationMessage);

          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>

<style scope lang="scss">
@import "~bootstrap/scss/mixins";
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/utilities/sizing.scss";
@import "~bootstrap/scss/utilities/text.scss";
@import "~bootstrap/scss/bootstrap-grid";
@import "~bootstrap/scss/close";
@import "~bootstrap/scss/buttons";
@import "~bootstrap/scss/button-group";
@import "~bootstrap/scss/badge";
@import "~bootstrap/scss/modal";
@import "~bootstrap/scss/tables";
@import "~bootstrap/scss/type";
@import "~plyr/src/sass/plyr.scss";
.fm {
  position: relative;
  height: 100%;
  padding: 1rem 1rem 0;
  background-color: white;

  &:-moz-full-screen {
    background-color: white;
  }

  &:-webkit-full-screen {
    background-color: white;
  }

  &:fullscreen {
    background-color: white;
  }

  .fm-body {
    display: flex;
    height: 100%;
    margin-right: -15px;
    margin-left: -15px;
    position: relative;
    padding-top: 1rem;
    padding-bottom: 1rem;
    border-top: 1px solid #6d757d;
    border-bottom: 1px solid #6d757d;
  }

  .unselectable {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
  }
}

.fm-error {
  color: white;
  background-color: #dc3545;
  border-color: #dc3545;
}

.fm-danger {
  color: #dc3545;
  background-color: white;
  border-color: #dc3545;
}

.fm-warning {
  color: #ffc107;
  background-color: white;
  border-color: #ffc107;
}

.fm-success {
  color: #28a745;
  background-color: white;
  border-color: #28a745;
}

.fm-info {
  color: #17a2b8;
  background-color: white;
  border-color: #17a2b8;
}

.fm.fm-full-screen {
  width: 100%;
  height: 100%;
  padding-bottom: 0;
}
</style>