<template>
  <div
    class="redesigned-white"
    style="background-color: rgba(53, 126, 172, 0.05)"
  >
    <div class="row details-bar q-px-md q-pt-md">
      <div class="q-pr-xs">
        <q-btn
          class="back-button q-px-xs"
          dense
          icon="pgs-arrow-left"
          size="sm"
          @click="
            returnToParentViews(
              'statements',
              'cards/personal-accounts',
              'cards/statements'
            )
          "
        />
      </div>
      <div>
        <div class="row header-details">
          <div class="col-shrink order-id">
            <span>{{ $t('statements.CommonCard.statement') }}</span>
            <span>
              <q-skeleton v-if="loading" type="text" />
              <template v-else>
                {{ get(model, 'common.orderId') }}
              </template>
            </span>
          </div>
          <div class="col-shrink order-status">
            <q-skeleton
              v-if="loading"
              class="full-height"
              style="width: 170px"
              type="QBadge"
            />
            <span v-else ref="statusRef">
              <reference-book-item
                :dictionary="get(model, 'dictionaries.internal.dictionary')"
                :value="get(model, 'system.status.internal')"
                name="description"
              />
              <q-tooltip>
                <reference-book-item
                  :dictionary="get(model, 'dictionaries.internal.dictionary')"
                  :value="get(model, 'system.status.internal')"
                  name="description"
                />
              </q-tooltip>
            </span>
          </div>
          <div class="col-shrink order-created">
            <span>{{ $t('statements.CommonCard.dateCreate') }}</span>
            <span>
              <q-skeleton v-if="loading" type="text" />
              <template v-else>
                {{ get(model, 'system.startDate') }}
              </template>
            </span>
          </div>
          <div class="col-shrink order-due">
            <span>
              {{ $t('statements.redesignedTranslate.CommonCard.dueDate') }}
              <q-tooltip>
                {{
                  $t('statements.redesignedTranslate.CommonCard.dueDateTooltip')
                }}
              </q-tooltip>
            </span>
            <span>
              <q-skeleton v-if="loading" type="text" />
              <template v-else>
                {{
                  convertDateFromBackendFormat(
                    get(model, 'common.dueDate'),
                    DateFormat.date
                  )
                }}
              </template>
            </span>
          </div>
          <div class="col-grow order-assignee">
            <span>{{ $t('statements.CommonCard.assignee') }}</span>
            <span>
              <q-skeleton v-if="loading" type="text" />
              <template v-else>
                {{ get(model, 'common.assignee.fullName') }}
              </template>
            </span>
          </div>
        </div>
      </div>
      <div style="flex-grow: 1" />
      <div class="action-buttons">
        <div class="row justify-end q-gutter-y-sm">
          <q-skeleton v-if="loading" type="QBtn" />
          <template v-else>
            <div v-for="button in visibleCustomComponents" :key="createUUID()">
              <component
                :is="components[button.componentPath]"
                :key="createUUID()"
                :button-settings="button"
                :common="common"
                :disable="disableAllButtons || button.props.disable"
                :disable-all-buttons="disableAllButtons"
                :model="model"
                :user-task="userTask"
                v-bind="get(button, 'componentProps')"
                @commonModels="upCommonModels"
                @submit="submit"
                @update="update"
              >
                <q-tooltip
                  v-if="
                    !!get(button, 'componentProps.tooltip') || !!button.tooltip
                  "
                >
                  {{ get(button, 'componentProps.tooltip') || button.tooltip }}
                </q-tooltip>
              </component>
            </div>
          </template>
        </div>
      </div>
    </div>
    <div class="row q-px-md q-pb-sm">
      <div class="col">
        <div class="masthead">
          <span class="q-pt-sm q-pb-sm q-pr-sm">
            <q-skeleton v-if="loading" height="26px" />
            <template v-else>
              {{ get(model, 'system.fullName') }}
            </template>
          </span>
          <span class="q-pr-sm">
            <b>Цель:</b>
            <q-skeleton v-if="loading" height="15px" />
            <template v-else>
              {{ goalText }}
            </template>
          </span>
        </div>
      </div>
      <div class="col col-xs-4 col-sm-shrink">
        <div class="row q-py-sm action-buttons justify-end q-gutter-y-sm">
          <q-skeleton v-if="loading" type="QBtn" />
          <template v-else>
            <div v-for="button in visibleActionButtons" :key="createUUID()">
              <!-- Кнопка приостановить -->
              <PauseButton
                v-if="button.id === 'pause'"
                :button="button"
                :disable="disableAllButtons || button.props.disable"
                :listTypesPause="extendDueReasonsList"
              />
              <q-btn
                v-else
                :class="{ hidden: !get(button.props, 'visible', true) }"
                :disable="disableAllButtons || mixProps(button).disable"
                class="q-ml-sm redesignedFullButton"
                no-caps
                outline
                v-bind="omit(mixProps(button), 'disable')"
                v-on="button.actions"
              >
                <q-tooltip
                  v-if="!!get(button, 'props.tooltip') || !!button.tooltip"
                >
                  {{ get(button, 'props.tooltip') || button.tooltip }}
                </q-tooltip>
              </q-btn>
            </div>
          </template>
        </div>
        <div>
          <preorder-info
            v-if="serviceCard.preorder"
            :common="common"
            :model="model"
          />
        </div>
      </div>
    </div>
    <div class="row full-width bordered">
      <div class="col-12">
        <LoaderWithText
          :flag="globLoaderFlag"
          message="Загружаем данные заявления"
        />
        <redesigned-tabs :current-tab="tabs.current" :tabs="tabs.list" dense />
        <q-dialog v-model="showModalChooseCheckRecalc">
          <q-card class="no-shadow" style="max-width: 80vw; width: 700px">
            <q-card-section class="text-h6">
              В данном заявлении уже выполнен расчёт критериев проверки. Хотите
              рассчитать проверки заново?
            </q-card-section>
            <q-card-section>
              В случае согласия все проставленные ручные критерии будут сброшены
            </q-card-section>
            <q-card-section class="full-width flex justify-end">
              <q-btn
                class="q-ml-sm"
                color="primary"
                label="Да"
                @click="
                  showModalChooseCheckRecalc = false;
                  goToReviewDocumentsCheckRecalc();
                "
              />
              <q-btn
                class="q-ml-sm"
                color="primary"
                label="Нет"
                outline
                @click="
                  showModalChooseCheckRecalc = false;
                  goToReviewDocuments();
                "
              />
            </q-card-section>
          </q-card>
        </q-dialog>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.bordered {
  border-top: 1px solid rgba(1, 72, 116, 0.11);
  border-bottom: 1px solid rgba(1, 72, 116, 0.11);
}

