const isShowRoute = (registryRoute) => {
  if(registryRoute && registryRoute.hasOwnProperty('before')) {
    if(registryRoute.action.showOnSave == 'true') return true;
    if(registryRoute.after.showOnSave == 'true') return true;
    if(registryRoute.before.showOnSave == 'true') return true;
    return false;
  }
  return false;
}

const parseRouteData = data => {
  const normalizeItems = items =>
  items
  .filter(item => Array.isArray(item.users) && item.users.length > 0)
  .map(item => ({
    ...item,
    users: item.users.map(({ userName, ...rest }) => rest)
  }));

  const result = {
    before: {
      routeID: data.before.routeID,
      items: normalizeItems(data.before.items)
    },
    after: {
      routeID: data.after.routeID,
      items: normalizeItems(data.after.items)
    }
  };

  return JSON.stringify(result);
};

const checkErrors = route => {
  const errors = [];

  const checkBlock = block => {
    if (block?.showOnSave !== "true") return;

    block.items?.forEach(item => {
      item.users?.forEach(proc => {
        if (!proc.userID) {
          errors.push({errorMessage: 'Не выбран ответственный', itemID: proc.itemID});
        }
      });
    });
  };

  checkBlock(route.before);
  checkBlock(route.after);

  return errors.length ? errors : null;
};


const routeNames = {
  "ASSIGNMENT_ITEM": "Работа",
  "AGREEMENT_ITEM": "Согласование",
  "APPROVAL_ITEM": "Утверждение",
  "ACQUAINTANCE_ITEM": "Ознакомление",
  "SEND_DOCUMENT": "Отправка документа",
  "BLOCKING_PROCESS": "Блокирующий процесс",
  "COMMON_PROCESS_BY_FORM": "Работа по форме",
  "REGISTRATION_ITEM": "Регистрация",
  "RESOLUTION_ACTION": "Резолюция"
}

const getRouteName = routeType =>  i18n.tr(routeNames[routeType]) || routeType;

const createUserParamBlock = (label, routeUserItem, itemContainer, panelType) => {
  const fc = $('<div>', {class: 'uk-form-controls'});
  const button = $('<a class="uk-form-icon uk-form-icon-flip" href="javascript:void(0);" uk-icon="icon: users"></a>');
  const input = $('<input class="uk-input" type="text" disabled>');
  const values = routeUserItem.userID !== '' ? [{personID: routeUserItem.userID, personName: routeUserItem.userName}] : null;

  if(panelType == '_action') {
    button.attr('disabled', true);
    button.css('cursor', 'default');
  } else {
    input.css('background', '#fff');
  }

  fc.append($('<div class="uk-inline uk-width-expand">').append(button, input));

  if(values) {
    const userNames = values.map(x => x.personName).join('; ');
    input.val(userNames).attr('title', userNames);
  }

  button.on('click', e => {
    e.preventDefault();

    if(panelType == '_action') return;

    //(values, multiSelectable, isGroupSelectable, showWithoutPosition, filterPositionID, filterDepartmentID, locale, handler)
    AS.SERVICES.showUserChooserDialog(values, false, false, false, null, null, AS.OPTIONS.locale, users => {
      const userNames = users.map(x => x.personName).join('; ');
      input.val(userNames).attr('title', userNames);
      const selectUser = users[0];
      routeUserItem.userID = selectUser.personID;
      routeUserItem.userName = selectUser.personName;
      itemContainer.find('[item-role="route_user_name"]').text(userNames);
      itemContainer.removeClass('uk-form-danger');
    });
  });

  return $('<div>', {class: 'uk-margin-small'}).append(`<label class="uk-form-label uk-text-bold">${label}</label>`).append(fc);
}

