
/*
const file = new AttachmentFile(name, uuid, container);
file.open();
*/

const getFileModels = playerModel => {
  const result = [];
  playerModel.models[0].modelBlocks[0].forEach(block => {
    if(block.asfProperty.type === "file") result.push(block);
    if(block.asfProperty.type === "table") {
      if(block.modelBlocks.length > 0) {
        block.modelBlocks.forEach(row => {
          row.forEach(tableBlock => {
            if(tableBlock.asfProperty.type === "file") result.push(tableBlock);
          });
        });
      }
    }
  });
  return result;
}

const initOpenFilesInForm = player => {
  const fileModels = getFileModels(player.model);

  fileModels.forEach(fileModel => {
    const props = fileModel.asfProperty;
    const tmpView = player.view.getViewWithId(props.id, props.ownerTableId, props.tableBlockIndex);

    //отключаем все стандартные события
    setTimeout(() => {
      player.view.container.find(`[data-asformid="file.filename.${props.id}"]`).off();
      fileModel.on('valueChange', () => {
        player.view.container.find(`[data-asformid="file.filename.${props.id}"]`).off();
        return null;
      });
    }, 100);

    //вешаем свое событие
    if(tmpView) {
      tmpView.container.off().on('click', () => {
        if(!fileModel.value) return;
        if(!fileModel.value.hasOwnProperty('identifier')) return;
        const file = new AttachmentFile(fileModel.value.name, fileModel.value.identifier);
        file.open();
      });
    }

  });
}

const initDataLoadPlayer = player => {
  player.model.on('dataLoad', () => {
    initOpenFilesInForm(player);
  });
}