.action-buttons {
  font-family: 'Golos UI', sans-serif;
}

.details-bar {
  display: flex;
  flex-flow: row;

  .back-button {
    border: 1px solid rgba(1, 72, 116, 0.18) !important;
    border-radius: 24px !important;
    color: #1491cf !important;
  }
}

.header-details {
  > div {
    overflow-x: hidden;
    font-family: 'Golos Text', sans-serif;
    font-style: normal;
    font-weight: 600;
    font-size: 12px;
    line-height: 16px;
    padding: 0 8px 0px 8px;
    margin-bottom: 8px;

    &.order-id {
      color: rgba(2, 12, 18, 0.58);
      display: flex;
      flex-flow: column;
      span {
        white-space: nowrap;
      }
    }

    &.order-status {
      background: #dddde1;
      display: inline-flex;
      align-items: center;
      text-align: center;
      max-width: 170px;

      span {
        // min-width: 130px;
        // height: 32px;
        border-radius: 2px;
        font-weight: 500;
        letter-spacing: 0.05em;
        font-size: 10px;
        font-style: normal;
        line-height: 12px;
        text-transform: uppercase;
        color: rgba(2, 12, 18, 0.9);
        margin: 2px;
        padding: 2px;

        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2; /* number of lines to show */
        line-clamp: 2;
        -webkit-box-orient: vertical;
      }
    }

    &.order-created,
    &.order-due,
    &.order-assignee {
      display: flex;
      flex-flow: column;
      max-width: 90px;

      span:first-child {
        color: rgba(2, 12, 18, 0.58);
        font-weight: 400;
        line-height: 14px;
      }
      span:not(:first-child) {
        font-weight: 500;
        line-height: 16px;
      }
      span {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }

    &.order-assignee {
      max-width: 200px;
    }
  }
}

.masthead {
  display: flex;
  flex-flow: column;
  span:first-child {
    font-family: 'Golos Text', sans-serif;
    font-style: normal;
    font-weight: 500;
    font-size: 22px;
    line-height: 26px;
    letter-spacing: -0.02em;
    color: rgba(2, 12, 18, 0.9);
  }
  span:last-child {
    font-family: 'Golos UI', sans-serif;
    font-style: normal;
    font-size: 13px;
    line-height: 15px;
    color: rgba(2, 12, 18, 0.9);
  }
}

.Index-Tabs {
  font-family: 'Golos Text', sans-serif;
  font-style: normal;
  font-weight: 500;
  font-size: 10px;
  line-height: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0;
  background: rgba(53, 126, 172, 0.05);
}
.redesignedFullButton {
  background: rgba(25, 164, 233, 0.1) !important;
  border: 1px solid rgba(1, 72, 116, 0.11) !important;
  color: #107abc !important;
  font-family: 'Golos UI', serif !important;
  font-style: normal !important;
  font-weight: 500 !important;
  font-size: 14px !important;
  line-height: 16px !important;
  border-radius: 24px !important;
}
</style>

<script lang="ts">
// @ts-nocheck
import { convertDateFromBackendFormat } from '@utils/format-date';
import { DateFormat } from '@constants/utils/format-date';
import { prepareStatementData } from '@utils/statement-print';
import { Component, Mixins, Prop, Watch } from 'vue-property-decorator';
import ReturnToParentView from '@mixins/ReturnToParentView';
import { Schema } from '@devsun/eva-models';
import { BaseCardCommon } from '@/interfaces';
import { CardNeedToUpdateType } from '@constants/models/Card';
import { USER_SCOPES } from '@constants/entities/Scope';
import { ScopesMode } from '@utils/scopes';
import get from 'lodash/get';
import has from 'lodash/has';
import omit from 'lodash/omit';
import merge from 'lodash/merge';
import isEmpty from 'lodash/isEmpty';
import isEqual from 'lodash/isEqual';
import isArray from 'lodash/isArray';
import { UserTaskListItem, WorkflowServiceApi } from '@openapi/wf';
import { GraphApi } from '@openapi/idm';
import { dispatchStatement } from '@services/document-registry';
import { notifyError, notifySuccess } from '@utils/notify';
import { DocumentTypeOption } from './DialogCommentAndDocuments.vue';
import { v4 as getUUID } from 'uuid';
import { DocumentApi } from '@openapi/document-registry';
// import { MessageEvent, MessageEventData } from '@services/websockets';
import LoaderWithText from '@components/common/loader';
import PreorderInfo from './components/PreorderInfo.vue';
import PauseButton from './PauseButton.vue';

const ACCREDITATION_ID = 'e8dfc145-ca22-4784-82ee-d7da39ab7d67';

const wfApi = new WorkflowServiceApi();
const graphApi = new GraphApi();
const documentApi = new DocumentApi();

function filterDocumentComponentByDialogCommentAndDocuments(
  context: DocumentTypeOption
): boolean {
  return ['MVZ', 'Specialist'].includes(context.data.source);
}

@Component({
  components: {
    LoaderWithText,
    PreorderInfo,
    PauseButton,
  },
  methods: {
    convertDateFromBackendFormat,
    get,
    omit,
  },
})
export default class StatementIndexCard extends Mixins(ReturnToParentView) {
  DateFormat = DateFormat;
  buttons: any[] = [];
  components = null;
  disableAllButtons = false;
  showModalChooseCheckRecalc = false;
  globLoaderFlag = false;
  updates = {};

  @Prop({}) private common?: BaseCardCommon;

  tabs = {
    current: this.common.active,
    list: [],
  };

  @Prop({}) private model?: any;
  @Prop({}) private userTask?: any;

  get outData() {
    return get(this.userTask, 'userTask.outData') || {};
  }

  get actions() {
    return get(this.userTask, 'userTask.outData.actions') || [];
  }

  get extendDueReasonsList() {
    return get(this.userTask, 'userTask.outData.extendDueReasonsList') || [];
  }

  get needRole() {
    return get(this.userTask, 'userTask.outData.needRole') || [];
  }

  get loading() {
    return !this.model && !this.components;
  }

  get commonData() {
    return get(this.common, 'models.index.data', []);
  }

  get goalText() {
    const goal = get(this.model, 'statement.goal');
    const goalsList = this.serviceCard?.goalsList || [];
    const goalEntry = goalsList.find((goalListEntry) => {
      return (
        goalListEntry.value === goal || goalListEntry.value === String(goal)
      );
    });

    return goalEntry && goalEntry.label;
  }

  get showGoal() {
    const isFamChildSub =
      get(this.model, 'serviceCode') === 'familychildsub' ||
      get(this.model, 'servicie') === '3-7';

    const hideGoalByFlag = get(this.model, 'system.hideStatementGoal');

    if (isFamChildSub || hideGoalByFlag) {
      return false;
    }

    return this.goalText;
  }

  get serviceCard() {
    return this.$store.getters['registryService/services/servicesCard'];
  }

  get buttonProperties(): any {
    return this.model?.buttonProperties || {};
  }

  /**
   * Кнопки для отображения
   */
  get visibleActionButtons(): unknown[] {
    if (this.$AC.haveScope(USER_SCOPES.RF_OBSERVER_SCOPE)) return [];
    return this.buttons
      .filter((button) => this.checkButtonVisibility(button))
      .map((button) => ({
        ...button,
        props: this.mixProps(button, 'props'),
      }));
  }

  get visibleCustomComponents(): unknown[] {
    if (this.$AC.haveScope(USER_SCOPES.RF_OBSERVER_SCOPE)) return [];
    return this.buttons
      .filter((button) => this.checkButtonForCustomComponent(button))
      .map((button) => ({
        ...button,
        componentProps: this.mixProps(button, 'componentProps'),
      }));
  }

  get schema(): Schema.MetaClassSchemaRaw {
    return this.$store.getters['utils/cards/getSchemaByPath']('data');
  }

  get authorSchema(): Schema.MetaClassSchemaRaw {
    return this.$store.getters['utils/cards/getSchemaByPath']('authorSchema');
  }

  created() {
    this.init();
  }

  upCommonModels(val) {
    this.$emit('commonModels', val);
  }

  showStatusComponent(button) {
    const byActions =
      !!button.withoutActions || this.actions.includes(button.id);
    const byScopes = this.$AC.haveScopes(button.scopes);
    const byComponent =
      !!button.componentPath &&
      !isEmpty(this.components[button.componentPath]) &&
      button.statusButton;
    const byLoading = !this.loading;
    const bySettings = get(button.props, 'visible', true);

    return byActions && byScopes && byComponent && byLoading && bySettings;
  }

  /**
   * Проверка отображения компонента вместо кнопки
   */
  checkButtonForCustomComponent(button): boolean {
    const byActions =
      !!button.withoutActions || this.actions.includes(button.id);
    const mode = get(button, 'scopesMode', ScopesMode.and);
    const byScopes = this.$AC.haveVisible(button.scopes, mode, ScopesMode.and);
    const byComponent =
      !!button.componentPath &&
      !isEmpty(this.components[button.componentPath]) &&
      !button.statusButton;
    const byLoading = !this.loading;
    const bySettings = get(button.props, 'visible', true);

    return byActions && byScopes && byComponent && byLoading && bySettings;
  }

  /**
   * Проверка видимости кнопки
   */
  checkButtonVisibility(button): boolean {
    const byActions =
      !!button.withoutActions || this.actions.includes(button.id);
    const mode = get(button, 'scopesMode', ScopesMode.and);
    const byScopes = this.$AC.haveVisible(button.scopes, mode, ScopesMode.and);
    const byComponent = !button.componentPath;
    return byActions && byScopes && byComponent;
  }

  checkDocumentSource(document, source) {
    return String(get(document, 'source')).toLowerCase() === source;
  }

  getButtonById(id) {
    return this.buttons.find((button) => button.id === id);
  }

  init(needToUpdateType = CardNeedToUpdateType.TRUE): void {
    this.$q.loading.show({
      message: 'Загружаем данные заявления',
    });
    const initModel = () =>
      this.initModel()
        .then(() => {
          this.initTabsList();
        })
        .finally(() => {
          this.$q.loading.hide();
        });
    const initUserTask = () =>
      this.initUserTask()
        .then(() => {
          this.initButtons();
          this.fetchCards();
        })
        .finally(() => {
          this.$q.loading.hide();
        });
    switch (needToUpdateType) {
      case CardNeedToUpdateType.TRUE: {
        initModel().then(() => {
          initUserTask();
        });
        break;
      }
      case CardNeedToUpdateType.MODEL: {
        initModel();
        break;
      }
      case CardNeedToUpdateType.USER_TASK: {
        initUserTask();
        break;
      }
    }
  }

  async initModel(): Promise<void> {
    const model = await dispatchStatement(
      this.common?.id,
      undefined,
      'payments,paymentsReceived,paymentsReceivedReq,relatives'
    );
    this.$store.commit(`utils/cards/addModel`, {
      model,
      path: this.common?.path,
    });
  }

  initUserTask(): Promise<void> {
    const handler = (tasks: UserTaskListItem[]) => {
      this.$store.commit(`utils/cards/addUserTask`, {
        path: this.common.path,
        userTask: tasks[0],
      });
    };

    return new Promise((resolve, reject) => {
      try {
        const applicationId = get(this.common, 'id');
        const assignee = this.$store.getters['oidcClient/currentUser'].sub;
        const processId = get(this.model, 'system.processId');
        const status = get(this.model, 'system.status.internal');
        wfApi
          .findUserTasks(processId, undefined, assignee)
          .then(({ data: { tasks = [] } }) => {
            if (tasks[0]) {
              handler(tasks);
              return resolve();
            }

            const reqData = {
              applicationId,
              status,
              processId,
            };
            const baseProcess = this.serviceCard?.processes?.find(
              (process) => process.type === 'baseProcess'
            );
            if (baseProcess) {
              reqData.baseProcess = baseProcess;
            }

            wfApi
              .taskListWithResurrect(
                'true',
                undefined,
                undefined,
                undefined,
                assignee,
                processId,
                undefined,
                {
                  data: reqData,
                }
              )
              .then(({ data: { tasks = [] } }) => {
                handler(tasks);
                return resolve();
              })
              .catch((e) => {
                throw e;
              });
          })
          .catch((e) => {
            throw e;
          });
      } catch (e) {
        return reject(e);
      }
    });
  }

  initEmployees() {
    const role = this.needRole;

    this.getButtonById('setAssignee').dialog.data.employees = [];
    this.getButtonById('setAssignee').dialog.data.selectedEmployee = [];
    if (role) {
      const currentUser = this.$store.getters['oidcClient/currentUser'] || {};

      graphApi
        .flatten(
          'Organization',
          'incoming',
          [currentUser.domain_id || null],
          10,
          ['Department,Group,Account'],
          undefined,
          ['Account:roles,Account:person']
        )
        .then(({ data }) => {
          this.getButtonById('setAssignee').dialog.data.employees =
            (Array.isArray(data) &&
              data
                .filter(
                  (employee) =>
                    employee.roles &&
                    employee.roles.map((item) => item.id).includes(role.id)
                )
                .sort((employeeA, employeeB) => {
                  const currentAccountId = currentUser.sub;

                  if (employeeA.id === currentAccountId) {
                    return -1;
                  }
                  if (employeeB.id === currentAccountId) {
                    return 1;
                  }
                  return 0;
                })) ||
            [];
        })
        .catch(() => {
          throw new Error('[components][cards][statements][Index][graphApi]');
        });
    }
  }

  generateMultiRouteButtons() {
    if (!this.serviceCard.ApproveSteps?.length) {
      return [];
    }

    const myOrgRegionCode = get(this, 'model.system.regionCode');
    const currentDepId = get(this, 'model.system.department.id');
    const StepsOrgInfo = this.serviceCard.ApproveSteps.filter(
      (s) => s.regionCode === Number(myOrgRegionCode)
    );
    if (!StepsOrgInfo.length) {
      return [];
    }

    return this.serviceCard.ApproveSteps.filter(
      (step) => step.isDefault !== true
    ).map((step) => ({
      actions: {
        click: () => {
          this.submit({
            buttonId: 'multiRoute',
            data: {
              currentDepId,
              step,
            },
          });
        },
      },
      id: 'multiRoute',
      props: {
        color: 'primary',
        label: step.ButtonLable,
        loading: false,
      },
    }));
  }

  mixProps(
    button: { id: string; props: unknown },
    propsPath = 'props'
  ): unknown {
    const buttonProps = get(button, propsPath);
    const userProps = get(this.userTask, ['userTask', 'outData', 'options', button.id], {});
    console.log(button.id, buttonProps, userProps);
    return {
      ...buttonProps,
      ...userProps,
    };
  }

  initButtons() {
    const isRoutingVisible = () => {
      const hiddenFor = ['accreditationIT'];
      const serviceCode = get(this, 'model.serviceCode');
      if (hiddenFor.includes(serviceCode)) return false;
    };
    const multiRouteButtons = this.generateMultiRouteButtons();

    this.buttons = [
      {
        actions: {
          click: () => {
            this.$recordActivity({
              buttonCode: 'application_appoint_self',
              extraInfo: {
                previewInfo: [
                  {
                    value: this.model?.common?.orderId,
                    label: 'номер',
                  },
                ],
              },
            });
            this.submit({ buttonId: 'takeToWork' });
          },
        },
        id: 'takeToWork',
        props: {
          disable: false,
          label: 'Назначить на себя',
          loading: false,
          icon: 'pgs-user-check',
        },
      },
      {
        id: 'temporaryResult',
        props: {
          color: 'primary',
          disable: false,
          label: 'Промежуточный результат',
          loading: false,
        },
        actions: {
          click: () => {
            this.submit({ buttonId: 'temporaryResult' });
          },
        },
      },
      {
        id: 'temporaryResultAndDocuments',
        props: {
          color: 'primary',
          disable: false,
          loading: false,
          label: 'Промежуточный результат с документами',
        },
        componentPath: 'dialog_comment_and_documents',
        componentProps: {
          filterDocument: filterDocumentComponentByDialogCommentAndDocuments,
        },
      },
      {
        actions: {
          click: () => {
            this.$recordActivity({
              buttonCode: 'application_register_go',
              extraInfo: {
                previewInfo: [
                  {
                    value: this.model?.common?.orderId,
                    label: 'номер',
                  },
                ],
              },
            });
            this.submit({ buttonId: 'goToRegistration' });
          },
        },
        id: 'goToRegistration',
        props: {
          color: 'primary',
          disable: false,
          label: 'Перейти к регистрации',
          loading: false,
        },
      },
      {
        actions: {
          click: () => {
            // Зажурналировать действие
            const goalsList =
              this.$store.getters['registryService/services/servicesCard']
                .goalsList || [];
            const goalValue = String(get(this.model, 'statement.goal') || '');
            const target =
              goalsList?.find((goal) => goal.value === goalValue)?.label || '';
            const idERN =
              this.model.IDERN ||
              get(
                this.model,
                'statement.recruitsData.mainInfo.[0].systemIdErn',
                ''
              );

            this.$recordActivity({
              buttonCode: 'application_register',
              extraInfo: {
                id: this.model?.id,
                type: 'application',
                number: this.model?.common?.orderId,
                idERN,
                fio: this.model?.applicant?.fullName,
                date: get(this.model, 'system.startDate') || '',
                target,
              },
            });
            this.submit({ buttonId: 'register' });
          },
        },
        id: 'register',
        props: {
          color: 'positive',
          disable: this.buttonProperties?.register?.disable || false,
          label: 'Зарегистрировать',
          loading: false,
          tooltip: this.buttonProperties?.register?.disable
            ? 'Регистрация не требуется'
            : '',
        },
      },
      {
        id: 'refuse',
        props: {
          color: 'negative',
          disable: false,
          loading: false,
          label: 'Отказать',
        },
        componentPath: 'document_dialog',
      },
      {
        id: 'extraDataRequired',
        props: {
          color: 'primary',
          disable: false,
          loading: false,
          label: 'Запросить дополнительные сведения',
        },
        componentPath: 'extra_data_required',
      },
      {
        id: 'extraDataRequiredAndDocuments',
        props: {
          color: 'primary',
          disable: false,
          loading: false,
          label: 'Запросить дополнительные сведения с документами',
        },
        componentPath: 'dialog_comment_and_documents',
        componentProps: {
          filterDocument: filterDocumentComponentByDialogCommentAndDocuments,
        },
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'goToCheckCriteria' });
          },
        },
        id: 'goToCheckCriteria',
        props: {
          color: 'primary',
          label: 'Проверка критериев',
          loading: false,
        },
      },
      {
        actions: {
          click: () => {
            if (get(this.model, 'decisionData.objects.length')) {
              this.showModalChooseCheckRecalc = true;
            } else {
              this.submit({
                buttonId: 'goToReviewDocuments',
                data: {
                  manualVerifications: this.commonData,
                },
              });
            }
          },
        },
        id: 'goToReviewDocuments',
        props: {
          color: 'primary',
          disable: false,
          label: 'Рассмотрение документов',
          loading: false,
        },
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'backToReview' });
          },
        },
        id: 'backToReview',
        props: {
          color: 'primary',
          disable: false,
          label: this.$t('statements.CommonCard.bringDocuments'),
          loading: false,
        },
      },
      {
        id: 'updateMZ',
        props: {
          color: 'primary',
          disable: false,
          label: 'Повторный запрос данных СМЭВ',
          loading: false,
        },
        componentPath: 'cross_updating_dialog',
      },
      {
        id: 'addManualVerifications',
        props: {
          visible: false,
          color: 'negative',
          disable: true,
          label: 'Отказать',
          loading: false,
        },
      },
      {
        id: 'preReject',
        props: {
          color: 'negative',
          label: 'Отказать',
          loading: false,
        },
        componentPath: 'pre_reject_dialog',
      },
      {
        id: 'reject',
        props: {
          color: 'negative',
          label: 'Отказать',
          loading: false,
          visible: get(
            this.userTask,
            'userTask.outData.availableDocs.reject',
            []
          ).length,
        },
        componentPath: 'document_dialog',
      },
      {
        id: 'pause',
        actions: {
          click: (pauseType: { id: string; reason: string }) => {
            this.submit({
              buttonId: 'pause',
              data: {
                cause: pauseType,
              },
            });
          },
        },
        props: {
          color: 'primary',
          label: 'Приостановить',
          loading: false,
        },
      },
      {
        id: 'accept',
        props: {
          color: 'positive',
          label: 'Предоставить',
          loading: false,
        },
        componentPath: 'document_dialog',
      },
      {
        id: 'correction',
        props: {
          visible:
            !this.actions.includes('accept') &&
            !this.actions.includes('correctionButtonHide'),
          // Кнопка Предоставить(correction) появлется, если нет accept.
          // Для услуги Беженцы такое поведение некорректно, добавили параметр correctionButtonHide
          // todo проанализировать целевое отображение correction_dialog, возможно оно отображается всегда некорректно
          // то есть условие покажи Предоставить(correction_dialog) если нет Предоставить(document_dialog) неочевидное.
          color: 'positive',
          label: 'Предоставить',
          loading: false,
        },
        componentPath: 'correction_dialog',
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'applicantVisited' });
          },
        },
        id: 'applicantVisited',
        props: {
          color: 'positive',
          disable: false,
          label: 'Заявитель явился',
          loading: false,
        },
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'applicantNotVisited' });
          },
        },
        id: 'applicantNotVisited',
        props: {
          color: 'negative',
          disable: false,
          label: 'Заявитель не явился',
          loading: false,
        },
      },
      {
        actions: {
          click: () => {
            this.$recordActivity({
              buttonCode: 'application_sign_send',
              extraInfo: {
                previewInfo: [
                  {
                    value: this.model?.common?.orderId,
                    label: 'номер',
                  },
                ],
              },
            });
            this.submit({ buttonId: 'confirm' });
          },
        },
        id: 'confirm',
        props: {
          color: 'primary',
          disable: false,
          label: 'Отправить на подписание',
          loading: false,
        },
      },
      {
        id: 'dataChangeRequired',
        props: {
          color: 'primary',
          disable: false,
          label: 'Запрос изменения информации',
          loading: false,
        },
        componentPath: 'dialog_comment_and_documents',
        componentProps: {
          filterDocument: filterDocumentComponentByDialogCommentAndDocuments,
        },
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'refresh' });
          },
        },
        id: 'refresh',
        props: {
          color: 'primary',
          disable: false,
          label: 'Обновление данных для решения',
          loading: false,
        },
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'returnForRevision' });
          },
        },
        id: 'returnForRevision',
        props: {
          color: 'primary',
          disable: false,
          label: 'Вернуть на доработку',
          loading: false,
        },
        scopesMode: ScopesMode.or,
        scopes: [
          USER_SCOPES.SIGNED_SPECIALIST,
          USER_SCOPES.MILITARY_COMMISSAR,
        ],
        componentPath: 'revision_comment',
      },
      {
        id: 'returnForRevision_info',
        props: {
          color: 'grey-8',
          icon: 'o_info',
          disable: false,
          loading: false,
          visible: get(this.model, 'system.status.comment', false),
        },
        scopes: [USER_SCOPES.SIGNED_SPECIALIST],
        tooltip: this.$t('statements.CommonCard.returnForRevisionComment'),
        componentPath: 'revision_comment',
        withoutActions: true,
        statusButton: true,
      },
      {
        id: 'sign',
        props: {
          color: 'primary',
          disable: false,
          label: 'Подписать',
          loading: false,
        },
        scopesMode: ScopesMode.or,
        scopes: [
          USER_SCOPES.SIGNED_SPECIALIST,
          USER_SCOPES.MILITARY_COMMISSAR,
        ],
        componentPath: 'sign_dialog',
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'formPayments' });
          },
        },
        id: 'formPayments',
        props: {
          color: 'primary',
          disable: false,
          label: 'Формирование начисления',
          loading: false,
        },
        callBack: this.setPaymentsTabActive,
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'skipFormPayments' });
          },
        },
        id: 'skipFormPayments',
        props: {
          color: 'primary',
          disable: false,
          label: 'Пропустить формирование начисления',
          loading: false,
        },
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'repeatFormPayments' });
          },
        },
        id: 'repeatFormPayments',
        props: {
          color: 'primary',
          disable: false,
          label: 'Повторное формирование начисления',
          loading: false,
        },
        callBack: this.setPaymentsTabActive,
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'registerPayments' });
          },
        },
        id: 'registerPayments',
        props: {
          color: 'primary',
          disable: false,
          label: 'Зарегистрировать начисление',
          loading: false,
        },
        componentPath: 'charge_approve_dialog',
        scopes: [USER_SCOPES.SPECIALIST],
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'reformPayments' });
          },
        },
        id: 'reformPayments',
        props: {
          color: 'primary',
          disable: false,
          label: 'Переформировать начисление',
          loading: false,
        },
        callBack: this.setPaymentsTabActive,
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'sendPayments' });
          },
        },
        id: 'sendPayments',
        props: {
          color: 'primary',
          disable: false,
          label: 'Отправить начисление заявителю',
          loading: false,
        },
        scopes: [USER_SCOPES.SPECIALIST],
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'checkPaymentStatus' });
          },
        },
        id: 'checkPaymentStatus',
        props: {
          color: 'primary',
          disable: false,
          label: 'Проверить статус оплаты',
          loading: false,
        },
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'mzSkip' });
          },
        },
        id: 'mzSkip',
        props: {
          color: 'primary',
          disable: false,
          label: 'Пропустить МЗ',
          loading: false,
        },
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'skipPaymentWaiting' });
          },
        },
        id: 'skipPaymentWaiting',
        props: {
          color: 'primary',
          disable: false,
          label: 'Пропустить ожидание оплаты',
          loading: false,
        },
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'status14' });
          },
        },
        id: 'status14',
        props: {
          color: 'primary',
          disable: false,
          label: 'Запрос дополнительной информации',
          loading: false,
        },
      },
      ...multiRouteButtons,
      {
        id: 'customButton',
        props: {
          color: 'primary',
          ...this.outData?.ButtonSettings,
        },
        componentPath: 'custom_form',
      },
      {
        actions: {
          click: () => {
            this.submit({ buttonId: 'endApprove' });
          },
        },
        id: 'endApprove',
        props: {
          color: 'primary',
          label: 'Завершить согласование',
          loading: false,
        },
      },
      {
        id: 'generateApprove',
        props: {
          color: 'positive',
          label: 'Сформировать решение',
          loading: false,
        },
        actions: {
          click: this.onGenerateApproveClick,
        },
      },
      {
        id: 'approveStep',
        props: {
          color: 'green',
          disable: false,
          loading: false,
          label: 'Согласовать',
        },
        actions: {
          click: () => {
            this.approveAvailableSteps();
          },
        },
        callBack: this.isRequiredRedirect,
      },
      {
        id: 'rejectStep',
        props: {
          color: 'red',
          disable: false,
          loading: false,
          label: 'Отклонить',
        },
        componentPath: 'dialog_comment',
      },
      {
        id: 'sendApproval',
        props: {
          color: 'primary',
          disable: false,
          loading: false,
          label: 'Отправить на согласование',
        },
        actions: {
          click: () => {
            this.submit({ buttonId: 'sendApproval' });
          },
        },
        callBack: this.isRequiredRedirect,
      },
      {
        id: 'routing',
        props: {
          visible: isRoutingVisible(),
          color: 'grey-8',
          icon: 'exit_to_app',
          disable: false,
          loading: false,
        },
        tooltip: this.$t('statements.routing'),
        componentPath: 'routing_dialog',
      },
      {
        id: 'setAssignee',
        props: {
          color: 'grey-8',
          icon: 'social_distance',
          disable: false,
          loading: false,
        },
        tooltip: this.$t('statements.changeAssignee'),
        componentPath: 'employee_dialog',
      },
      {
        id: 'userComment',
        props: {
          color: 'grey-8',
          disable: false,
          label: '',
          loading: false,
          icon: 'o_comment_bank',
        },
        componentPath: 'comment_dialog',
        tooltip: 'Добавить комментарий',
      },
      {
        id: 'userCommentDoc',
        props: {
          color: 'grey-8',
          disable: false,
          label: '',
          loading: false,
          icon: 'o_comment_bank',
        },
        componentPath: 'user_docs_comment_dialog',
        tooltip: 'Добавить комментарий',
      },
      {
        id: 'preReviewDocuments',
        props: {
          color: 'primary',
          disable: false,
          label: 'Перейти к рассмотрению',
          loading: false,
        },
        actions: {
          click: () => {
            this.submit({ buttonId: 'preReviewDocuments' });
          },
        },
      },
      {
        actions: {
          click: () => {
            this.$recordActivity({
              buttonCode: 'application_unload',
              extraInfo: {
                previewInfo: [
                  {
                    value: this.model?.common?.orderId,
                    label: 'номер',
                  },
                ],
              },
            });
            this.pack();
          },
        },
        id: 'pack',
        props: {
          flat: true,
          color: 'grey-8',
          disable: false,
          icon: 'arrow_circle_down',
          loading: false,
          padding: '6px',
        },
        scopesMode: ScopesMode.or,
        scopes: [
          USER_SCOPES.REGISTRAR,
          USER_SCOPES.SPECIALIST,
          USER_SCOPES.SIGNED_SPECIALIST,
          USER_SCOPES.MILITARY_APPLICATION_SPECIALIST,
          USER_SCOPES.MILITARY_COMMISSAR,
        ],
        tooltip: this.$t('statements.PackagesCard.tooltip'),
        withoutActions: true,
      },
      {
        id: 'invite',
        props: {
          flat: true,
          color: 'grey-8',
          disable: false,
          icon: 'insert_invitation',
          loading: false,
          padding: '6px',
        },
        scopes: [USER_SCOPES.PREORDER],
        tooltip: this.$t('statements.inviteTooltip'),
        componentPath: 'invate_dialog',
      },
      {
        id: 'printStatement',
        props: {
          color: 'grey-8',
          disable: false,
          label: '',
          loading: false,
          icon: 'pgs-print',
          visible: true,
        },
        componentPath: 'print_statement_button',
        tooltip: 'Печать заявления',
        withoutActions: true,
      },
    ];

    this.disableAllButtons = false;
  }

  initTabsList() {
    this.tabs.list = [
      {
        name: this.$t('statements.BasicCard.tab'),
        path: 'basic',
        visible: true,
      },
      {
        name: this.$t('statements.AuthorCard.tab'),
        path: 'author',
        visible: true,
      },
      {
        name: this.$t('statements.StatementCard.tab'),
        path: 'data',
        visible: () => this.model.system.serviceId !== ACCREDITATION_ID,
      },
      {
        name: this.$t('statements.RecruitInfoForm.tab'),
        path: 'info',
        visible: () => this.model.recruitInfoForm.flag,
      },
      {
        name: this.$t('statements.OldMetaCard.tab'),
        path: 'old_meta',
        visible: () => !!this.model?.oldMeta,
      },
      {
        name: this.$t('statements.DocumentCard.tab'),
        path: 'documents',
        visible: true,
      },
      {
        name: this.$t('statements.OtherStatementsCard.tab'),
        path: 'statements',
        visible: true,
      },
      {
        name: this.$t('statements.ChargesCard.tab'),
        path: 'charges',
        visible: () => !!get(this.model, 'payments'),
      },
      {
        name: this.$t('statements.PaymentsSearchCard.tab'),
        path: 'payments_search',
        visible: () => this.serviceCard?.isPayable,
      },
      {
        name: this.$t('statements.MezhvedsCard.tab'),
        path: 'cross',
        visible: () => !!get(this.model, 'interDepartmentReq.length'),
      },
      {
        name: this.$t('statements.SDD.tab'),
        path: 'sdd',
        visible: () =>
          (get(
            this.model,
            'system.isSDD'
          ) /* todo: isSdd is deprecated, delete it after a few releases */ ||
            get(this.model, 'system.hasSDD')) &&
          get(this.model, 'system.status.external') !== 2,
      },
      {
        name: this.$t('statements.ChecksCard.tab'),
        path: 'checks',
        visible: () =>
          !!get(this.model, 'decisionData.groups.length') ||
          get(this.userTask, 'userTask.outData.manualVerifications.length'),
      },
      {
        name: this.$t('statements.DocumentResolutionCard.tab'),
        path: 'documents_resolution',
        visible: !!(get(this.model, 'documents') || []).find((document) =>
          this.checkDocumentSource(document, 'result')
        ), // Проверка на наличие результирующих документов
      },
      {
        name: this.$t('statements.PackagesCard.tab'),
        path: 'packages',
        visible: () =>
          !!(get(this.model, 'documents') || []).filter((document) =>
            isEqual(document.type.code, 'archivedApplication')
          ).length,
      },
      {
        name: this.$t('statements.HistoryCard.tab'),
        path: 'history',
        visible: () => !!get(this.model, 'history.length'),
      },
      {
        name: this.$t('statements.SystemCard.tab'),
        path: 'system',
        visible: () => this.$AC.haveOneOfScope([USER_SCOPES.CLOUD_ADMIN]),
      },
    ];

    this.disableAllButtons = false;
  }

  submit({ buttonId, data, force }, counter = 0) {
    const button = this.getButtonById(buttonId) || {};
    const cb = button.callBack;
    if (!force && button.dialog) {
      button.dialog.value = true;
    } else {
      if (button.props) {
        button.props.loading = true;
      }

      this.disableAllButtons = true;

      const requestBody = {
        id: button.id || buttonId,
      };

      if (data) {
        requestBody.data = data;
      }

      const updateComment = get(this.updates, 'comment');
      const currentComment = requestBody.data?.comment;
      if (updateComment) {
        if (has(requestBody, 'data')) {
          // PGSSUPPORT-14052 - пропадал комментарий, из-за пустых update-ов
          // разобраться для чего эти update-ы небыло времени, поэтому дописал
          // осторожную логику которая исключает переписывание коммента пустой строкой
          if (currentComment && updateComment != currentComment) {
            requestBody.data.comment = `${currentComment}, ${updateComment}`;
          } else {
            requestBody.data.comment = updateComment;
          }
        } else {
          requestBody.data = {
            comment: updateComment || '',
          };
        }
        delete this.updates.comment;
      }

      const taskId = get(this.userTask, 'userTask.taskId');
      if (taskId) {
        this.$emit('submit', {
          button,
          requestBody,
          taskId,
          ...(cb && { cb }),
        });
      } else if (counter < 3) {
        setTimeout(() => {
          this.submit({ buttonId, data, force }, counter + 1);
        }, 700);
      }
    }
  }

  async pack() {
    const button = this.getButtonById('pack') || {};
    const printParams = await prepareStatementData(
      this.schema,
      this.authorSchema,
      this.model,
      this.serviceCard,
      true
    );

    // TODO - PGSSUPPORT-21413 - возможно в данном месте стоит отказаться от prepareStatementData
    // или создать ответвление для функции
    printParams.parameters = JSON.parse(printParams.parameters);

    button.props.loading = true;
    this.$store
      .dispatch('wf/processes/dispatchProcess', {
        processKey: 'GPZUExport',
        data: {
          applicationId: this.common.id,
          ...printParams,
        },
      })
      .then(() => {
        notifySuccess(this.$t('statements.PackagesCard.process.success'));
      })
      .catch(() => {
        notifyError(this.$t('statements.PackagesCard.process.error'));
      })
      .finally(() => {
        button.props.loading = false;
      });
  }

  goToCheckCriteria() {
    this.submit({
      buttonId: 'goToCheckCriteria',
    });
  }

  goToReviewDocumentsCheckRecalc() {
    this.submit({
      buttonId: 'isChecksRecalc',
      data: {
        manualVerifications: this.commonData,
      },
    });
  }

  goToReviewDocuments() {
    this.submit({
      buttonId: 'goToReviewDocuments',
      data: {
        manualVerifications: this.commonData,
      },
    });
  }

  backToReview() {
    this.submit({
      buttonId: 'backToReview',
    });
  }

  updateMZ() {
    this.submit({
      buttonId: 'updateMZ',
    });
  }

  confirm() {
    this.submit({
      buttonId: 'confirm',
    });
  }

  returnForRevision() {
    this.submit({
      buttonId: 'returnForRevision',
    });
  }

  fetchCards() {
    const componentsObj = this.components ? this.components : {};

    this.buttons.forEach((button) => {
      const pathComponent = get(button, 'componentPath');

      if (!pathComponent || get(this.components, `${pathComponent}`)) {
        return;
      } // не выполняем загрузку, если нет pathComponent или уже загружено
      componentsObj[pathComponent] = {};
      this.$set(
        componentsObj,
        pathComponent,
        this.$GlobalComponentImporter.registerComponent(
          pathComponent,
          `cards/statements/`
        )
      );
    });
    this.components = componentsObj;
  }

  update(updatesObj) {
    Object.entries(updatesObj).forEach(([key, value]) => {
      this.updates[key] = value;
    });
  }

  setPaymentsTabActive() {
    const tabsList = this.tabs?.list || [];

    if (tabsList.find((tab) => tab.path === 'charges')) {
      const route = this.$route;
      const newQuery = { ...route.query, active: 'charges' };

      this.$router.push({ ...route, query: newQuery });
    }
  }

  async isRequiredRedirect(): void {
    // const handler = (e: MessageEvent) => {
    //   let traceId = '';
    //   const taskId = get(this.userTask, 'userTask.taskId');
    //   const data: MessageEventData = JSON.parse(get(e, 'data', '{}'));
    //   if (data.body.taskId === taskId) {
    //     traceId = data.traceId;
    //   }
    //   if (
    //     data.traceId === traceId
    //     && data.body?.process?.defKey === 'RouteDecisionStepsProcess' // задать условие
    //   ) {
    //     this.checkStatementAwailability();
    //     this.$websockets.removeListener(handler);
    //   }
    // }
    // this.$websockets.addListener(handler);
  }

  async checkStatementAwailability(): Promise<void> {
    const currentStatementId = this.$route.params?.id;
    await documentApi
      .getDocument('Applications', currentStatementId)
      .then(() => {
        this.initButtons();
      })
      .catch((e) => {
        this.returnToParentView('/statements');
      });
  }

  convertDateFromBackendFormat(date, format) {
    return convertDateFromBackendFormat(date, format);
  }

  onGenerateApproveClick() {
    if (!this.model?.decisionData) {
      return;
    }
    const noManualUndoneChecks =
      get(this.model, 'decisionData.recommendation') &&
      !isEmpty(get(this.model, 'decisionData.recommendation'));
    if (noManualUndoneChecks) {
      this.submit({ buttonId: 'generateApprove' });
    } else {
      this.$emit('commonModels', {
        checks: {
          needToBeValidated: true,
        },
      });
    }
  }

  async approveAvailableSteps(): void {
    const route = this.$route;
    let timeout = 0;
    if (route.query?.active !== 'checks') {
      timeout = 1000;
      await this.$router.push({
        name: route.name || '',
        params: route.params || {},
        query: {
          ...route.query,
          active: 'checks',
        },
      });
    }

    setTimeout(() => {
      if (get(this.common, 'models.checks.avilableCheksPassed')) {
        this.submit({ buttonId: 'approveStep' });
      } else {
        this.$emit('commonModels', {
          checks: {
            needToBeValidated: true,
          },
        });
      }
    }, timeout);
  }

  @Watch('common.active')
  commonActiveHandler(val) {
    this.tabs.current = val;
  }

  @Watch('common.needToUpdate', { immediate: true })
  commonNeedToUpdatehandler(val) {
    this.$store.commit(`utils/cards/needToUpdate`, CardNeedToUpdateType.FALSE);

    this.init(val);
  }

  @Watch('common.models.index.updateButtons')
  updateButtonshandler(val) {
    if (isArray(val)) {
      val.forEach((button) => {
        merge(this.getButtonById(button.id), button);
      });
    }
  }

  // Watching submit data from one-level components and start submit function
  @Watch('common.models.index.submit')
  submitHandler(val) {
    // Clear submit model after action handle
    if (val) {
      this.submit(val);
      this.$emit('commonModels', {
        index: {
          submit: null,
        },
      });
    }
  }

  @Watch('userTask.userTask.outData.redirectToDocObject')
  redirectToDocObjectHandler(val) {
    const route = this.$route;
    const lock = get(route, 'query.lock', false);

    if (val && route && !lock) {
      const location = {
        name: route.name || '',
        params: route.params || {},
        query: {
          ...route.query,
          active: get(val, 'tab'),
        },
      };

      if (has(val, 'docIds')) {
        location.query.markeredDocuments = get(val, 'docIds');
      }

      if (route.query.active !== location.query.active) {
        this.$router.replace(location);
      }
    }
  }

  createUUID() {
    return getUUID();
  }

  beforeDestroy() {
    this.$store.commit(`utils/cards/removeModel`, {
      path: this.common.path,
    });

    this.$store.commit(`utils/cards/removeUserTask`, {
      path: this.common.path,
    });
  }
}
</script>