this.StartRegistryRoute = class {
  constructor(_doc) {
    this._doc = _doc;
    this.panelSettingsIsShow = false;

    this.init();
  }

  async startRoute() {
    Cons.showLoader();
    try {
      const param = new URLSearchParams();

      param.append("data", parseRouteData(this.registryRoute));
      param.append("dataUUID", this.dataUUID);
      param.append("documentID", this.documentID);
      param.append("registryID", this.registryInfo.registryID);
      param.append("subject", this.documentName);
      param.append("type", "ACTIVATE");

      const {login, password} = Cons.creds;
      const url = `../Synergy/rest/api/registry/route/start?locale=${AS.OPTIONS.locale}`;
      const headers = new Headers();
      headers.append("Authorization", "Basic " + btoa(unescape(encodeURIComponent(`${login}:${password}`))));
      headers.append("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
      const response = await fetch(url, {method: 'POST', headers, body: param});

      if(!response.ok) throw new Error(await response.text());

      const result = await response.json();
      if(result.hasOwnProperty('errorCode') && result.errorCode != 0) throw new Error(result.errorMessage);

      Cons.hideLoader();

      
      if(isShowRoute(this.registryRoute)) this.closeDialog();
      if(this.registryRoute.closeAfterActivation === "true") this.closeDocument(this._doc);

    } catch (err) {
      Cons.hideLoader();
      UIkit.notification.closeAll();
      showMessage(i18n.tr(err.message), 'error');
      console.log(err);
    }
  }

  addRouteItem() {
    const container = $(`.routes_group_content[panel-type="${this.panelTypeSelected}"]`);
    console.log('addRouteItem', container);
    showMessage(i18n.tr('Функционал в разработке'), 'info');
  }

  showHidePanelSettings(value){
    this.panelSettingsIsShow = value;
    if(this.panelSettingsIsShow) {
      this.routeContent.addClass('panel_settings_visible');
      this.panelSettings.addClass('panel_settings_visible');
      $('.route_dialog_sub_header > a:nth-child(2)').attr('uk-icon', 'chevron-double-right');
    } else {
      this.routeContent.removeClass('panel_settings_visible');
      this.panelSettings.removeClass('panel_settings_visible');
      $('.route_dialog_sub_header > a:nth-child(2)').attr('uk-icon', 'chevron-double-left');
    }
  }

  addPanelGroupHandler(panels){
    panels.forEach(panel => {
      panel.on('click', e => {
        this.panelTypeSelected = panel.attr('panel-type');
        panels.map(x => x.removeClass('selected'));
        panel.addClass('selected');

        if(this.panelTypeSelected == '_action') {
          $('.route_dialog_sub_header > a:nth-child(1)').attr('disabled', true);
        } else {
          $('.route_dialog_sub_header > a:nth-child(1)').attr('disabled', false);
        }
      });
    });
  }

  renderSettings(item, itemContainer, panelType){
    this.showHidePanelSettings(true);

    this.panelSettings.empty();

    const userBlock = createUserParamBlock(i18n.tr('Ответственный'), item, itemContainer, panelType);
    this.panelSettings.append(userBlock);
  }

  renderRouteItem(index, panel, panelType, item) {
    const {itemID, users} = item;

    users.forEach((proc, i) => {
      const itemContainer = $('<div>', {class: 'route_item_container', itemid: itemID, itemindex: index});
      const panelTop = $('<div>', {class: 'route_item_panel_top'});
      const panelBottom = $('<div>', {class: 'route_item_panel_bottom'});
      const routeName = getRouteName(proc.typeID);

      const deleteItemButton = $('<span>', {class: 'delete_item_route_button', 'uk-icon': 'trash'});

      panelTop.append(
        `<span item-role="route_index" style="font-weight: bold;">${index + 1}</span>`,
        `<span>-</span>`,
        `<span item-role="route_name">${routeName}</span>`
      );

      if(panelType !== '_action' && proc.typeID !== 'BLOCKING_PROCESS'){
        panelTop.append(
          '<span item-role="route_user_icon" uk-icon="user"></span>',
          `<span item-role="route_user_name" style="font-weight: bold;">${proc.userName}</span>`,
          `<span>-</span>`,
          `<span item-role="route_duration">${Math.round(proc.length)} ${proc.lengthType == "HOURS" ? 'ч' : 'дн'}</span>`
        );
      }

      panelBottom.text(proc.name);

      itemContainer.on('click', e => {
        e.preventDefault();
        if($(e.target).closest('span').hasClass("delete_item_route_button")) return;
        this.renderSettings(proc, itemContainer, panelType);
        $('.route_item_container').removeClass('selected');
        itemContainer.addClass('selected');
      });

      itemContainer.hover(() => {
        const $group = $(`.route_item_container[itemid="${itemID}"]`);

        if ($group.length < 2) return;
        $group.addClass('is-linked');
        $group.first().addClass('is-first');
        $group.last().addClass('is-last');

      }, () => {
        $(`[itemid="${itemID}"]`).removeClass('is-linked is-first is-last');
      });

      deleteItemButton.on('click', e => {
        e.preventDefault();
        if (window.confirm(i18n.tr('Вы действительно хотите удалить данный этап?'))) {
          itemContainer.remove();

          const idx = users.indexOf(proc);
          if (idx !== -1) users.splice(idx, 1);

          this.reRenderRouteItem(panel, panelType);

          this.showHidePanelSettings(false);
          this.panelSettings.empty();
        }
      });

      if(panelType == '_action') {
        itemContainer.append(panelTop, panelBottom);
      } else {
        itemContainer.append(panelTop, panelBottom, deleteItemButton);
      }

      itemContainer.prepend('<div class="line"></div>');

      panel.append(itemContainer);
    });

  }

  reRenderRouteItem(panel, panelType){
    const {action, after, before} = this.registryRoute;
    const data = panelType == '_before' ? before : panelType == '_after' ? after : action;

    if(data.showOnSave === "true"){
      panel.empty();
      data.items.forEach((item, i) => this.renderRouteItem(i, panel, panelType, item));
    }
  }

  renderRouteItems(panels){
    const {action, after, before} = this.registryRoute;

    panels.forEach(panel => {
      const panelType = panel.attr('panel-type');
      const data = panelType == '_before' ? before : panelType == '_after' ? after : action;
      
      if(data.showOnSave === "true"){
        data.items.forEach((item, i) => this.renderRouteItem(i, panel, panelType, item));
      }

    });
  }

  closeDialog(){
    this.dialogContainer.fadeOut(300, function(){
      $( this ).remove();
    });
  }

  openEditRouteDialog(){
    const {action, after, before} = this.registryRoute;

    this.dialogContainer = $('<div>', {class: 'route_dialog_container'});
    const header = $('<div>', {class: 'route_dialog_header'});
    const subHeader = $('<div>', {class: 'route_dialog_sub_header'});
    const body = $('<div>', {class: 'route_dialog_body'});
    const footer = $('<div>', {class: 'route_dialog_footer'});

    this.routeContent = $('<div>', {class: 'route_dialog_body_content'}); //список этапов
    this.panelSettings = $('<div>', {class: 'route_dialog_body_settings'}); //найстройка этапа маршрута

    const panelAction = $('<div>', {class: 'route_dialog_panel_routes_group', 'panel-type': '_action'}); //Действия
    const panelAfter = $('<div>', {class: 'route_dialog_panel_routes_group', 'panel-type': '_after'}); //Последующие этапы
    const panelBefore = $('<div>', {class: 'route_dialog_panel_routes_group', 'panel-type': '_before'}); //Предварительные этапы

    const routesGroupeHeaderAction = $(`<h5 class="routes_group_header">${i18n.tr('Действия')}</h5>`);
    const routesGroupeHeaderAfter = $(`<h5 class="routes_group_header">${i18n.tr('Последующие этапы')}</h5>`);
    const routesGroupeHeaderBefore = $(`<h5 class="routes_group_header">${i18n.tr('Предварительные этапы')}</h5>`);

    const routesGroupeContentAction = $('<div>', {class: 'routes_group_content', 'panel-type': '_action'});
    const routesGroupeContentAfter = $('<div>', {class: 'routes_group_content', 'panel-type': '_after'});
    const routesGroupeContentBefore = $('<div>', {class: 'routes_group_content', 'panel-type': '_before'});

    const dialogName = $(`<h3>${i18n.tr('Запуск маршрута')} - ${this.registryInfo.name}</h3>`);
    const closeButton = $('<span>', {class: 'route_dialog_close_button', 'uk-icon': 'close'});

    const addItemButton = $(`<a href="" class="uk-icon-button" uk-icon="plus" disabled></a>`);
    const showHideSettingsButton = $(`<a href="" class="uk-icon-button" uk-icon="chevron-double-left"></a>`);

    const buttonStartRoute = $('<button>', {class: 'route_dialog_button uk-button window-action-button fonts window-action-button-green'});
    buttonStartRoute.text(i18n.tr('Запустить'));

    const panels = [];
    const panelsContent = [];

    if(before.showOnSave === "true") {
      panels.push(panelBefore);
      panelsContent.push(routesGroupeContentBefore);
    }
    if(action.showOnSave === "true") {
      panels.push(panelAction);
      panelsContent.push(routesGroupeContentAction);
    }
    if(after.showOnSave === "true") {
      panels.push(panelAfter);
      panelsContent.push(routesGroupeContentAfter);
    }

    this.addPanelGroupHandler(panels);
    this.renderRouteItems(panelsContent);

    addItemButton.on('click', e => {
      e.preventDefault();
      if(addItemButton.attr('disabled')) return;
      this.addRouteItem();
    });
    
    showHideSettingsButton.on('click', e => {
      e.preventDefault();
      this.showHidePanelSettings(!this.panelSettingsIsShow);
    });

    closeButton.on('click', e => {
      e.preventDefault();
      this.closeDialog();
    });

    buttonStartRoute.on('click', e => {
      e.preventDefault();
      const errors = checkErrors(this.registryRoute);

      if(errors) {
        const errMessage = [];

        errors.forEach(err => {
          $(`.route_item_container[itemid="${err.itemID}"]`).addClass('uk-form-danger');
          errMessage.push(err.errorMessage);
        })

        UIkit.notification.closeAll();
        showMessage(errMessage.join('\n'), 'error');

      } else {
        this.startRoute();
      }
      
    });

    subHeader.append(addItemButton, showHideSettingsButton)

    panelAction.append(routesGroupeHeaderAction, routesGroupeContentAction);
    panelAfter.append(routesGroupeHeaderAfter, routesGroupeContentAfter);
    panelBefore.append(routesGroupeHeaderBefore, routesGroupeContentBefore);
    
    if(before.showOnSave === "true") this.routeContent.append(panelBefore);
    if(action.showOnSave === "true") this.routeContent.append(panelAction);
    if(after.showOnSave === "true") this.routeContent.append(panelAfter);

    footer.append(buttonStartRoute);
    body.append(this.routeContent, this.panelSettings);
    header.append(dialogName, closeButton);
    this.dialogContainer.append(header, subHeader, body, footer);
    $('body').append(this.dialogContainer);

    Cons.hideLoader();
  }

  init(){
    try {
      const {registryInfo, registryRoute, documentID, dataUUID, documentName, closeDocument} = this._doc;
      this.registryInfo = registryInfo;
      this.registryRoute = registryRoute;
      this.documentID = documentID;
      this.dataUUID = dataUUID;
      this.documentName = documentName;
      this.closeDocument = closeDocument;

      if(isShowRoute(registryRoute)) {
        this.openEditRouteDialog();
      } else {
        this.startRoute();
      }

    } catch (err) {
      UIkit.notification.closeAll();
      showMessage(i18n.tr(err.message), 'error');
      console.log(err);
    }
  }
}
