<i18n>
{
  "en": {
    "sdd": {
      "common": {
        "cancel": "Cancel",
        "create": "Create"
      },
      "modal": {
        "createIncome": {
          "title": "Create additional income",
          "incomeTypeSelectLabel": "Income type",
          "incomeSourceSelectLabel": "Income source"
        }
      },
      "btn": {
        "recalculate": "Recalculate",
        "delete": "Remove / exclude"
      },
      "exclude" : {
        "ignore": "Exclude",
        "revert": "Revert",
        "cancel": "Cancel",
        "cause": "Cause exclude"
      },
      "text": {
        "aggregateIncomePeriod": "Aggregate income for the period",
        "groupSubsistenceMinimumSum": "The sum of the values of the substinence minimum of the group",
        "costOfLivingPerCapita": "Cost of living per capita",
        "averageIncomePerCapita": "Average income per capita",
        "personsParticipatingInCalculations": "The number of family members participating in the calculation",
        "unemployed": "Unemployed",
        "tin": "TIN of the employer (tax agent)",
        "defense": "A family member is serving in the Ministry of Defense (including the RF Armed Forces, Main Directorate of the General Staff of the RF Armed Forces), Rosgvardia, FSSP, FCS, GUSP RF",
        "internal": "A family member is serving in the FSIN, FSB, FSO, Ministry of Internal Affairs of the Russian Federation",
        "incomeIgnored": "Does not participate in the calculation of AMI",
        "incomeCreateDate": "Create date",
        "incomeEditDate": "Edit date"
      },
      "options": {
        "calcType": {
          "full": "Consider for the full period",
          "short": "Take into account the months when the income was received"
        }
      }
    }
  },
  "ru": {
    "sdd": {
      "common": {
        "cancel": "Отмена",
        "create": "Создать"
      },
      "modal": {
        "createIncome": {
          "title": "Добавить дополнительный доход",
          "incomeTypeSelectLabel": "Тип дохода",
          "incomeSourceSelectLabel": "Источник дохода"
        }
      },
      "btn": {
        "recalculate": "Перерассчитать",
        "delete": "Удалить / Исключить"
      },
      "exclude" : {
        "ignore": "Исключить",
        "revert": "Вернуть",
        "cancel": "Отмена",
        "cause": "Причина исключения"
      },
      "text": {
        "aggregateIncomePeriod": "Совокупный доход за период",
        "groupSubsistenceMinimumSum": "Сумма величин прожиточного минимума группы",
        "costOfLivingPerCapita": "Прожиточный минимум на душу населения",
        "averageIncomePerCapita": "Среднедушевой доход",
        "personsParticipatingInCalculations": "Количество членов семьи, участвующих в расчете",
        "unemployed": "Безработный",
        "tin": "ИНН работодателя (налогового агента)",
        "defense": "Член семьи проходит службу в Минобороны (включая ВС РФ, ГУ ГШ ВС РФ), Росгвардии, ФССП, ФТС, ГУСП РФ",
        "internal": "Член семьи проходит службу ФСИН, ФСБ, ФСО, МВД РФ",
        "incomeIgnored": "Не участвует в расчете СДД",
        "incomeCreateDate": "Дата создания",
        "incomeEditDate": "Дата редактирования"
      },
      "options": {
        "calcType": {
          "full": "Учитывать за полный период",
          "short": "Учитывать за месяцы, когда был получен доход"
        }
      }
    }
  }
}
</i18n>

