<i18n>
{
  "en": {
    "regions": {
      "organizationsCard": {
        "tree": "Hierarchy of organizations",
        "services": "Services",
        "name": "Name",
        "description": "Description",
        "emptyNodes": "No organizations"
      }
    }
  },
  "ru": {
    "regions": {
      "organizationsCard": {
        "tree": "Иерархия организаций",
        "services": "Услуги",
        "name": "Наименование",
        "description": "Описание",
        "emptyNodes": "Нет организаций"
      }
    }
  }
}
</i18n>

<template>
  <div v-if="common.active === 'organizations'" class="q-pb-md">
    <q-card class="no-shadow q-gutter-y-md q-mx-md no-border-radius">
      <q-card-section
        class="q-gutter-y-md bg-white q-pb-md q-pt-sm q-mt-md q-mx-md"
      >
        <q-card class="no-shadow q-pt-md q-px-md q-pb-lg" bordered>
          <div class="flex items-start justify-between">
            <div class="text-h6 text-grey-6 col q-pr-md">
              {{ $t('regions.organizationsCard.tree') }}
            </div>
          </div>
          <q-card-section>
            <q-tree
              v-if="organizations.length"
              ref="tree"
              node-key="id"
              children-key="leafs"
              :no-nodes-label="$t('regions.organizationsCard.emptyNodes')"
              :selected.sync="selected"
              selected-color="primary"
              text-color="grey-7"
              :nodes="organizations"
              @update:selected="getOrganizationInfo"
            />
          </q-card-section>
        </q-card>
      </q-card-section>
      <q-card-section
        class="q-gutter-y-md bg-white q-px-lg q-pb-md q-pt-sm q-mt-md q-mx-lg"
      >
        <FormGeneratorWrapper
          v-if="!loading && selected"
          :model="formModel"
          :schema="formSchema"
          :hide-nulls="true"
        />
        <q-btn
          v-if="isOrganization(currentOrganization)"
          @click="openOrganization(currentOrganization.id)"
          outline
          color="primary"
          :label="$t('entities.organization.actions.open')"
        />
      </q-card-section>
      <q-card-section
        v-if="tableData.length"
        class="q-gutter-y-md bg-white q-pb-md q-pt-sm q-mt-md q-mx-md"
      >
        <q-card
          v-if="!loading && selected"
          class="no-shadow q-pt-md q-pr-md q-pb-lg"
          bordered
        >
          <q-table
            class="no-shadow text-grey-9"
            row-key="id"
            :title="$t('regions.organizationsCard.services')"
            title-class="text-grey-6 text-h6"
            table-class="q-pl-md"
            :columns="tableColumns"
            :data="tableData"
            wrap-cells
            hide-bottom
          >
          </q-table>
        </q-card>
      </q-card-section>
      <q-inner-loading :showing="loading">
        <q-spinner-gears size="50px" color="primary" />
      </q-inner-loading>
    </q-card>
  </div>
</template>

<script lang="ts">
// @ts-nocheck

import { LinksApi } from '@openapi/registry-service';
import { GraphApi } from '@openapi/idm';
import FormGeneratorWrapper from '@components/common/node-generator/FormGeneratorWrapper.vue';
import get from 'lodash/get';
import has from 'lodash/has';
import { notifyError } from '@utils/notify';

const linksApi = new LinksApi();
const graphApi = new GraphApi();