this.AttachmentFile = class {
  constructor(name, uuid, container) {
    this.fullName = name;
    this.identifier = uuid;
    this.container = container;
    this.init();
  }

  textFiles = ['doc', 'docx', 'odt', 'xls', 'xlsx', 'ods', 'rtf', 'pdf', 'txt', 'xml', 'js', 'css'];
  imgFiles = ['jpg', 'jpeg', 'png', 'svg', 'bmp', 'gif'];
  audioFiles = ['wav', 'mp3', 'ogg'];
  videoFiles = ['mp4', 'mpeg', 'avi'];
  mediaFiles = [...this.imgFiles, ...this.audioFiles, ...this.videoFiles];

  async getFileVersions(){
    const headers = [i18n.tr('Дата'), i18n.tr('Автор'), i18n.tr('Длина'), i18n.tr('Комментарий'), i18n.tr('Действие')];
    const table = $('<table>', {class: "uk-table uk-table-small wf-versions-table uk-table-responsive"});
    const thead = $('<thead>');
    const tbody = $('<tbody>');
    const theadTr = $('<tr>');

    headers.forEach(header => theadTr.append(`<th>${header}</th>`));
    thead.append(theadTr);
    table.append(thead).append(tbody);

    const description = await appAPI.getFileDescription(this.identifier);
    if(description && description.hasOwnProperty('versions')) {
      description.versions.forEach(item => {
        const {modified, author, length, comment} = item;
        const tr = $('<tr>');
        tbody.append(tr);

        tr.on('click', e => {
          tbody.find('tr').removeClass('select');
          tr.addClass('select');
        });

        tr.append(
          `<td>${modified}</td>`,
          `<td>${author}</td>`,
          `<td>${i18n.tr('{0} Байт').replace('{0}', length)}</td>`,
          `<td>${comment}</td>`
        );

        const lastTd = $('<td>');

        const buttonDownloadVersion = $('<button>', {class: 'uk-button uk-button-default uk-button-small button-switch pressed'});
        buttonDownloadVersion.text(i18n.tr('Скачать'));
        buttonDownloadVersion.on('click', e => {
          e.preventDefault();
          e.target.blur();
          UTILS.fileDownload(this.fullName, item.identifier);
        });
        lastTd.append(buttonDownloadVersion);

        tr.append(lastTd);
      });
    }

    return table;
  }

  async getContentVersionsFile() {
    const container = $('<div>', {class: 'wf-versions-container'});
    const content = $('<div>', {class: 'wf-versions-content'});
    const button = $('<button>', {class: 'uk-button uk-button-default button-switch wf-button-version'});

    button.text(i18n.tr('Версии'));
    container.append(button, content);

    const table = await this.getFileVersions();
    content.append(table);

    return {container, button, content};
  }

  async canEdit(workInfo) {
    const {docInfo, actionID, has_subprocesses, parent_process} = workInfo;
    const procCode = ['approval-single', 'agreement-single', 'acquaintance-single'];

    if(!docInfo) return false;
    if(docInfo.registered == "true") return false;
    if(procCode.includes(parent_process)) return false;

    if(has_subprocesses == "true") {
      const subworks = await appAPI.getSubworks(actionID);
      const filtered = subworks.filter(x => procCode.includes(x.parent_process));
      if(filtered.length) return false;
    }

    return true;
  }

  async getContentFromForm(asfData) {
    Cons.showLoader();

    const {uuid, version} = asfData;
    const documentID = await AS.FORMS.ApiUtils.getDocumentIdentifier(uuid);
    const docInfo = await appAPI.getDocumentInfo(documentID);

    let workInfo = {};

    if(docInfo.actions.length) workInfo = await appAPI.getWorkInfo(docInfo.actions[0]);

    workInfo.docInfo = docInfo;

    const can_edit = await this.canEdit(workInfo);

    Cons.hideLoader();

    const container = $('<div>', {style: 'width: 100%; overflow: hidden;'});
    if(this.container) {
      container.css('height', '100%');
    } else {
      container.css('height', 'calc(100% - 40px)');
    }

    const buttonsPanel = $('<div>', {class: 'wf-form-buttons-panel'});
    const playerContainer = $('<div>', {class: 'wf-form-player-container'});
    const buttonSave = $('<span class="material-icons wf-icons" style="display: none;">save</span>');
    const buttonPrint = $('<span class="material-icons wf-icons">print</span>');
    const buttonEditable = $('<span class="material-icons wf-icons">edit</span>');

    if(!can_edit) {
      buttonSave.hide();
      buttonEditable.hide();
      this.editable = false;
    } else if (this.editable) {
      buttonEditable.text('description');
      buttonPrint.hide();
      buttonSave.show();
    }

    const player = UTILS.getSynergyPlayer(uuid, this.editable, version);
    player.view.container.css({'background': '#fff'});
    playerContainer.append(player.view.container);

    this.formPlayer = player;

    initDataLoadPlayer(player);

    buttonSave.on('click', e => {
      if(!player.model.hasChanges) return;
      Cons.showLoader();
      if(!player.model.isValid()) {
        showMessage(i18n.tr('Заполните обязательные поля'), 'error');
        Cons.hideLoader();
      } else {
        player.saveFormData(result => {
          showMessage(i18n.tr('Данные сохранены'), 'success');
          Cons.hideLoader();
        });
      }
    });

    buttonPrint.on('click', e => {
      if(player.model.hasPrintable) {
        window.open(`../Synergy/rest/asforms/template/print/form?format=pdf&dataUUID=${uuid}`);
      } else {
        UTILS.printForm(player.view.container[0]);
      }
    });

    buttonEditable.on('click', e => {
      this.editable = !this.editable;
      player.view.setEditable(this.editable);
      if(this.editable) {
        buttonEditable.text('description');
        buttonPrint.hide();
        buttonSave.show();
      } else {
        buttonEditable.text('edit');
        buttonPrint.show();
        if(player.model.hasChanges) {
          buttonSave.show();
        } else {
          buttonSave.hide();
        }
      }
      initDataLoadPlayer(player);
    });

    buttonsPanel.append(
      $('<div>').append(buttonSave, buttonPrint),
      $('<div>').append(buttonEditable)
    );

    const {container: footer, button: buttonVersion, content: contentVersion} = await this.getContentVersionsFile();

    let panelVersion = false;
    buttonVersion.off().on('click', e => {
      e.preventDefault();
      e.target.blur();
      if(panelVersion) {
        playerContainer.css({"height": "calc(100% - 90px)"});
        footer.css({"height": "40px"});
        buttonVersion.removeClass('pressed');
        contentVersion.removeClass('open');
      } else {
        playerContainer.css({"height": "calc(100% - 250px)"});
        footer.css({"height": "250px"});
        buttonVersion.addClass('pressed');
        contentVersion.addClass('open');
      }
      panelVersion = !panelVersion;
    });

    container.append(buttonsPanel, playerContainer, footer);
    return container;
  }

  async getContentFromFile(src) {
    const container = $('<div>', {style: 'width: 100%; overflow: hidden;'});
    if(this.container) {
      container.css('height', '100%');
    } else {
      container.css('height', 'calc(100% - 40px)');
    }

    const iFrame = $(`<iframe id="file-view" src="${src}">`);
    iFrame.css({"width": "100%", "height": "calc(100% - 40px)", "transition": "0.3s"});

    const {container: footer, button: buttonVersion, content: contentVersion} = await this.getContentVersionsFile();

    let panelVersion = false;
    buttonVersion.off().on('click', e => {
      e.preventDefault();
      e.target.blur();
      if(panelVersion) {
        iFrame.css({"height": "calc(100% - 40px)"});
        footer.css({"height": "40px"});
        buttonVersion.removeClass('pressed');
        contentVersion.removeClass('open');
      } else {
        iFrame.css({"height": "calc(100% - 250px)"});
        footer.css({"height": "250px"});
        buttonVersion.addClass('pressed');
        contentVersion.addClass('open');
      }
      panelVersion = !panelVersion;
    });

    container.append(iFrame, footer);
    return container;
  }

  async getContentFromMedia(src) {
    const container = $('<div>', {style: 'width: 100%; overflow: hidden;'});
    if(this.container) {
      container.css('height', '100%');
    } else {
      container.css('height', 'calc(100% - 40px)');
    }

    const body = $(`<div>`);
    body.css({
      "width": "100%",
      "height": "calc(100% - 40px)",
      "overflow": "hidden",
      "display": "flex",
      "justify-content": "center",
      "transition": "0.3s"
    });

    if(this.imgFiles.includes(this.ext)) {
      body.append(`<img src="${src}" alt="" style="object-fit: scale-down; width: 100%; height: 100%;">`);
    } else if (this.audioFiles.includes(this.ext)) {
      body
      .css({"align-items": "center"})
      .append(`
        <audio controls>
          <source src="${src}">
          <a href="${src}">Скачать</a>
        </audio>`);
    } else if (this.videoFiles.includes(this.ext)) {
      body
      .css({"align-items": "center"})
      .append(`
        <video controls="controls" style="width: auto; height: 100%;">
          <source src="${src}">
          <a href="${src}">Скачать</a>
        </video>`);
    }

    const {container: footer, button: buttonVersion, content: contentVersion} = await this.getContentVersionsFile();

    let panelVersion = false;
    buttonVersion.off().on('click', e => {
      e.preventDefault();
      e.target.blur();
      if(panelVersion) {
        body.css({"height": "calc(100% - 40px)"});
        footer.css({"height": "40px"});
        buttonVersion.removeClass('pressed');
        contentVersion.removeClass('open');
      } else {
        body.css({"height": "calc(100% - 250px)"});
        footer.css({"height": "250px"});
        buttonVersion.addClass('pressed');
        contentVersion.addClass('open');
      }
      panelVersion = !panelVersion;
    });

    container.append(body, footer);
    return container;
  }

  async openASForm() {
    Cons.showLoader();
    const asfData = await appAPI.getFile(this.identifier, 'json');
    const body = await this.getContentFromForm(asfData);

    if(this.container) {
      this.container.empty();
      this.container.append(body);
    } else {
      const dialog = UTILS.getFullModalDialog(this.nameWithExt, body);
      UIkit.modal(dialog).show();
      dialog.on('hidden', () => dialog.remove());
    }
    Cons.hideLoader();
  }

  async openPDF() {
    Cons.showLoader();
    const file = await appAPI.getPdfFile(this.identifier);
    if(!file) {
      Cons.hideLoader();
      return;
    }
    const fileUrl = window.URL.createObjectURL(file);
    const body = await this.getContentFromFile(fileUrl, this.identifier);

    if(this.container) {
      this.container.empty();
      this.container.append(body);
    } else {
      const dialog = UTILS.getFullModalDialog(this.fullName, body);
      UIkit.modal(dialog).show();
      dialog.on('hidden', () => dialog.remove());
    }
    Cons.hideLoader();
  }

  async openMedia() {
    Cons.showLoader();
    const file = await appAPI.getFile(this.identifier);
    if(!file) {
      Cons.hideLoader();
      return;
    }
    const fileUrl = window.URL.createObjectURL(file);
    const body = await this.getContentFromMedia(fileUrl);;

    if(this.container) {
      this.container.empty();
      this.container.append(body);
    } else {
      const dialog = UTILS.getFullModalDialog(this.fullName, body);
      UIkit.modal(dialog).show();
      dialog.on('hidden', () => dialog.remove());
    }
    Cons.hideLoader();
  }

  async openDownload() {
    const container = $('<div>', {style: 'width: 100%; overflow: hidden;'});
    if(this.container) {
      container.css('height', '100%');
    } else {
      container.css('height', 'calc(100% - 40px)');
    }

    const body = $('<div>', {class: 'wf-other-file-container'});
    const button = $('<button>', {class: 'uk-button uk-button-primary', style: 'border-radius: 3px;'});
    button.text(i18n.tr('Скачать'));

    body.append(
      `<p>${i18n.tr('Уважаемый {0}!').replace('{0}', UTILS.getCurrentUserFullName())}</p>`,
      `<p>${i18n.tr('Данный файл имеет неизвестный для системы формат, и просмотреть его в браузере не представляется возможным.')}</p>`,
      `<p>${i18n.tr('Вы можете скачать этот файл себе на компьютер и попробовать открыть его.')}</p>`,
      button
    );

    button.on('click', e => {
      e.preventDefault();
      e.target.blur();
      Cons.showLoader();
      UTILS.fileDownload(this.fullName, this.identifier);
      Cons.hideLoader();
    });

    const {container: footer, button: buttonVersion, content: contentVersion} = await this.getContentVersionsFile();

    let panelVersion = false;
    buttonVersion.off().on('click', e => {
      e.preventDefault();
      e.target.blur();
      if(panelVersion) {
        body.css({"height": "calc(100% - 40px)"});
        footer.css({"height": "40px"});
        buttonVersion.removeClass('pressed');
        contentVersion.removeClass('open');
      } else {
        body.css({"height": "calc(100% - 250px)"});
        footer.css({"height": "250px"});
        buttonVersion.addClass('pressed');
        contentVersion.addClass('open');
      }
      panelVersion = !panelVersion;
    });

    container.append(body, footer);

    if(this.container) {
      this.container.empty();
      this.container.append(container);
    } else {
      const dialog = UTILS.getFullModalDialog(this.fullName, container);
      UIkit.modal(dialog).show();
      dialog.on('hidden', () => dialog.remove());
    }
  }

  async open(){
    if(this.ext == 'asfdocx') {
      await this.openASForm();
    } else if (this.textFiles.includes(this.ext)) {
      await this.openPDF();
    } else if (this.mediaFiles.includes(this.ext)) {
      await this.openMedia();
    } else {
      await this.openDownload();
    }
  }

  init(){
    this.ext = this.fullName.substring(this.fullName.lastIndexOf('.') + 1);
    this.nameWithExt = this.fullName.substr(0, this.fullName.lastIndexOf('.'));
  }
}
