import axios from 'axios';

import copyContent from '@assets/js/copyContent';
import BaseButton from '@elements/BaseButton/index.vue';
import BaseInput from '@elements/BaseInput/index.vue';
import BaseSelect from '@elements/BaseSelect/index.vue';
import BaseAlert from '@elements/BaseAlert/index.vue';
import BaseModal from '@components/BaseModal/index.vue';

import BaseFile from './BaseFile.vue';
import TheUpload from './TheUpload.vue';
import TheHeader from './TheHeader.vue';

import icons from './icons';

export default {
  name: 'FileManager',
  components: {
    BaseButton,
    BaseInput,
    BaseSelect,
    BaseAlert,
    BaseModal,
    BaseFile,
    TheUpload,
    TheHeader,
  },
  props: {
    maxWidth: {
      type: Number | String,
    },
    maxHeight: {
      type: Number | String,
    },
    minWidth: {
      type: Number | String,
    },
    minHeight: {
      type: Number | String,
    },
    square: {
      type: Boolean,
      default: false,
    },
    showFolderIcons: {
      type: Boolean,
      default: false,
    },
    hideSelection: {
      type: Boolean,
      default: false,
    },
    extensions: {
      type: Array,
      default: () => ['jpg', 'jpeg', 'png', 'pdf'],
    },
  },
  data() {
    return {
      token: '',
      aside: true,

      staticFolders: [
        {
          title: 'Arquivos',
          name: 'arquivos',
          directory: '',
          icon: 'fas fa-file',
          active: false,
        },
      ],
      folders: [],
      files: [],
      icons: icons,
      selectedIcon: '',
      uploadFiles: [],
      activeFolder: {},
      error: {},

      state: 'loading', // initial, upload, loading

      search: '',
      to: '',

      showModal: '', // move-files, rename-files, delete-files, create-folders, delete-folders, rename-folders
      loadingModal: false,

      folderName: '',
      folderNameError: '',

      fileName: '',
      fileNameError: '',

      hasImagetoSend: false,
      disabledSendButton: false,
    };
  },
  computed: {
    listFolders() {
      return [...this.staticFolders, ...this.folders];
    },
    dropdown() {
      let dropdown = [];

      if (this.activeFolder.isFolder) {
        const dropdownItemsFolder = [
          {
            title: 'Renomear pasta',
            click: 'rename-folders',
          },
          {
            title: 'Deletar pasta',
            click: 'delete-folders',
          },
        ];
        dropdown = [...dropdown, ...dropdownItemsFolder];
      }

      if (this.totalSelectedFiles > 0) {
        const dropdownItemsAllFiles = [
          {
            title: `Deletar ${this.labelFileOrFiles}`,
            click: 'delete-files',
            topLine: this.activeFolder.isFolder,
          },
          { title: `Mover ${this.labelFileOrFiles}`, click: 'move-files' },
        ];
        dropdown = [...dropdown, ...dropdownItemsAllFiles];
      }

      if (this.totalSelectedFiles === 1) {
        const dropdownItemsOneFile = [
          { title: 'Renomear arquivo', click: 'rename-files' },
          { title: 'Copiar link do arquivo', click: 'copy-files' },
        ];

        dropdown = [...dropdown, ...dropdownItemsOneFile];
      }

      return dropdown;
    },
    selectedFiles() {
      return this.files.filter(file => file.selected);
    },
    totalSelectedFiles() {
      return this.selectedFiles.length;
    },
    indexSelectedFiles() {
      return this.files.findIndex(filesItem => filesItem.selected);
    },
    labelFileOrFiles() {
      return this.totalSelectedFiles > 1 ? 'arquivos' : 'arquivo';
    },
    listFiles() {
      if (this.activeFolder.name === 'icones') {
        return;
      }

      const filter = this.search.trim().toLowerCase();

      const files = this.files.filter(file => {
        const filename = file.filename.trim().toLowerCase();
        return filename.indexOf(filter) > -1;
      });

      return files;
    },
    listIcons() {
      if (this.activeFolder.name !== 'icones') {
        return;
      }

      const filter = this.search.trim().toLowerCase();

      const filteredIcons = this.icons.filter(icon => {
        const iconName = icon.replace(/^[^-]*-/, '');
        return iconName.indexOf(filter) > -1;
      });

      return filteredIcons;
    },
  },
  created() {
    if (this.showFolderIcons) {
      this.staticFolders.push({
        title: 'Icones',
        name: 'icones',
        directory: '',
        icon: 'fab fa-font-awesome',
        active: false,
      });
    }

    this.token = document.body.dataset.token;
    this.loadFolders();
  },
  methods: {
    handleAsideItem(folderIndex) {
      this.changeFolders(folderIndex);

      if (this.listFolders[folderIndex].name !== 'icones') {
        this.loadFiles();
        return;
      }

      this.state = 'initial';
    },
    handleFolders(folders) {
      const formattedFolders = folders.map(folder => {
        return {
          title: folder.data,
          name: folder.data,
          directory: folder.attributes.directory,
          icon: 'fas fa-folder',
          active: false,
          isFolder: true,
        };
      });

      return [...formattedFolders];
    },
    handleFiles(files) {
      const formattedFiles = files.map(file => {
        file.selected = false;
        return file;
      });

      return [...formattedFiles];
    },
    getFileName() {
      const extension = this.selectedFiles[0].ext;
      const filename = this.selectedFiles[0].filename;

      const name = filename.replace(extension, '');

      return name;
    },
    closeModal() {
      this.showModal = '';
      this.loadingModal = false;

      this.fileName = '';
      this.fileNameError = '';

      this.folderName = '';
      this.folderNameError = '';
    },
    loadFolders() {
      this.changeFolders();

      const method = 'post';
      const { token } = this;
      const url = 'index.php?route=common/filemanager/loadFolders';

      axios({
        method,
        url,
        params: {
          token,
          typefile: 1,
        },
      })
        .then(({ data }) => {
          const { folders, files } = data;
          this.folders = this.handleFolders(folders);
          this.files = this.handleFiles(files);
          this.state = 'initial';
        })
        .catch(() => {})
        .finally(() => {});
    },
    loadFiles() {
      this.files = [];
      this.state = 'loading';

      const formData = new FormData();
      const directory = this.activeFolder.directory;
      formData.append('directory', directory);

      const method = 'post';
      const { token } = this;
      const url = 'index.php?route=common/filemanager/files';

      axios({
        method,
        url,
        data: formData,
        params: {
          token,
          typefile: 1,
        },
      })
        .then(({ data }) => {
          if (directory === this.activeFolder.directory) {
            this.files = this.handleFiles(data);
            this.state = 'initial';
          }
        })
        .catch(() => {})
        .finally(() => {});
    },
    changeFolders(folderIndex = 0) {
      this.listFolders.map(folderItem => {
        folderItem.active = false;
        if (folderItem.isFolder) {
          folderItem.icon = 'fas fa-folder';
        }
      });

      const activeFolder = this.listFolders[folderIndex];
      activeFolder.active = true;
      activeFolder.icon = activeFolder.isFolder ? 'fas fa-folder-open' : activeFolder.icon;

      this.activeFolder = activeFolder;
    },
    renameFolders() {
      if (!this.folderName || this.activeFolder.title === this.folderName) {
        this.closeModal();
        return;
      }

      this.loadingModal = true;

      const method = 'post';
      const { token } = this;
      const url = 'index.php?route=common/filemanager/rename';

      const formData = new FormData();
      formData.append('path', this.activeFolder.directory);
      formData.append('name', this.folderName);

      axios({
        method,
        url,
        data: formData,
        params: {
          token,
          typefile: 1,
        },
      })
        .then(({ data }) => {
          const { success, error, folders, files } = data;
          this.loadingModal = false;

          if (success) {
            this.folders = this.handleFolders(folders);
            this.files = this.handleFiles(files);
            const activeFolderIndex = this.listFolders.findIndex(folderItem => folderItem.name === this.folderName);
            this.changeFolders(activeFolderIndex);
            this.closeModal();
          }

          if (error) {
            this.folderNameError = error;
          }
        })
        .catch(() => {})
        .finally(() => {});
    },
    deleteFolders() {
      this.loadingModal = true;

      const method = 'post';
      const { token } = this;
      const url = 'index.php?route=common/filemanager/delete';

      const formData = new FormData();
      formData.append('path', this.activeFolder.directory);

      axios({
        method,
        url,
        data: formData,
        params: {
          token,
        },
      })
        .then(({ data }) => {
          const { success, folders, files } = data;
          this.loadingModal = false;

          if (success) {
            this.folders = this.handleFolders(folders);
            this.files = this.handleFiles(files);
            this.changeFolders();
            this.closeModal();
          }
        })
        .catch(() => {})
        .finally(() => {});
    },
    createFolders() {
      if (!this.folderName) {
        this.closeModal();
        return;
      }

      this.loadingModal = true;

      const method = 'post';
      const { token } = this;
      const url = `index.php?route=common/filemanager/create`;

      const formData = new FormData();
      formData.append('name', this.folderName);

      axios({
        method,
        url,
        data: formData,
        params: {
          token,
          typefile: 1,
        },
      })
        .then(({ data }) => {
          const { success, error, directories } = data;
          this.loadingModal = false;

          if (success) {
            this.folders = this.handleFolders(directories);
            this.files = [];
            const newFolderIndex = this.listFolders.findIndex(folder => folder.name === this.folderName);
            this.changeFolders(newFolderIndex);
            this.closeModal();
          }

          if (error) {
            this.folderNameError = error;
          }
        })
        .catch(() => {})
        .finally(() => {});
    },
    deleteFiles() {
      this.loadingModal = true;

      const method = 'post';
      const { token } = this;
      const url = 'index.php?route=common/filemanager/deleteFiles';

      const formData = new FormData();
      formData.append('directory', this.activeFolder.directory);
      for (let i = 0; i < this.selectedFiles.length; i++) {
        formData.append('files[]', this.selectedFiles[i].file);
      }

      axios({
        method,
        url,
        data: formData,
        params: {
          token,
        },
      })
        .then(({ data }) => {
          const { success, files } = data;
          this.loadingModal = false;

          if (success) {
            this.files = this.handleFiles(files);
            this.closeModal();
          }
        })
        .catch(() => {})
        .finally(() => {});
    },
    renameFiles() {
      if (!this.fileName || this.fileName === this.getFileName()) {
        this.closeModal();
        return;
      }

      this.loadingModal = true;

      const method = 'post';
      const { token } = this;
      const url = 'index.php?route=common/filemanager/rename';
      const formData = new FormData();
      formData.append('path', this.selectedFiles[0].file);
      formData.append('directory', this.activeFolder.directory);
      formData.append('name', this.fileName);

      axios({
        method,
        url,
        data: formData,
        params: {
          token,
          typefile: 1,
        },
      })
        .then(({ data }) => {
          const { success, error } = data;
          this.loadingModal = false;

          if (success) {
            const { files } = data;
            this.files = this.handleFiles(files);
            this.closeModal();
          }

          if (error) {
            this.fileNameError = error;
          }
        })
        .catch(() => {})
        .finally(() => {});
    },
    moveFiles() {
      const method = 'post';
      const { token } = this;
      const url = 'index.php?route=common/filemanager/move';

      this.loadingModal = true;

      const formData = new FormData();
      formData.append('to', this.to);
      formData.append('directory', this.activeFolder.directory);
      for (let i = 0; i < this.selectedFiles.length; i++) {
        formData.append('from[]', this.selectedFiles[i].file);
      }

      axios({
        method,
        url,
        data: formData,
        params: {
          token,
          typefile: 1,
        },
      })
        .then(({ data }) => {
          const { success, files } = data;
          this.loadingModal = false;

          if (success) {
            this.closeModal();
            this.files = this.handleFiles(files);
          }
        })
        .catch(() => {})
        .finally(() => {});
    },
    useFiles(fileIndex) {
      if (this.hideSelection) {
        return;
      }

      const file = this.files[fileIndex];

      if (
        this.minWidth &&
        this.minHeight &&
        (file.width < Number(this.minWidth) || file.height < Number(this.minHeight))
      ) {
        this.error = {
          type: 'error',
          message: `Dimensões mínima permitida: ${this.minWidth}x${this.minHeight}`,
        };
        return;
      }

      if (
        this.maxWidth &&
        this.maxHeight &&
        (file.width > Number(this.maxWidth) || file.height > Number(this.maxHeight))
      ) {
        this.error = {
          type: 'error',
          message: `Dimensões máxima permitida: ${this.maxWidth}x${this.maxHeight}`,
        };
        return;
      }

      if (this.square && file.width !== file.height) {
        this.error = {
          type: 'error',
          message: 'A imagem deve ser quadrada.',
        };
        return;
      }

      const ensureExtensions = this.extensions.find(extensionsItem => `.${extensionsItem}` === file.ext);
      if (!ensureExtensions) {
        this.error = {
          type: 'error',
          message: `Arquivos permitidos: ${this.extensions.join(', ')}`,
        };
        return;
      }

      this.$emit('close', false);
      this.$emit('file', file);
    },
    copyFiles() {
      const { linkdireto } = this.files.find(file => file.selected);
      copyContent(linkdireto);
    },
    sendFiles() {
      this.state = 'loading';

      const method = 'post';
      const { token } = this;
      const url = 'index.php?route=common/filemanager/sendFiles';

      const formData = new FormData();
      formData.append('directory', this.activeFolder.directory);
      for (let i = 0; i < this.uploadFiles.length; i++) {
        formData.append('files[]', this.uploadFiles[i].file);
        formData.append('names[]', this.uploadFiles[i].name);
      }

      axios({
        method,
        url,
        data: formData,
        params: {
          token,
        },
      })
        .then(({ data }) => {
          const { files } = data;
          this.files = this.handleFiles(files);
          this.state = 'initial';
          this.hasImagetoSend = false;
        })
        .catch(() => {})
        .finally(() => {});
    },
  },
};
