/*  Настройки на компоненте:

    //Наименование компонента (не обязательно)
    model.name = {
      ru: 'Этапы работ',
      kk: 'Жұмыс кезеңдері',
      en: 'Stages of work'
    }

    //список этапов работ (обязательно)
    model.stages = [];

    //добавляем этап с наименованием и кодом процесса (маршрута)
    model.stages.push({
      stageName: {
        ru: 'Этап 1',
        kk: 'Жұмыс 1',
        en: 'Stage 1'
      },
      processCode: 'process_stage_1'
    });
*/

class Timeline {
  constructor(parentContainer) {
    this.parentContainer = parentContainer;
    this.timelineContainer = parentContainer.find('.timeline_container');
    this.timelineTitle = parentContainer.find('.timeline_title');
    this.timelineContent = parentContainer.find('.timeline_content');
    this.active = false;
    this.init();
  }

  getCoords(elem){
    const box = $(elem)[0].getBoundingClientRect();
    const formOffset = view.playerView.container.offset();
    return {
      top: box.bottom - formOffset.top + (box.height / 2),
      left: box.left - formOffset.left - box.width
    };
  }

  getStep(item){
    const step = $('<div>', {class: 'timeline_step'});
    const circle = $('<div>', {class: 'timeline_step_circle'});
    const line = $('<div>', {class: 'timeline_step_line'});
    step.append(circle, line);

    if(item) {
      const {processCode} = item;
      const finishedProcess = this.getFinishedProcesses(this.processes, processCode);
      const notFinishedProcess = this.getNotFinishedProcesses(this.processes, processCode);

      if(finishedProcess.length && notFinishedProcess.length) {
        step.addClass('active');
        this.active = true;
      } else if(notFinishedProcess.length) {
        step.addClass('active');
        this.active = true;
      } else if (finishedProcess.length && !this.active) {
        step.addClass('finished');
      }
    }

    return step;
  }

  createMessage(elem, data) {
    $('.timeline_message').fadeOut(300, function(){
      $(this).remove();
    });

    const coords = this.getCoords(elem);
    const messageBox = $('<div>', {class: 'timeline_message'});
    const content = $('<div>', {class: 'timeline_message_content'});
    const closeButton = $('<button>', {class: 'timeline_message_button_close'});

    messageBox.css({
      'left': `${coords.left}px`,
      'top': `${coords.top}px`
    });

    data.forEach(item => {
      const {title, value} = item;
      const msg = $('<div>', {class: 'timeline_message_item'});
      msg.append(
        `<span class="timeline_message_item_title">${title}</span>`,
        `<span> - </span>`,
        `<span class="timeline_message_item_value">${value}</span>`
      )
      content.append(msg);
    });

    closeButton.text(i18n.tr('Понятно'));

    closeButton.on('click', e => {
      messageBox.fadeOut(300, function(){
        $(this).remove();
      });
    });

    messageBox.append(content, closeButton);
    view.playerView.container.append(messageBox);
  }

  initStepListener(step, item, title){
    const circle = step.find('.timeline_step_circle');

    if(item) {
      const {stageName, processCode} = item;
      const finishedProcess = this.getFinishedProcesses(this.processes, processCode);
      const notFinishedProcess = this.getNotFinishedProcesses(this.processes, processCode);

      const msgData = [];
      msgData.push({title: 'Наименование этапа', value: stageName[AS.OPTIONS.locale]});

      if(finishedProcess.length && !this.active) {
        msgData.push({title: 'Ответственный', value: finishedProcess[0].responsibleUserName || ''});
        msgData.push({title: 'Дата начала этапа', value: finishedProcess[0].started || ''});
        msgData.push({title: 'Дата окончания этапа', value: finishedProcess[0].finished || ''});
        msgData.push({title: 'Завершил этап', value: finishedProcess[0].finishedUser || ''});

        if(['AGREEMENT_ITEM', 'APPROVAL_ITEM', 'ACQUAINTANCE_ITEM'].includes(finishedProcess[0].typeID)) {
          msgData.push({title: 'Результат', value: finishedProcess[0].name || ''});
        }
      } else if (notFinishedProcess.length) {
        msgData.push({title: 'Ответственный', value: notFinishedProcess[0].responsibleUserName || ''});
        msgData.push({title: 'Дата начала этапа', value: notFinishedProcess[0].started || ''});
      }

      circle.attr('title', stageName[AS.OPTIONS.locale]);

      circle.on('click', e => {
        this.createMessage(circle, msgData);
      });

    } else {
      if(title) circle.attr('title', title);
    }

    return;
  }

  render(){
    try {
      const startStage = this.getStep();
      const finishStage = this.getStep();

      startStage.addClass('first');
      finishStage.addClass('last');

      this.initStepListener(startStage, null, i18n.tr('Начало маршрута'));
      this.initStepListener(finishStage, null, i18n.tr('Конец маршрута'));

      if(this.processes.length) {
        startStage.addClass('finished');
        if(this.processesIsFinish(this.processes)) finishStage.addClass('finished');
      }

      this.timelineContent.append(startStage); // Начало маршрута

      // все остальные этапы
      this.stages.forEach(item => {
        const step = this.getStep(item);
        this.timelineContent.append(step);
        this.initStepListener(step, item);
      });

      this.timelineContent.append(finishStage); // Конец маршрута

    } catch (err) {
      console.log(`ERROR Timeline render`, err);
    }
  }

  getNotFinishedProcesses(processes, code) {
    const result = [];
    const search = p => {
      p.forEach(x => {
        if (x.started && !x.finished && x.code == code) result.push(x);
        if (x.subProcesses.length > 0) search(x.subProcesses);
      });
    }
    search(processes);
    return result.sort((a,b) => new Date(b.started) - new Date(a.started));
  }

  getFinishedProcesses(processes, code) {
    const result = [];
    const search = p => {
      p.forEach(x => {
        if (x.finished && x.code == code) result.push(x);
        if (x.subProcesses.length > 0) search(x.subProcesses);
      });
    }
    search(processes);
    return result.sort((a,b) => new Date(b.finished) - new Date(a.finished));
  }

  processesIsFinish(processes) {
    let started = 0;
    let finished = 0;
    const search = p => {
      p.forEach(x => {
        started++;
        if (x.started && x.finished) finished++;
        if (x.subProcesses.length > 0) search(x.subProcesses);
      });
    }
    search(processes);
    return started == finished;
  }

  async init(){
    AS.SERVICES.showWaitWindow();
    $('.timeline_message').remove();

    try {
      const {name = {}, stages, playerModel: {asfDataId}} = model;

      this.timelineTitle.text(name[AS.OPTIONS.locale] || 'Этапы проведения работ');
      this.stages = stages;

      const documentID = await AS.FORMS.ApiUtils.getDocumentIdentifier(asfDataId);
      this.processes = await AS.FORMS.ApiUtils.simpleAsyncGet(`rest/api/workflow/get_execution_process?documentID=${documentID}&locale=${AS.OPTIONS.locale}`);

      this.render();

      AS.SERVICES.hideWaitWindow();
    } catch (err) {
      AS.SERVICES.hideWaitWindow();
      AS.SERVICES.showErrorMessage(err.message);
      this.parentContainer.fadeOut();
      console.log(`ERROR Timeline init`, err);
    }
  }
}

new Timeline(view.container);