<template>
  <div class="row q-pa-md justify-center" v-if="common.active === 'sdd'">
    <div class="col-12 max-1280-width Sdd q-gutter-y-md">
      <div>
        <IncomeForm
          :service="service"
          :model="model"
        />
      </div>
      <div class="section Sdd-TableCard">
        <q-table

          :loading="!application"
          bordered
          separator="cell"
          wrap-cells
          :data="incomeData"
          :columns="columns"
          row-key="name"
          virtual-scroll
        >
          <template #body="{ row, rowIndex, cols }">
            <q-tr no-hover class="bg-grey-1" :key="row.owner.id">
              <template v-for="col in cols">
                <q-td
                  class="text-center"
                  v-if="col.name === 'expand'"
                  :key="col.name"
                >
                  <q-btn v-if="row.income" color="primary" flat round dense>
                    <q-icon
                      @click="expand(row)"
                      :name="getExpandedIcon(row)"
                    />
                  </q-btn>
                  <q-btn
                    v-else-if="!isMadeDecision"
                    round
                    dense
                    icon="add_box"
                    color="primary"
                    flat
                    @click="createNewIncome(row)"
                    :disable="isMadeDecision"
                  >
                    <q-tooltip :delay="500">Добавить доход</q-tooltip>
                  </q-btn>
                </q-td>
                <q-td
                  v-else-if="col.name === 'owner'"
                  :style="{
                    minWidth: '300px',
                    position: 'sticky',
                    left: 0,
                    zIndex: 100,
                  }"
                  :key="col.name"
                >
                  <div class="owner-cell">
                    <div class="owner-cell__name text-weight-medium">
                      {{ getOwnerName(row) }}

                      <span
                        v-if="causesExcludeOwner.length"
                        :id="`owner-exclude-${rowIndex}`"
                      >
                        <q-icon
                          v-if="row.owner.ownerIgnore === null"
                          name="visibility"
                          @click="openExcludePopup(rowIndex)"
                        >
                          <q-tooltip>
                            {{ $t('sdd.exclude.ignore') }}
                          </q-tooltip>
                        </q-icon>
                        <q-icon
                          v-else
                          name="visibility_off"
                          @click="ownerInclude(row.owner.id)"
                        >
                          <q-tooltip>
                            {{ $t('sdd.exclude.revert') }}
                          </q-tooltip>
                        </q-icon>

                        <q-popup-proxy
                          no-parent-event
                          :target="`#owner-exclude-${rowIndex}`"
                          ref="exclude"
                          @hide="ownerIgnore = null"
                        >
                          <q-banner style="width: 600px">
                            <q-select
                              filled
                              dense
                              emit-value
                              map-options
                              v-model="ownerIgnore"
                              :options="causesExcludeOwner"
                              :label="$t('sdd.exclude.cause')"
                              class="q-mb-md q-mt-md"
                            />
                            <q-btn
                              outline
                              :label="$t('sdd.exclude.ignore')"
                              :disable="!ownerIgnore"
                              class="q-mr-md"
                              @click="ownerExclude(row.owner.id, rowIndex)"
                            />
                            <q-btn
                              outline
                              :label="$t('sdd.exclude.cancel')"
                              @click="closeExcludePopup(rowIndex)"
                            />
                          </q-banner>
                        </q-popup-proxy>
                      </span>
                    </div>
                    <div v-if="relationDict" class="owner-cell__name">
                      {{ getOwnerRelation(row) }}
                    </div>
                    <div v-if="isUnemployed(row)" class="text-blue-grey-8">
                      {{ $t('sdd.text.unemployed') }}
                    </div>
                  </div>
                </q-td>
                <q-td
                  v-else-if="col.name === 'calcType'"
                  :key="col.name"
                  :style="{ borderLeftColor: '#fafafa' }"
                ></q-td>
                <q-td
                  :style="{ borderLeftColor: '#fafafa' }"
                  v-else
                  :key="col.name"
                ></q-td>
              </template>
            </q-tr>
            <template v-if="row.owner && expanded[row.owner.id]">
              <q-tr
                class="inner"
                v-for="(income, index) of row.income"
                :key="row.owner.id + '_' + index"
              >
                <template v-if="income">
                  <template v-for="col in cols">
                    <q-td
                      no-hover
                      v-if="col.name === 'expand'"
                      :key="col.name"
                    >
                      <q-btn
                        round
                        dense
                        icon="delete"
                        color="red-5"
                        flat
                        v-if="!isMadeDecision"
                        @click="deleteOrExclude(income, row)"
                        :disable="isMadeDecision"
                      >
                        <q-tooltip :delay="500">{{
                          $t('sdd.btn.delete')
                        }}</q-tooltip>
                      </q-btn>
                      <q-checkbox
                        v-else-if="!isMadeDecision"
                        v-model="income.incomeIgnored"
                        @input="changeIncome(row.owner.id)"
                        :false-value="true"
                        :true-value="false"
                        :disable="isMadeDecision"
                      />
                    </q-td>
                    <q-td
                      v-else-if="col.name === 'owner'"
                      :style="getIncomeStyle(income)"
                      :key="col.name"
                    >
                      <div
                        class="ignored-cell"
                        v-if="income.incomeIgnored"
                        :style="ignoredInnerCellStyle"
                      ></div>
                      <div class="owner-cell">
                        <div class="text-weight-medium">
                          {{ getIncomeType(income) }}
                        </div>
                        <div class="text-primary">
                          {{ getIncomeSource(income) }}
                        </div>
                      </div>
                      <div class="text-grey-7" v-if="income.incomeCreateDate">
                        <q-icon name="calendar_today" />
                        {{ $t('sdd.text.incomeCreateDate') }}:
                        {{
                          convertDateFromBackendFormat(
                            income.incomeCreateDate
                          )
                        }}
                      </div>
                      <div class="text-grey-7" v-if="income.incomeEditDate">
                        <q-icon name="calendar_today" />
                        {{ $t('sdd.text.incomeEditDate') }}:
                        {{
                          convertDateFromBackendFormat(income.incomeEditDate)
                        }}
                      </div>
                    </q-td>
                    <template v-else-if="col.name === 'calcType'">
                      <q-td
                        :style="income.incomeIgnored && ignoredCellStyle"
                        :key="col.name"
                      >
                        <div
                          class="ignored-cell"
                          v-if="income.incomeIgnored"
                          :style="ignoredInnerCellStyle"
                        ></div>
                        <q-select
                          :disable="isMadeDecision || !isManualIncome(income)"
                          outlined
                          v-model="income.incomeIsShort"
                          emit-value
                          dense
                          options-dense
                          options-cover
                          :display-value="
                            calcTypeOptionsMap[income.incomeIsShort]
                          "
                          :options="calcTypeOptions"
                          @input="recalculate"
                        >
                        </q-select>
                      </q-td>
                    </template>
                    <template v-else-if="isSpecialType(income)">
                      <q-td
                        v-if="col.name === 'incomeSizeAverage'"
                        :key="col.name"
                        :style="income.incomeIgnored && ignoredCellStyle"
                        :colspan="
                          income.incomeSize && income.incomeSize.length + 1
                        "
                      >
                        <div
                          class="ignored-cell"
                          v-if="income.incomeIgnored"
                          :style="ignoredInnerCellStyle"
                        ></div>
                        <template v-if="getTypeIdAsNumber(income) === 13">
                          <div class="text-weight-medium">
                            {{ $t('sdd.text.defense') }}
                          </div>
                          <div
                            v-if="get(row, 'owner.workINN')"
                            class="text-blue-grey-8"
                          >
                            <span class="text-weight-medium">
                              {{ $t('sdd.text.tin') }}:
                            </span>
                            <span>{{ get(row, 'owner.workINN') }}</span>
                          </div>
                        </template>
                        <template
                          v-else-if="getTypeIdAsNumber(income) === 14"
                        >
                          <div class="text-weight-medium">
                            {{ $t('sdd.text.internal') }}
                          </div>
                        </template>
                        <template v-else></template>
                      </q-td>
                    </template>
                    <q-td
                      v-else-if="col.name === 'incomeSizeAverage'"
                      :key="col.name"
                    >
                      <div v-if="!income.incomeIgnored" class="text-right">
                        {{ formatMoney(income[col.name]) }}
                      </div>
                      <div v-else class="text-right text-red-8">
                        {{ $t('sdd.text.incomeIgnored') }}
                      </div>
                    </q-td>
                    <q-td
                      v-else-if="income && income.incomeSize"
                      class="text-right"
                      :style="income.incomeIgnored && ignoredCellStyle"
                      :key="col.name"
                    >
                      <div
                        class="ignored-cell"
                        v-if="income.incomeIgnored"
                        :style="ignoredInnerCellStyle"
                      ></div>
                      {{ formatMoney(income.incomeSize[col.name]) }}
                      <q-popup-edit
                        auto-save
                        :cover="false"
                        anchor="top left"
                        self="top left"
                        v-model="income.incomeSize[col.name]"
                        :title="col.label"
                        :disable="isMadeDecision"
                        @show="
                          showHandler($event, income.incomeSize[col.name])
                        "
                        @hide="
                          hideHandler($event, {
                            rowIndex,
                            expandIndex: index,
                            colName: col.name,
                          })
                        "
                      >
                        <q-input
                          autofocus
                          type="number"
                          color="primary"
                          dense
                          outlined
                          v-model.number="inputModel"
                        />
                      </q-popup-edit>
                    </q-td>
                    <q-td
                      v-else
                      :key="col.name"
                      :style="income.incomeIgnored && ignoredCellStyle"
                      class="text-grey-4"
                    >
                      <div
                        class="ignored-cell"
                        v-if="income.incomeIgnored"
                        :style="ignoredInnerCellStyle"
                      ></div>
                    </q-td>
                  </template>
                </template>
              </q-tr>
              <q-tr v-if="!isMadeDecision">
                <template v-for="col in cols">
                  <q-td
                    class="text-center"
                    no-hover
                    v-if="col.name === 'expand'"
                    :key="col.name"
                  >
                    <q-btn
                      round
                      dense
                      icon="add_box"
                      color="primary"
                      flat
                      @click="createNewIncome(row)"
                      :disable="isMadeDecision"
                    >
                      <q-tooltip :delay="500">Добавить доход</q-tooltip>
                    </q-btn>
                  </q-td>
                  <q-td
                    colspan="15"
                    no-hover
                    v-else-if="col.name === 'owner'"
                    class="text-grey-6"
                    :key="col.name"
                  >
                    {{ $t('sdd.modal.createIncome.title') }}
                  </q-td>
                </template>
              </q-tr>
            </template>
          </template>
        </q-table>
      </div>
      <div :style="{ position: 'relative' }" class="section">
        <div
          class="section-cover"
          :style="{
            backdropFilter: 'blur(2px)',
            position: 'absolute',
            width: '100%',
            height: '100%',
            top: 0,
            left: 0,
            zIndex: 100,
            backgroundColor: 'rgba(255, 255, 255, 0.9)',
            borderRadius: '4px',
            border: '1px solid #eee',
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
          }"
          v-if="recalculating"
        >
          <q-spinner-gears size="50px" color="primary" />
        </div>
        <q-markup-table :style="{ width: '600px' }" bordered separator="cell">
          <tbody>
            <tr v-for="row of costData" :key="row.uid">
              <td :style="{ whiteSpace: 'pre-line' }" class="text-left">
                {{ row.label }}
              </td>
              <td
                class="text-right"
                :class="{
                  [averageIncomePerCapitaClass]:
                    row.code === 'averageIncomePerCapita',
                }"
              >
                {{ row.value }}
              </td>
            </tr>
          </tbody>
        </q-markup-table>
      </div>
    </div>
    <q-dialog persistent v-model="showCreateIncomeModal">
      <q-card :style="{ maxWidth: '500px', width: '500px' }" class="no-shadow">
        <q-card-section>
          <div class="text-h6">{{ $t('sdd.modal.createIncome.title') }}</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          <q-select
            v-model="newIncomeType"
            :options="incomeTypeDict"
            class="q-mb-md"
            dense
            outlined
            :label="$t('sdd.modal.createIncome.incomeTypeSelectLabel')"
          />
          <q-select
            v-model="newIncomeSource"
            :options="incomeSourceOptions"
            dense
            outlined
            :disable="incomeSourceOptions && incomeSourceOptions.length === 1"
            :label="$t('sdd.modal.createIncome.incomeSourceSelectLabel')"
          >
          </q-select>
        </q-card-section>

        <q-card-actions align="right">
          <q-btn
            @click="cancelChoosingIncomeType"
            flat
            :label="$t('sdd.common.cancel')"
            color="red-5"
          />
          <q-btn
            @click="addIncome"
            :disable="!newIncomeType || !newIncomeSource || isMadeDecision"
            flat
            :label="$t('sdd.common.create')"
            color="primary"
          />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

