<i18n>
{
  "en": {
    "VerificationsCard": {
      "type": "Type",
      "code": "Code",
      "goal": "Goal",
      "subjectType": "Subject",
      "autolVerificationsTitle": "Autochecks",
      "manualVerificationsTitle": "Manual checks",
      "rejectCode": "Reject code",
      "name": "Name",
      "invertLabel": "Invert label",
      "basedOn": "Based on",
      "noProcessesResult": "No Processes directories",
      "title": "Verifications",
      "create": "Create verification",
      "confirmationMessage": "Are you sure you want to delete the verification?"
    }
  },
  "ru": {
    "VerificationsCard": {
      "type": "Тип",
      "code": "Код",
      "goal": "Цели",
      "subjectType": "Субъект",
      "rejectCode": "Код отказа",
      "autolVerificationsTitle": "Aвтопроверки ",
      "manualVerificationsTitle": "Ручные проверки",
      "name": "Наименование",
      "invertLabel": "Инвертированое значение",
      "basedOn": "Основан на",
      "noProcessesResult": "Нет проверок",
      "title": "Проверки",
      "create": "Новая проверка",
      "confirmationMessage": "Вы уверены, что хотите удалить проверку?"
    }
  }
}
</i18n>

<template>
  <div class="q-pb-md" v-if="common.active === 'verifications' && !loadingCard">
    <q-card class="no-shadow q-gutter-y-md q-mx-md no-border-radius">
      <div
        class="q-gutter-y-md bg-white q-px-lg q-pb-md q-pt-sm q-mt-md rounded-borders"
      >
        <div
          class="flex justify-between q-px-md q-my-md row"
          style="width: 100%"
        >
          <div class="text-h6">{{ $t('VerificationsCard.title') }}</div>
          <q-btn
            color="primary"
            icon="add_box"
            v-if="state === 'inProgress' && canEdit"
            @click="editVerifItem({ code: 'create' })"
            :label="$t('VerificationsCard.create')"
          />
        </div>
        <div v-if="autoVerifications.length || manualVerifications.length">
          <q-expansion-item default-opened v-if="autoVerifications.length">
            <template v-slot:header>
              <q-item-section>
                <div class="text-h6">
                  {{ $t('VerificationsCard.autolVerificationsTitle') }}
                </div>
              </q-item-section>
            </template>

            <q-table
              :columns="columns"
              :data="autoVerifications"
              :pagination.sync="pagination"
              hide-no-data
              hide-bottom
            >
              <template v-slot:header="props">
                <q-tr :props="props">
                  <q-th key="code" :props="props">
                    {{ props.cols[0].label }}
                  </q-th>
                  <q-th key="name" :props="props">
                    {{ props.cols[1].label }}
                  </q-th>
                  <q-th key="invertLabel" :props="props">
                    {{ props.cols[2].label }}
                  </q-th>
                  <q-th style="font-size: 16px; font-weight: 600">
                    {{ $t('VerificationsCard.basedOn') }}
                  </q-th>
                  <q-th key="subjectType" :props="props">
                    {{ props.cols[4].label }}
                  </q-th>
                  <q-th v-if="state === 'inProgress'" />
                </q-tr>
              </template>

              <template v-slot:body="props">
                <q-tr :props="props">
                  <q-td key="code" :props="props">
                    {{ props.row.code }}
                  </q-td>
                  <q-td key="name" :props="props">
                    {{ props.row.name }}
                  </q-td>
                  <q-td key="invertLabel" :props="props">
                    {{ props.row.invertLabel }}
                  </q-td>
                  <q-td style="white-space: pre-wrap">
                    {{ get(props.row, 'basedOn.title') }}
                  </q-td>
                  <q-td key="subjectType">
                    <span
                      style="display: inline-block; margin: 5px"
                      v-for="item in props.cols[4].value"
                      :key="item"
                    >
                      <q-badge
                        :color="goalColorMap[item]"
                        :label="subjectLabel(item)"
                      />
                    </span>
                  </q-td>
                  <q-td auto-width v-if="state === 'inProgress'">
                    <q-btn
                      v-if="canEdit"
                      text-color="primary"
                      @click="editVerifItem(props.row)"
                      icon="edit"
                      flat
                    />

                    <q-btn
                      v-if="canEdit"
                      text-color="negative"
                      @click="toggleDeleteConfim(props.row)"
                      icon="delete"
                      flat
                    />
                  </q-td>
                </q-tr>
              </template>
            </q-table>
          </q-expansion-item>
          <q-expansion-item default-opened v-if="manualVerifications.length">
            <template v-slot:header>
              <q-item-section>
                <div class="text-h6">
                  {{ $t('VerificationsCard.manualVerificationsTitle') }}
                </div>
              </q-item-section>
            </template>
            <q-table
              :columns="columns"
              :filter="search"
              :filter-method="verificationFilter"
              :data="manualVerifications"
              hide-no-data
              :pagination.sync="pagination"
              hide-bottom
            >
              <template v-slot:top>
                <div style="width: 100%" class="row q-gutter-md">
                  <div class="col-3">
                    <q-select
                      label="Фильтр по цели"
                      dense
                      multiple
                      :options="manualVerificationsGoals"
                      v-model="search.goals"
                    >
                      <template v-slot:append>
                        <q-icon name="search" />
                      </template>
                    </q-select>
                  </div>
                  <div class="col-3">
                    <q-select
                      label="Фильтр по субъекту"
                      dense
                      multiple
                      :options="manualVerificationsSubjects"
                      v-model="search.subjects"
                    >
                      <template v-slot:append>
                        <q-icon name="search" />
                      </template>
                    </q-select>
                  </div>
                </div>
              </template>
              <template v-slot:header="props">
                <q-tr :props="props">
                  <q-th key="code" :props="props">
                    {{ props.cols[0].label }}
                  </q-th>
                  <q-th key="name" :props="props">
                    {{ props.cols[1].label }}
                  </q-th>
                  <q-th key="invertLabel" :props="props">
                    {{ props.cols[2].label }}
                  </q-th>
                  <q-th style="font-size: 16px; font-weight: 600">
                    {{ $t('VerificationsCard.basedOn') }}
                  </q-th>
                  <q-th style="font-size: 16px; font-weight: 600">
                    {{ $t('VerificationsCard.rejectCode') }}
                  </q-th>
                  <q-th key="goal" :props="props">
                    {{ props.cols[3].label }}
                  </q-th>
                  <q-th key="subjectType" :props="props">
                    {{ props.cols[4].label }}
                  </q-th>
                  <q-th v-if="state === 'inProgress'" />
                </q-tr>
              </template>
              <template v-slot:body="props">
                <q-tr :props="props">
                  <q-td key="code" :props="props">
                    {{ props.row.code }}
                  </q-td>
                  <q-td key="name" :props="props">
                    {{ props.row.name }}
                  </q-td>
                  <q-td key="invertLabel" :props="props">
                    {{ props.row.invertLabel }}
                  </q-td>
                  <q-td style="white-space: pre-wrap">
                    {{ get(props.row, 'basedOn.title') }}
                  </q-td>
                  <q-td>
                    {{ get(props.row, 'rejectCode') }}
                  </q-td>
                  <q-td key="goal">
                    <span
                      style="display: inline-block; margin: 5px"
                      v-for="item in props.row.goal"
                      :key="item"
                    >
                      <q-badge :color="goalColorMap[item]" :label="item" />
                    </span>
                  </q-td>
                  <q-td key="subjectType">
                    <span
                      style="display: inline-block; margin: 5px"
                      v-for="item in props.cols[4].value"
                      :key="item"
                    >
                      <q-badge
                        :color="goalColorMap[item]"
                        :label="subjectLabel(item)"
                      />
                    </span>
                  </q-td>
                  <q-td auto-width v-if="state === 'inProgress'">
                    <q-btn
                      v-if="canEdit"
                      text-color="primary"
                      @click="editVerifItem(props.row)"
                      icon="edit"
                      flat
                    />
                    <q-btn
                      v-if="canEdit"
                      text-color="negative"
                      @click="toggleDeleteConfim(props.row)"
                      icon="delete"
                      flat
                    />
                  </q-td>
                </q-tr>
              </template>
            </q-table>
          </q-expansion-item>
        </div>
        <div class="full-width text-center" v-else>
          {{ $t('VerificationsCard.noProcessesResult') }}
        </div>
      </div>
      <q-dialog class="full-width" v-model="deleteConfim">
        <q-card class="no-shadow full-width">
          <q-card-section>
            <div class="text-h6">
              {{ $t('VerificationsCard.confirmationMessage') }}
            </div>
          </q-card-section>

          <q-card-actions align="right">
            <q-btn @click="deleteVerifItem" color="primary" label="Удалить" />

            <q-btn
              color="white"
              text-color="primary"
              outline
              @click="toggleDeleteConfim"
              label="Отменить"
            />
          </q-card-actions>
        </q-card>
      </q-dialog>
    </q-card>

    <VerificationDialog
      :common="common"
      :model="model"
      @commonModels="commonModels"
      :dialog-data="formModel"
    />
  </div>