export default {
  components: {
    FormGeneratorWrapper,
  },
  props: ['common', 'model'],

  data() {
    return {
      schemaCode: 'Regions_OrganizationInfo',
      selected: null,
      currentOrganization: null,
      formSchema: null,
      tree: null,
    };
  },

  computed: {
    loading() {
      return this.selected ? !this.currentOrganization : false;
    },
    organizations() {
      if (this.tree) {
        this.serializeTreeToValidFormat(this.tree);
        return [this.tree];
      } else {
        return [];
      }
    },
    formModel() {
      if (
        this.currentOrganization &&
        this.formSchema &&
        Array.isArray(get(this.formSchema, 'attrList'))
      ) {
        const dataFormObject = {};
        this.formSchema.attrList.forEach((attr) => {
          if (has(this.currentOrganization, `${attr.name}`)) {
            dataFormObject[attr.name] = this.currentOrganization[attr.name];
          }
        });
        return dataFormObject;
      } else {
        return null;
      }
    },
    tableColumns() {
      return [
        {
          align: 'left',
          field: 'name',
          name: 'name',
          sortable: false,
          label: this.$t('regions.organizationsCard.name'),
          headerStyle: 'font-size: 14px; width: 200px;',
        },
        {
          align: 'left',
          field: 'description',
          name: 'description',
          sortable: false,
          label: this.$t('regions.organizationsCard.description'),
          headerStyle: 'font-size: 14px;',
        },
      ];
    },
    tableData() {
      if (
        this.currentOrganization &&
        Array.isArray(get(this.currentOrganization, 'services'))
      ) {
        const rows = [];
        this.currentOrganization.services.forEach((item) => {
          rows.push({
            name: item.shortName,
            description: item.fullName,
          });
        });
        return rows;
      } else {
        return [];
      }
    },
  },

  watch: {
    'model.id': function (val) {
      if (val) {
        this.initCard();
      }
    },
  },

  methods: {
    initCard() {
      this.getOrganizationsTree().then((tree) => {
        this.tree = tree;
        this.getFormSchema();
      });
    },
    getOrganizationsTree() {
      return graphApi
        .tree(
          'Region',
          'incoming',
          this.model.id,
          2,
          ['Organization'],
          ['parent']
        )
        .then(({ data }) => data)
        .catch((e) => {
          notifyError(e.message.toString());

          throw new Error(
            '[components][cards][regions][Organizations][graphApi]'
          );
        });
    },
    getFormSchema() {
      // TODO : Request this from SchemaRegistry. This one requests a static common one
      // Have to make a registry/ui for common schemas
      this.$store
        .dispatch('utils/components/fetchModelByCode', this.schemaCode)
        .then((schema) => {
          this.formSchema = schema;
        })
        .catch(() => {
          notifyError(this.$t('StatementCard.errorLoadingModel'));
        });
    },
    getOrganizationInfo(key) {
      if (!key) return false;

      this.currentOrganization = null;
      this.getOrganizationServices(key).then(({ data }) => {
        this.currentOrganization = this.searchCurrentValue(key, this.tree);
        this.currentOrganization.services = data || [];
      });
    },
    getOrganizationServices(key) {
      return linksApi.searchLinks('Organization', key, 'Service');
    },
    setFormModel(data) {
      this.formModel = null;
      if (this.formSchema && Array.isArray(get(this.formSchema, 'attrList'))) {
        const dataFormObject = {};
        this.formSchema.attrList.forEach((attr) => {
          if (has(data, `${attr.name}`)) {
            dataFormObject[attr.name] = data[attr.name];
          }
        });
        this.formModel = dataFormObject;
      }
    },
    // Recursive function to set labels for quasar tree
    serializeTreeToValidFormat(tree) {
      tree.label = get(tree, 'value.shortname') || '';
      tree.id = get(tree, 'value.id');
      if (Array.isArray(tree.leafs)) {
        tree.leafs.forEach((item) => {
          this.serializeTreeToValidFormat(item);
        });
      }
    },
    // Recursive search current value
    searchCurrentValue(id, tree) {
      if (get(tree, 'value.id') === id) {
        return tree.value;
      } else if (Array.isArray(tree.leafs)) {
        for (let i = 0; i < tree.leafs.length; i++) {
          const result = this.searchCurrentValue(id, tree.leafs[i]);
          if (result !== false) {
            return result;
          }
        }
        return false;
      } else {
        return false;
      }
    },
    openOrganization(id) {
      this.$router.push({
        name: 'organization',
        params: {
          id,
        },
      });
    },
    isOrganization(currentOrganization) {
      return currentOrganization
        ? currentOrganization.schema === 'Organization'
        : false;
    },
  },
};
</script>