<script lang="ts">
// @ts-nocheck
import {
  convertDateFormat,
  convertDateFromBackendFormat,
  convertDateToBackendFormat,
} from '@utils/format-date';
import { DateFormat } from '@constants/utils/format-date';
import get from 'lodash/get';
import has from 'lodash/has';
import head from 'lodash/head';
import cloneDeep from 'lodash/cloneDeep';
import isEmpty from 'lodash/isEmpty';
import { mapGetters } from 'vuex';
import IncomeForm from './components/IncomeFormDataEditor.vue';

export default {
  name: 'StatementSDD',
  components: {
    IncomeForm
  },
  props: ['common', 'model', 'user-task'],
  watch: {
    model: {
      handler() {
        const clonedModel = cloneDeep(this.model);
        this.$set(this, 'application', clonedModel);

        const originalIncome = cloneDeep(
          get(clonedModel, 'statement.incomeInfo', [])
        );
        this.$set(this, 'originalIncome', originalIncome);
        this.initExpanded();

        this.recalculating = false;
      },
    }
  },
  data() {
    return {
      inputModel: null,
      application: null,
      pagination: {
        rowsPerPage: 10,
      },
      expanded: {},
      showCreateIncomeModal: false,
      newIncomeType: null,
      newIncomeSource: null,
      addNewIncomeTo: null,
      originalIncome: null,
      recalculating: false,
      DOC_INCOME_REF: 'IncomeRef',
      ownerIgnore: null,
    };
  },
  computed: {
    isMadeDecision() {
      const hasComplyingAction = get(
        this.userTask,
        'userTask.outData.actions',
        []
      ).some((action) =>
        ['confirm', 'returnForRevision', 'sign'].includes(action)
      );

      return !this.userTask || hasComplyingAction;
    },
    columns() {
      const headerClasses = ['bg-blue-grey-1'].join(' ');
      const periods = this.periods.map((period) => {
        return {
          code: period,
          name: period
        } 
      })

      const base = {
        align: 'left',
        sortable: false,
        headerClasses,
      };

      const periodCols = (periods || []).map((period, index) => ({
        ...base,
        name: index,
        label: period.name,
        field: period.code,
        align: 'right',
      }));

      const expandCol = {
        ...base,
        name: 'expand',
        label: '',
        field: 'expand',
        align: 'center',
      };

      const ownerCol = {
        ...base,
        name: 'owner',
        label: 'Владелец дохода',
        field: 'owner',
        headerStyle:
          'position: sticky;' +
          'left: 0;' +
          'zIndex: 100;' +
          'background: #fff;',
      };

      const incomeSizeAverageCol = {
        ...base,
        name: 'incomeSizeAverage',
        label: 'Среднемесячный доход',
        field: 'incomeSizeAverage',
        align: 'center',
      };

      const calcTypeCol = {
        ...base,
        name: 'calcType',
        label: '',
        field: null,
        align: 'center',
        headerStyle: 'borderLeftColor: #eceff1',
      };

      return [
        expandCol,
        ownerCol,
        calcTypeCol,
        ...(periodCols || []),
        incomeSizeAverageCol,
      ];
    },
    costData() {
      const extendedCapita = this.costOfLivingExtendedPerCapita;

      return [
        {
          code: 'aggregateIncomePeriod',
          label: this.$t('sdd.text.aggregateIncomePeriod'),
          value: this.formatMoney(this.aggregateIncomePeriod),
        },
        {
          code: 'personsParticipatingInCalculations',
          label: this.$t('sdd.text.personsParticipatingInCalculations'),
          value: this.personsParticipatingInCalculations,
        },
        {
          code: 'costOfLivingPerCapita',

          label: extendedCapita
            ? this.costOfLivingExtendedPerCapitaTitle
            : this.$t('sdd.text.costOfLivingPerCapita'),

          value: this.formatMoney(
            extendedCapita
              ? this.costOfLivingExtendedPerCapita
              : this.costOfLivingPerCapita
          ),
        },
        {
          code: 'averageIncomePerCapita',
          label: this.$t('sdd.text.averageIncomePerCapita'),
          value: this.formatMoney(this.averageIncomePerCapita),
        },
      ];
    },
    averageIncomePerCapitaDeficient() {
      const cost =
        this.costOfLivingExtendedPerCapita || this.costOfLivingPerCapita;

      return cost >= this.averageIncomePerCapita;
    },
    averageIncomePerCapitaClass() {
      return this.averageIncomePerCapitaDeficient
        ? 'text-green-7'
        : 'text-red-7';
    },
    personsParticipatingInCalculations() {
      return get(this.application, 'statement.incomePersonCount');
    },
    hasIncomeInfo() {
      return Boolean(get(this.application, 'statement.incomeInfo'));
    },
    incomeData() {
      if (!this.hasIncomeInfo) return [];

      const incomeInfo = this.application.statement.incomeInfo.map((user) => {
        if (user?.owner?.ownerIgnore === undefined) {
          user.owner.ownerIgnore = null;
        }
        return user;
      });
      return incomeInfo;
    },
    documents() {
      return get(this.model, 'documents');
    },
    periods() {
      return get(this.application, 'statement.incomePeriod') || [];
    },
    aggregateIncomePeriod() {
      return get(this.application, 'statement.aggregateIncomePeriod');
    },
    groupSubsistenceMinimumSum() {
      return get(this.application, 'statement.groupSubsistenceMinimumSum');
    },
    costOfLivingPerCapita() {
      return get(this.application, 'statement.costOfLivingPerCapita');
    },
    costOfLivingExtendedPerCapita() {
      return get(this.application, 'statement.extendedCapita');
    },
    service() {
      return this.$store.getters['registryService/services/servicesCard'];
    },
    costOfLivingExtendedPerCapitaTitle() {
      return get(this.service, 'livingWage.textOfExtended');
    },
    averageIncomePerCapita() {
      return get(this.application, 'statement.averageIncomePerCapita');
    },
    incomeSourceOptions() {
      if (!this.incomeSourceDict) return [];

      const hasIncomeRefDoc =
        this.documents &&
        this.documents.some(
          (doc) => get(doc, 'type.code') === this.DOC_INCOME_REF
        );

      const availableSources = hasIncomeRefDoc ? ['2', '5'] : ['2'];

      return Object.entries(this.incomeSourceDict)
        .filter(([id]) => availableSources.includes(id))
        .map(([id, valueWrapper]) => ({
          value: id,
          label: valueWrapper.value,
        }));
    },
    ignoredCellStyle() {
      return {
        position: 'relative',
        pointerEvents: 'none',
      };
    },
    ignoredInnerCellStyle() {
      return {
        position: 'absolute',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%',
        zIndex: '101',
        opacity: '0.6',
        backgroundColor: '#fafafa',
        pointerEvents: 'none',
        // backdropFilter: 'blur(1px)', эксперементальное свойство, хром зависает с ним
      };
    },
    calcTypeOptions() {
      return [
        {
          label: this.$t('sdd.options.calcType.full'),
          value: false,
        },
        {
          label: this.$t('sdd.options.calcType.short'),
          value: true,
        },
      ];
    },
    calcTypeOptionsMap() {
      return {
        [false]: this.$t('sdd.options.calcType.full'),
        [true]: this.$t('sdd.options.calcType.short'),
      };
    },
    directoryLinks() {
      return get(this.service, 'incomeDirectorylinks', []);
    },
    relationDict() {
      if (get(this.common, 'active') !== 'sdd') return null;

      const findLinkRelationDict = this.directoryLinks.find(
        (v) => v.linkCode === 'TYPE_RELATED_CONNECTION'
      );
      if (!findLinkRelationDict) return null;

      const directory = this.findDirectory()(
        findLinkRelationDict.directoryCode,
        { typeResult: 'documents' }
      );
      if (!directory?.length) return null;

      return directory.reduce((result, item) => {
        result[item.code] = { value: item.value };

        return result;
      }, {});
    },
    incomeTypeDict() {
      if (get(this.common, 'active') !== 'sdd') return [];

      const findLinkRelationDict = this.directoryLinks.find(
        (v) => v.linkCode === 'TYPE_INCOME'
      );

      if (!findLinkRelationDict) return [];

      const directories = this.findDirectory()(
        findLinkRelationDict.directoryCode,
        { typeResult: 'documents' }
      );

      if (!directories?.length) return [];

      return directories.map((directory) => ({
        value: directory.code,
        label: directory.value,
      }));
    },
    incomeSourceDict() {
      if (get(this.common, 'active') !== 'sdd') return null;

      const findLinkRelationDict = this.directoryLinks.find(
        (v) => v.linkCode === 'INCOME_SOURCE'
      );
      if (!findLinkRelationDict) return null;

      const directory = this.findDirectory()(
        findLinkRelationDict.directoryCode,
        { typeResult: 'documents' }
      );
      if (!directory?.length) return null;

      return directory.reduce((result, item) => {
        result[item.code] = { value: item.value };

        return result;
      }, {});
    },
    causesExcludeOwner() {
      const findLinkRelationDict = this.directoryLinks.find(
        (v) => v.linkCode === 'REASONS_EXCLUSION_FAMILY_MEMBERS'
      );

      if (!findLinkRelationDict) return [];

      const directories = this.findDirectory()(
        findLinkRelationDict.directoryCode,
        { typeResult: 'documents' }
      );

      if (!directories?.length) return [];

      return directories.map((directory) => ({
        value: directory.code,
        label: directory.value,
      }));
    },
  },
  methods: {
    ...mapGetters('registryService/services', ['findDirectory']),
    get,
    initExpanded() {
      this.originalIncome.forEach((element) => {
        if (element.owner && element.income) {
          this.$set(this.expanded, element.owner.id, true);
        }
      });
    },
    ownerChange(ownerId, incomeIgnored) {
      this.application.statement.incomeInfo = this.incomeData.map((user) => {
        if (user.owner.id === ownerId) {
          user.owner.ownerIgnore = this.ownerIgnore;

          if (user.income) {
            user.income.map((income) => {
              income.incomeIgnored = incomeIgnored;
              return income;
            });
          }
        }
        return user;
      });
    },
    ownerExclude(ownerId, key) {
      this.ownerChange(ownerId, true);
      this.ownerIgnore = null;
      this.$refs.exclude[key].hide();
      this.recalculate();
    },
    ownerInclude(ownerId) {
      this.ownerChange(ownerId, false);
      this.recalculate();
    },
    openExcludePopup(key) {
      this.$refs.exclude[key].show();
    },
    closeExcludePopup(key) {
      this.ownerIgnore = null;
      this.$refs.exclude[key].hide();
    },
    changeIncome(ownerId) {
      this.application.statement.incomeInfo = this.incomeData.map((user) => {
        if (user.owner.id === ownerId) {
          user.owner.ownerIgnore = null;
        }
        return user;
      });
      this.recalculate();
    },
    isSpecialType(income) {
      const sourceId = get(income, 'incomeSource');
      const typeId = this.getTypeIdAsNumber(income);
      const specialTypes = [13, 14];

      return specialTypes.includes(typeId) && sourceId === '1';
    },
    getOwnerName(row) {
      return get(row, 'owner.name') || '';
    },
    isUnemployed(row) {
      return Boolean(get(row, 'owner.isUnemployed'));
    },
    getOwnerRelation(row) {
      const relation = get(row, 'owner.relation');

      if (!relation || !this.relationDict) return '';

      const valueWrapper = this.relationDict[relation];

      return get(valueWrapper, 'value') || '';
    },
    getIncomeType(income) {
      const incomeTypeRaw = get(income, 'incomeType');

      if (!incomeTypeRaw) return '';

      return get(incomeTypeRaw, 'value');
    },
    getIncomeSource(income) {
      const incomeSourceRaw = get(income, 'incomeSource');

      if (!incomeSourceRaw || !this.incomeSourceDict) return '';

      const incomeSource = String(parseInt(incomeSourceRaw, 10));
      const valueWrapper = this.incomeSourceDict[String(incomeSource)];

      return get(valueWrapper, 'value') || '';
    },
    getExpandedIcon(row) {
      const key = get(row, 'owner.id');

      return this.expanded[key] ? 'keyboard_arrow_up' : 'keyboard_arrow_right';
    },
    expand(row) {
      const key = get(row, 'owner.id');

      this.$set(this.expanded, key, !this.expanded[key]);
    },
    cancelChoosingIncomeType() {
      this.showCreateIncomeModal = null;
      this.addNewIncomeTo = null;
    },
    createNewIncome(entry) {
      this.showCreateIncomeModal = true;
      this.addNewIncomeTo = entry;

      if (get(this.incomeSourceOptions, 'length') === 1) {
        const manual = head(this.incomeSourceOptions);

        this.newIncomeSource = manual;
      }
    },
    addIncome() {
      this.showCreateIncomeModal = false;

      if (!this.addNewIncomeTo) return;

      const incomeEntry = {
        incomeSource: get(this.newIncomeSource, 'value'),
        incomeSizeTotal: 0,
        incomeIgnored: false,
        incomeIsCreated: true,
        incomeIsShort: false,
        incomeSize: new Array(12).fill(0),
        incomeType: {
          code: get(this.newIncomeType, 'value'),
          value: get(this.newIncomeType, 'label'),
        },
      };

      const updatedIncomes = cloneDeep(this.addNewIncomeTo.income) || [];

      updatedIncomes.push(incomeEntry);

      this.$set(this.addNewIncomeTo, 'income', updatedIncomes);

      const ownerID = get(this.addNewIncomeTo, 'owner.id');

      if (!this.expanded[ownerID]) {
        this.$set(this.expanded, ownerID, true);
      }

      this.recalculate();
    },
    async recalculate() {
      this.recalculating = true;

      try {
        const applicationId = get(this.application, 'id');

        if (applicationId) {
          await this.$store.dispatch('wf/processes/dispatchProcess', {
            processKey: 'IncomeApplicationUpdate',
            data: {
              applicationId,
              fields: { statement: { incomeInfo: this.prepareIncomeData() } },
            },
          });
        }
      } catch (err) {
        console.error('[sdd][recalculate] Could not recalculate', { err });
      }
    },
    prepareIncomeData() {
      // filter out unwanted incomes (marked as faulty, but not deleted)
      return this.incomeData;
    },
    deleteOrExclude(income, row) {
      if (String(income.incomeSource) === '1') {
        this.$set(income, 'incomeIgnored', true);
      } else {
        const updated = row.income.map((incomeIT) => {
          if (incomeIT === income) {
            incomeIT.incomeIsDeleted = true;
          }
          return incomeIT;
        });

        this.$set(row, 'income', updated);
      }

      this.recalculate();
    },
    formatMoney(amount) {
      if (!amount && amount !== 0) return '---';

      let num = amount;

      if (typeof num === 'string') {
        num = parseFloat(amount);
      }

      return typeof num === 'number'
        ? num.toLocaleString('ru', { style: 'currency', currency: 'RUB' })
        : '---';
    },
    isManualIncome(income) {
      return String(income.incomeSource) !== '1';
    },
    getIncomeStyle(income) {
      const ignoredStyles = income.incomeIgnored ? this.ignoredCellStyle : {};

      return {
        ...ignoredStyles,
        position: 'sticky',
        left: 0,
        zIndex: 102,
        background: '#fff',
        opacity: 1,
      };
    },
    getTypeIdAsNumber(income) {
      const typeValue = get(income, 'incomeType.code');

      return typeof typeValue === 'string'
        ? parseInt(typeValue, 10)
        : typeValue;
    },
    showHandler($event, value) {
      if (typeof value === 'number' && value !== 0) this.inputModel = value;
    },
    async hideHandler($event, { rowIndex, expandIndex, colName }) {
      const income = get(this.application, 'statement.incomeInfo', {});
      const path = `[${rowIndex}].income[${expandIndex}].incomeSize[${colName}]`;

      const date = new Date();
      this.$set(
        income[rowIndex].income[expandIndex],
        'incomeEditDate',
        convertDateToBackendFormat(date)
      );
      this.$set(income[rowIndex].income[expandIndex], 'incomeIsChanged', true);

      if (has(income, path)) {
        const shortPath = `[${rowIndex}].income[${expandIndex}].incomeSize`;
        const incomeEntry = get(income, shortPath);

        const inputModel = this.inputModel || 0;
        this.$set(incomeEntry, colName, inputModel);
      }

      await this.recalculate();

      this.inputModel = null;
    },
    convertDateFromBackendFormat(date) {
      return convertDateFromBackendFormat(date, DateFormat.datetime);
    },
  },
};
</script>

<style lang="scss" scoped>
.Sdd {
  font-family: 'Golos Text', sans-serif;
}
</style>
