<template>
  <ul class="mc-fileuploader__files">
    <li
      v-for="(file, index) in files"
      :key="`file-${index}`"
      class="mc-fileuploader__file"
      :class="
        checkFileStatus(file)
          ? 'mc-fileuploader__file--is-valid'
          : 'mc-fileuploader__file--is-invalid'
      "
    >
      <span class="mc-fileuploader__file-name">{{ file.name }}</span>
      <span class="mc-fileuploader__file-icon">&nbsp;</span>
      <button
        type="button"
        class="mc-fileuploader__delete"
        :aria-label="removeLabel"
        :disabled="disabled"
        @click="deleteFile(file)"
      ></button>
      <div
        v-if="!checkFileStatus(file)"
        class="mc-fileuploader__file-message"
      >
        <slot :name="`errorMessage${index}`" />
      </div>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'MFileResult',
  inheritAttrs: false,
  props: {
    /**
     * `Array` or `Object` of loaded files
     * {
     *    name: string;
     *    size: number;
     *    valid?: boolean;
     *    errorMessage?: string;
     *  }
     */
    files: {
      type: [Array, Object],
      default: () => [],
    },
    /**
     * Array taking as value a list of allowed file extensions to consider the field as valid
     * @type {['png', 'jpg', 'pdf']}
     */
    allowedExtensions: {
      type: Array,
      default: () => [],
    },
    /**
     * File size in bytes not to be exceeded
     */
    maxSize: {
      type: Number,
      default: null,
    },
    /**
     * Label of the delete button for downloaded files. _(Useful for improving the accessibility of the component)_
     */
    removeLabel: {
      type: String,
      default: '',
    },
    /**
     * Allows to disabled the delete button
     */
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['file-removed', 'has-invalid-files'],
  watch: {
    files: {
      handler: function () {
        const files = Object.values(this.files);
        const invalidFiles = [];

        files.forEach((file, index) => {
          const fileName = file.name;
          const fileSize = file.size;
          const fileErrorMessage = file.errorMessage;
          const fileIsValid = file.valid;
          const validExtension = this.checkFileExtension(fileName);
          const validSize = this.checkFileSize(fileSize);
          const customValidation = fileIsValid !== false;
          let errorType = '';

          if (!validExtension) {
            errorType = 'invalid-extension';
          }

          if (!validSize) {
            errorType = 'invalid-size';
          }

          if (!customValidation) {
            errorType = 'custom-error';
          }

          if (!validExtension || !validSize || !customValidation) {
            invalidFiles.push({
              index: index,
              fileName: fileName,
              fileSize: fileSize,
              errorType: errorType,
              errorMessage: fileErrorMessage,
            });
          }
        });

        if (invalidFiles.length > 0) {
          this.$emit('has-invalid-files', invalidFiles);
        }
      },
      immediate: true,
    },
  },
  methods: {
    deleteFile(file) {
      this.$emit('file-removed', file);
    },
    checkFileExtension(fileName) {
      const allowedExtensions = this.allowedExtensions;

      if (allowedExtensions.length > 0) {
        const extension = fileName.slice(
          ((fileName.lastIndexOf('.') - 1) >>> 0) + 2,
        );

        if (!allowedExtensions.includes(extension)) {
          return false; // invalid
        }
      }

      return true; // valid
    },
    checkFileSize(fileSize) {
      const fileSizeMB = fileSize / 1024 / 1024; // convert default file size from Bytes to Megabytes

      if (this.maxSize && fileSizeMB > this.maxSize) {
        return false; // invalid
      }

      return true; // valid
    },
    checkFileStatus(file) {
      const validExtension = this.checkFileExtension(file.name);
      const validSize = this.checkFileSize(file.size);
      const customValidation = file.valid !== false;

      if (!validExtension || !validSize || !customValidation) {
        return false; // invalid
      }

      return true; // valid
    },
  },
};
</script>

<style lang="scss">
@import 'settings-tools/all-settings';
@import 'components/c.file-uploader';
</style>
