<i18n>
{
  "en": {
    "statements": {
      "RoutingDialog": {
        "dataTitle": "Statement data",
        "departmentName": "Department name",
        "errorTitle": "Select a region to redirect your sa",
        "error": "For the selected region value, there is no branch available that provides a referral service. Change the address or contact the situation center",
        "serviceRegion": "Service region",
        "regionPlaceholder": "Enter the region",
        "empty": "No available values",
        "departmentPlaceholder": "Select department",
        "department": "Department",
        "redirect": "Redirect",
        "comments": "Comments"
      }
    }
  },
  "ru": {
    "statements": {
      "RoutingDialog": {
        "dataTitle": "Данные заявления",
        "departmentName": "Наименование ведомства",
        "errorTitle": "Выберите регион для перенаправления заявления",
        "error": "Для выбранного региона нет ни одного доступного отделения, оказывающего услугу для перенаправления. Измените адрес или обратитесь в ситуационный центр",
        "serviceRegion": "Регион оказания услуги",
        "regionPlaceholder": "Введите регион",
        "empty": "Нет доступных значений",
        "departmentPlaceholder": "Выберите ведомство",
        "department": "Ведомство",
        "redirect": "Перенаправить",
        "comments": "Комментарий"
      }
    }
  }
}
</i18n>

<template>
  <div>
    <div
      v-if="$slots.button"
      class="cursor-pointer"
      v-bind="button.props"
      @click="doAction"
    >
      <slot name="button"> </slot>
    </div>
    <q-btn
      v-else
      :disable="disableAllButtons"
      class="q-ml-sm"
      padding="6px"
      flat
      v-bind="buttonProps"
      @click="doAction"
    >
      <q-tooltip v-if="get(buttonSettings, 'tooltip')">
        {{ get(buttonSettings, 'tooltip') }}
      </q-tooltip>
    </q-btn>
    <q-dialog v-model="value">
      <q-card class="no-shadow" style="max-width: 80vw; width: 700px">
        <q-card-section>
          <div class="text-h6">
            {{ get(buttonSettings, 'tooltip') }}
          </div>
        </q-card-section>
        <q-card-section class="q-p">
          <div class="text-h7">
            {{ $t('statements.RoutingDialog.dataTitle') }}
          </div>
          <div class="q-gutter-y-md q-py-md">
            <div class="row">
              <div class="col-6 text-grey-5">
                {{ $t('statements.RoutingDialog.serviceRegion') }}
              </div>
              <div class="col-5 text-grey-7">{{ currentRegionName }}</div>
            </div>
            <div class="row">
              <div class="col-6 text-grey-5">
                {{ $t('statements.RoutingDialog.departmentName') }}
              </div>
              <div class="col-5 text-grey-7">{{ currentDepartmentName }}</div>
            </div>
          </div>
          <q-slide-transition>
            <div v-show="isWarning">
              <div class="text-h7">
                {{ $t('statements.RoutingDialog.errorTitle') }}
              </div>
              <q-banner
                class="q-pa-md q-my-md"
                rounded
                style="
                  background-color: #fedd9c;
                  border-left: 5px solid #ffc655;
                  border-right: 5px solid #ffc655;
                "
              >
                <div class="text-weight-bold">
                  {{ $t('statements.RoutingDialog.error') }}
                </div>
              </q-banner>
            </div>
          </q-slide-transition>
          <template v-if="hasApproveOrganisation">
            <div class="q-my-sm text-grey-7">
              {{ $t('statements.RoutingDialog.departmentName') }}
            </div>
            <q-select
              filled
              use-input
              v-model="selectedOrganization"
              hide-selected
              fill-input
              input-debounce="500"
              :options="organisations"
              option-value="id"
              option-label="fullname"
              :placeholder="$t('statements.RoutingDialog.department')"
            />
          </template>
          <template v-else>
            <div class="q-my-sm text-grey-7">
              {{ $t('statements.RoutingDialog.serviceRegion') }}
            </div>
            <BaseAutocompleteSelect
              :model.sync="region"
              :async-getter="getRegions"
              label-value="fullname"
              :field-label="$t('statements.RoutingDialog.regionPlaceholder')"
              :is-multiple="false"
              @value="inputRegion"
            />
            <div class="q-my-sm text-grey-7">
              {{ $t('statements.RoutingDialog.departmentName') }}
            </div>
            <BaseTreeSelector
              :label="$t('statements.RoutingDialog.department')"
              tree-label="fullname"
              :current-request-id="selectedRegionId"
              :selected-value.sync="selectedOrganization"
              :selected-label.sync="selectedOrganizationLabel"
              :values-to-filter="filteredValues"
              @empty="isWarning = true"
              schema="Region"
              :schemas="['Organization']"
              :links="['parent']"
              @update:selectedValue="getDepartments(selectedOrganization)"
            />
            <div v-if="departments && departments.length" class="q-my-sm text-grey-7">
              {{ $t('statements.RoutingDialog.departmentLabel') }}
            </div>
            <q-select
              filled
              hide-dropdown-icon
              use-input
              v-if="departments && departments.length"
              v-model="selectDepartment"
              hide-selected
              fill-input
              input-debounce="1000"
              :options="departmentsByFilter"
              option-value="id"
              @filter="filterFn"
              option-label="fullname"
              :placeholder="$t('statements.RoutingDialog.department')"
              ><template #append> <q-icon name="search" /> </template>
            </q-select>
          </template>
          <div class="q-my-sm text-grey-7">
            {{ $t('statements.RoutingDialog.comments') }}
          </div>
          <q-input
            v-model="comment"
            dense
            type="textarea"
            :rows="5"
            :resize="false"
            filled
          />
        </q-card-section>
        <q-card-actions class="q-pa-md" align="left">
          <q-btn
            :disable="!selectedOrganization"
            :label="$t('statements.RoutingDialog.redirect')"
            unelevated
            color="primary"
            @click="submit"
          />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