</template>

<script lang="ts">
// @ts-nocheck
import get from 'lodash/get';
import cloneDeep from 'lodash/cloneDeep';
import uniq from 'lodash/uniq';
import { notifyError } from '@utils/notify';
import VerificationDialog from '@components/cards/services/VerificationDialog.vue';

export default {
  props: ['common', 'model'],
  components: { VerificationDialog },
  data() {
    return {
      deleteConfim: false,
      deleteItem: null,
      openEditModal: false,
      formModel: {},
      pagination: {
        rowsPerPage: 0,
      },
      search: {
        goals: [],
        subjects: [],
      },
    };
  },
  methods: {
    get,
    toggleDeleteConfim(item = null) {
      this.deleteConfim = !this.deleteConfim;
      this.deleteItem = item;
    },
    deleteVerifItem() {
      try {
        this.card.verifications = this.verifications.filter(
          (i) => i.code !== this.deleteItem.code
        );
        this.$store.dispatch(
          'registryService/services/setCardForJson',
          this.card
        );
      } catch (e) {
        notifyError(e.message.toString());
      } finally {
        this.toggleDeleteConfim();
      }
    },

    editVerifItem(row) {
      this.$router.push({
        name: 'cards',
        params: {
          id: row.code,
          path: 'verifications',
        },
        query: {
          active: 'index',
          components: 'index',
          service: this.card.id,
        },
      });
    },
    commonModels(val) {
      this.$emit('commonModels', val);
    },

    goalManualVerificat(name) {
      const card = get(this, 'card', {});

      return (card.verifications || [])
        .filter((i) => i.type === name)
        .map((i) => {
          i.goal = [];
          const applicationConditions = i?.applicability?.application || {};
          const subjectConditions = i?.applicability?.subjects || [];

          const applicationConditionGoals = Object.keys(
            applicationConditions
          ).reduce((finalGoals, key) => {
            if (Array.isArray(applicationConditions[key])) {
              applicationConditions[key].forEach((condition) => {
                if (condition.attribute === 'statement.goal') {
                  if (Array.isArray(condition.value)) {
                    finalGoals = condition.value.concat(finalGoals);
                  } else {
                    finalGoals.push(condition.value);
                  }
                }
              });
            } else {
              if (applicationConditions[key].attribute === 'statement.goal') {
                if (Array.isArray(applicationConditions[key].value)) {
                  finalGoals = applicationConditions[key].value.concat(
                    finalGoals
                  );
                } else {
                  finalGoals.push(applicationConditions[key].value);
                }
              }
            }

            return finalGoals;
          }, []);

          const subjectConditionGoals = subjectConditions.reduce(
            (finalGoals, subjectCondition) => {
              if (!subjectCondition.conditions) return [];
              return finalGoals.concat(
                Object.keys(subjectCondition.conditions).reduce(
                  (finalGoals, key) => {
                    if (Array.isArray(subjectCondition.conditions[key])) {
                      subjectCondition.conditions[key].forEach((condition) => {
                        if (condition.attribute === 'statement.goal') {
                          if (Array.isArray(condition.value)) {
                            finalGoals = condition.value.concat(finalGoals);
                          } else {
                            finalGoals.push(condition.value);
                          }
                        }
                      });
                    } else {
                      if (
                        subjectCondition.conditions[key].attribute ===
                        'statement.goal'
                      ) {
                        if (
                          Array.isArray(subjectCondition.conditions[key].value)
                        ) {
                          finalGoals = subjectCondition.conditions[
                            key
                          ].value.concat(finalGoals);
                        } else {
                          finalGoals.push(
                            subjectCondition.conditions[key].value
                          );
                        }
                      }
                    }

                    return finalGoals;
                  },
                  []
                )
              );
            },
            []
          );

          i.goal = uniq([
            ...applicationConditionGoals,
            ...subjectConditionGoals,
          ]);

          return i;
        });
    },
    verificationFilter(rows, terms) {
      const filterByGoal = (row) =>
        !terms.goals.length ||
        !row.goal?.length ||
        row.goal.findIndex((g) => terms.goals.includes(g)) >= 0;

      const filterBySubject = (row) => {
        const subjectTypes = this.getSubjectTypesFromVerification(row);
        return (
          !terms.subjects.length ||
          !subjectTypes.length ||
          terms.subjects.find((s) => subjectTypes.includes(s.code))
        );
      };

      return rows.filter(filterByGoal).filter(filterBySubject);
    },
    getSubjectTypesFromVerification(v) {
      return v?.applicability?.subjects?.map((s) => s.subjectType) || [];
    },
    subjectLabel(code) {
      return (
        this.subjectTypesDictionary.find((d) => d.value === code)?.label || code
      );
    },
  },
  computed: {
    columns() {
      const headerStyle = 'font-size: 16px; font-weight: 600';
      return [
        {
          align: 'left',
          field: 'code',
          label: this.$t('VerificationsCard.code'),
          name: 'code',
          sortable: false,
          headerStyle,
        },
        {
          align: 'left',
          field: 'name',
          label: this.$t('VerificationsCard.name'),
          name: 'name',
          sortable: true,
          style: 'white-space: normal',
          headerStyle,
        },
        {
          align: 'left',
          field: 'invertLabel',
          label: this.$t('VerificationsCard.invertLabel'),
          name: 'invertLabel',
          sortable: true,
          style: 'white-space: normal',
          headerStyle,
        },
        {
          align: 'left',
          label: this.$t('VerificationsCard.goal'),
          name: 'goal',
          field: 'goal',
          sortable: true,
          sort: (a, b) => Math.min(...(a || [0])) - Math.min(...(b || [0])),
          style: 'white-space: normal',
          headerStyle,
        },
        {
          align: 'left',
          label: this.$t('VerificationsCard.subjectType'),
          name: 'subjectType',
          field: this.getSubjectTypesFromVerification,
          sortable: true,
          sort: (a, b) => Math.min(...(a || [0])) - Math.min(...(b || [0])),
          style: 'white-space: normal',
          headerStyle,
        },
      ];
    },
    manualVerifications() {
      return this.goalManualVerificat('manual');
    },
    autoVerifications() {
      const card = this.$store.getters['registryService/services/servicesCard'];
      return (card.verifications || []).filter((i) => i.type === 'auto');
    },
    state() {
      return get(this.card, 'state', 'inProgress');
    },
    loadingCard() {
      return (
        this.$store.getters['registryService/services/servicesLoading'] || false
      );
    },
    card() {
      return cloneDeep(
        this.$store.getters['registryService/services/servicesCard']
      );
    },
    goalColorMap() {
      return this.$store.getters['registryService/services/goalColorMap'];
    },
    verifications() {
      return get(this.card, 'verifications', []);
    },
    manualVerificationsGoals() {
      return uniq(
        (this.manualVerifications || []).flatMap((v) => v.goal || [])
      ).sort();
    },
    manualVerificationsSubjects() {
      return uniq(
        (this.manualVerifications || []).flatMap(
          (v) => v?.applicability?.subjects?.map((s) => s.subjectType) || []
        )
      )
        .sort()
        .map((code) => ({ code, label: this.subjectLabel(code) }));
    },
    subjectTypesDictionary() {
      const card = this.$store.getters['registryService/services/servicesCard'];
      return card.subjectsList || [];
    },
    subjectTypesDictId() {
      const card = this.$store.getters['registryService/services/servicesCard'];
      return `${card.name}_subject_types`;
    },
    canEdit(): boolean {
      return this.$store.getters['registryService/services/canEdit'];
    },
  },
};
</script>
