import { Utility } from '../../core/utility';
import { EventManager, EventWrapper, EVENT_TYPE } from '../../lib/event-manager/event-manager';
import './file-input.sass';

const FILE_INPUT_CLASS = 'file-input';
const FILE_INPUT_INITIALIZED_CLASS = 'file-input--initialized';
const FILE_INPUT_LIST_CLASS = 'file-input__list';
const FILE_INPUT_UNPACK_CHECKBOX_CLASS = 'file-input__unpack';
const FILE_INPUT_LABEL_CLASS = 'file-input__label';

@Utility({
  selector: 'input[type="file"][uw-file-input]',
})
export class FileInput {

  _element;
  _app;

  _isMultiFileInput = false;
  _fileList;
  _label;

  _eventManager;

  constructor(element, app) {
    if (!element) {
      throw new Error('FileInput utility cannot be setup without an element!');
    }

    this._element = element;
    this._app = app;

    this._eventManager = new EventManager();

    if (this._element.classList.contains(FILE_INPUT_INITIALIZED_CLASS)) {
      throw new Error('FileInput utility already initialized!');
    }

    // check if is multi-file input
    this._isMultiFileInput = this._element.hasAttribute('multiple');
    if (this._isMultiFileInput) {
      this._fileList = this._createFileList();
    }

    this._label = this._createFileLabel();
    this._updateLabel();

    const changeInputEv = new EventWrapper(EVENT_TYPE.CHANGE,(() => {
      this._updateLabel();
      this._renderFileList();
    }).bind(this), this._element );
    this._eventManager.registerNewListener(changeInputEv);

    // add util class for styling and mark as initialized
    this._element.classList.add(FILE_INPUT_CLASS);
    this._element.classList.add(FILE_INPUT_INITIALIZED_CLASS);
  }

  destroy() {
    this._eventManager.cleanUp();
    this._fileList.remove();
    this._label.remove();
    this._element.classList.remove(FILE_INPUT_INITIALIZED_CLASS);
  }

  _renderFileList() {
    if (!this._fileList) {
      return;
    }

    const files = this._element.files;
    this._fileList.innerHTML = '';
    Array.from(files).forEach((file) => {
      const fileDisplayEl = document.createElement('li');
      fileDisplayEl.innerHTML = file.name;
      this._fileList.appendChild(fileDisplayEl);
    });
  }

  _createFileList() {
    const list = document.createElement('ol');
    list.classList.add(FILE_INPUT_LIST_CLASS);
    const unpackEl = this._element.parentElement.querySelector('.' + FILE_INPUT_UNPACK_CHECKBOX_CLASS);
    if (unpackEl) {
      this._element.parentElement.insertBefore(list, unpackEl);
    } else {
      this._element.parentElement.appendChild(list);
    }
    return list;
  }

  _createFileLabel() {
    const label = document.createElement('label');
    label.classList.add(FILE_INPUT_LABEL_CLASS);
    label.setAttribute('for', this._element.id);
    this._element.parentElement.insertBefore(label, this._element);
    return label;
  }

  _updateLabel() {
    const files = this._element.files;
    if (files && files.length) {
      this._label.innerText = this._isMultiFileInput ? files.length + ' ' + this._app.i18n.get('filesSelected') : files[0].name;
    } else {
      this._label.innerText = this._isMultiFileInput ? this._app.i18n.get('selectFiles') : this._app.i18n.get('selectFile');
    }
  }
}