<script lang="ts">
import BaseTreeSelector from '@components/common/base-tree-selector/index.vue';
import { LinksApi, Document } from '@openapi/registry-service';
import {
  LinksApi as LinksApiIdm,
  RegionApi,
  Region,
  DepartmentAllOf,
  OrganizationApi,
  Organization,
} from '@openapi/idm';
import { notifyError } from '@utils/notify';
import get from 'lodash/get';
import { Component, Prop, Vue } from 'vue-property-decorator';
import ButtonSettings from '@interfaces/entities/ButtonSettings';
import { AxiosResponse } from 'axios';

const organizationApi = new OrganizationApi();

const linksApi = new LinksApi();
const linksApiIdm = new LinksApiIdm();
const regionApi = new RegionApi();

@Component({
  components: { BaseTreeSelector },
  methods: { get },
})
export default class RoutingDialog extends Vue {
  @Prop() model: any;
  @Prop() disableAllButtons: boolean;
  @Prop() userTask: any;
  @Prop() buttonSettings: ButtonSettings;

  private button = {
    props: {
      color: 'primary',
      label: 'Просмотр',
      loading: false,
    },
  };

  private selectedRegionId = '';
  private currentDepartmentName = '';
  private currentRegionName = '';
  private isWarning = false;
  private hasApproveOrganisation = false;
  private comment = '';
  private selectedOrganization: { id: string; fullname: string } | null = null;
  private selectedOrganizationLabel = null;
  private value = false;
  private filteredValues: Document[] | null = null;
  private departments: Document[] | null = null;
  private departmentsByFilter: Document[] | null = null;
  private organisations: Organization[] | null = null;
  private selectDepartment: DepartmentAllOf | null = null;
  private region = {
    search: '',
    records: [],
    selected: [],
    loading: false,
  };

  get buttonProps() {
    return get(this.buttonSettings, 'props', {});
  }

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

  async getOrganization(): Promise<Organization> {
    const currentUser = this.$store.getters['oidcClient/currentUser'];
    const organization = await this.$store.dispatch(
      'idm/organizations/getOrganization',
      { id: currentUser.domain_id }
    );
    return organization;
  }

  private async getRegions() {
    try {
      this.region.loading = true;
      const fulltextString = this.region.search
        ? `(fullname=searchprefix="${this.region.search}" or fullname=search="${this.region.search}") or (code=searchprefix="${this.region.search}" or code=search="${this.region.search}")`
        : '';
      const { data: records } = await regionApi.searchRegions(
        undefined,
        '',
        fulltextString
      );
      return records;
    } catch (e) {
      notifyError(e.toString());
    } finally {
      this.region.loading = false;
    }
  }

  private async doAction() {
    this.currentDepartmentName = get(this.model, 'system.department.fullName');

    const { data: currentRegion } = await regionApi
      .getRegion(this.model.system.regionId)
      .catch(() => {
        throw new Error(
          '[components][cards][statements][RoutingDialog][graphApi]'
        );
      });

    this.currentRegionName = currentRegion.name;
    this.getApproveOrganisation();
    this.value = true;
  }

  private async getDepartments(parentId: string): Promise<void> {
    if (parentId) {
      const { data: response } = ((await linksApiIdm
        .searchLinks('Organization', parentId, 'Department')
        .catch((e) => notifyError(e.toString()))) as unknown) as AxiosResponse<
        Document[]
      >;
      this.departments = response;
      this.departmentsByFilter = response
      this.selectDepartment = null
    } else {
      this.selectDepartment = null;
      this.departments = null;
      this.departmentsByFilter = null
    }
  }

  private async inputRegion(regionObject: Region): Promise<void> {
    if (regionObject) {
      const { data: regions } = ((await linksApi
        .searchLinks(
          'Service',
          this.serviceCard.id,
          'Organization',
          `regionId==${get(regionObject, 'id', '')}`
        )
        .catch((e) => notifyError(e.toString()))) as unknown) as AxiosResponse<
        Document[]
      >;
      this.filteredValues = regions;
      this.selectedRegionId = get(regionObject, 'id', '');
      this.isWarning = false;
      this.selectedOrganization = null;
    } else {
      this.selectedOrganization = null;
      this.selectedOrganizationLabel = null;
      this.filteredValues = null;
      this.selectDepartment = null;
      this.departments = null;
      this.departmentsByFilter = null;
      this.selectedRegionId = '';
    }
  }

  async getApproveOrganisation(): Promise<void> {
    this.hasApproveOrganisation = !!this.model?.approveRoute?.length;
    const myOrg = await this.getOrganization();
    const approveOrganisationIdList =
      this.model?.approveRoute &&
      this.model?.approveRoute?.reduce(
        (acc: string[], route: { idOrg: string; subOrgs?: string[] }) => {
          if (myOrg.id === route.idOrg || route.subOrgs?.includes(myOrg.id)) {
            acc.push(route.idOrg);
            route.subOrgs?.length &&
              route.subOrgs.forEach((org: string) => {
                return acc.push(org)});
            return acc;
          }
          return acc;
        }, []);
    if (approveOrganisationIdList && approveOrganisationIdList?.length) {
      const orgs = await organizationApi
        .searchOrganizations(
          undefined,
          `id=in=(${approveOrganisationIdList.join(',')})`
        )
        .then(({ data }) => data)
        .catch(() => {
          this.organisations = [];
        });
      this.organisations = orgs || [];
    }
  }

  private filterFn(value: string, update: any):void {
    if (value === '') {
      update(() => {
        this.departmentsByFilter = this.departments
      })
      return
    }

    update(() => {
      if (this.departments) {
        const needle = value.toLowerCase()
        this.departmentsByFilter = this.departments.filter((v:any) => {
          if (v.fullname) {
            return v.fullname.toLowerCase().indexOf(needle) > -1
          }
        })
      }
    })
  }

  submit(): void {
    let data = {};
    if (this.hasApproveOrganisation) {
      data = {
        departmentId: this.selectedOrganization?.id,
        departmentName: this.selectedOrganization?.fullname,
        comment: this.comment,
      };
    } else {
      data = {
        departmentId: this.selectDepartment
          ? this.selectDepartment.id
          : this.selectedOrganization,
        departmentName: this.selectDepartment
          ? this.selectDepartment.fullname
          : this.selectedOrganizationLabel,
        comment: this.comment,
      };
    }
    this.$emit('submit', {
      buttonId: 'routing',
      data: data,
      force: true,
    });

    this.value = false;
  }
}
</script>
