<i18n>
{
  "ru": {
    "OfficeSelect": {
      "areaId": "Номер кабинета",
      "nsiSelect": "Выбрать номер кабинета из ЕСНСИ",
      "cancel": "Отмена",
      "edit": "Сохранить",
      "add": "Добавить",
      "columns": {
        "name": "Кабинет"
      },
      "error": {
        "notValid": "Содержит недопустимые символы",
        "notUniq": "Расписание для этого кабинета существует"
      }
    }
  },
  "en": {
    "OfficeSelect": {
      "areaId": "Area id",
      "nsiSelect": "Select from NSI",
      "cancel": "Cancel",
      "edit": "Save",
      "add": "Select",
      "columns":  {
        "name": "Office"
      },
      "error": {
        "notValid": "Not valid",
        "notUniq": "Not uniq"
      }
    }
  }
}
</i18n>
<template>
  <div class="service-select">
    <q-dialog v-if="fromFps" v-model="popup" persistent>
      <q-card
        :title="$t('OfficeSelect.nsiSelect')"
        :style="{
          maxWidth: '80vw',
          width: '700px',
        }"
      >
        <q-card-section>
          <div class="select-table">
            <q-table
              dense
              :title="$t('OfficeSelect.nsiSelect')"
              class="no-shadow text-grey-9"
              row-key="id"
              :selected-rows-label="
                (number) => $tc('OfficeSelect.selected', number)
              "
              :rows-per-page-options="[5, 10, 15]"
              :columns="columns"
              :grid="$q.screen.xs"
              :loading="loading"
              :data="model"
            >
              <template v-slot:body-selection="scope">
                <q-checkbox v-model="scope.selected" />
              </template>
              <template v-slot:body-cell-title="scope">
                <q-td :props="scope">
                  <div class="row">
                    <q-chip
                      :clickable="!validateAreaId(scope.row.title).length"
                      :text-color="
                        validateAreaId(scope.row.title).length
                          ? 'grey-8'
                          : 'black'
                      "
                      @click="save(scope.row.id, scope.row.title)"
                    >
                      {{ scope.row.title }}
                    </q-chip>
                    <div
                      class="text-red-3 q-py-sm"
                      v-for="error in validateAreaId(scope.row.title)"
                      :key="error"
                    >
                      {{ $t(`OfficeSelect.error.${error}`) }}
                    </div>
                  </div>
                </q-td>
              </template>
            </q-table>
          </div>
        </q-card-section>
        <q-card-actions align="right">
          <q-btn
            dense
            text-color="primary"
            color="white"
            flat
            :label="$t('OfficeSelect.cancel')"
            v-close-popup
          />
        </q-card-actions>
      </q-card>
    </q-dialog>
    <q-dialog v-else v-model="popup" persistent>
      <q-card style="min-width: 350px">
        <q-card-section>
          <div class="text-h6">{{ $t('OfficeSelect.areaId') }}</div>
        </q-card-section>

        <q-card-section class="q-pt-none">
          <q-input dense v-model="areaId" autofocus @keyup.enter="closePopup" />
          <div
            class="text-red-3 q-py-sm"
            v-for="error in validateAreaId(areaId)"
            :key="error"
          >
            {{ $t(`OfficeSelect.error.${error}`) }}
          </div>
        </q-card-section>

        <q-card-actions align="right" class="text-primary">
          <q-btn flat :label="$t('OfficeSelect.cancel')" v-close-popup />
          <q-btn
            dense
            text-color="primary"
            color="white"
            :disable="!isValid"
            @click="save(areaId, areaId)"
          >
            {{ $t(`OfficeSelect.${action}`) }}
          </q-btn>
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

<script lang="ts">
import { Component, Prop, PropSync, Vue, Watch } from 'vue-property-decorator';
import { ScheduleDTO } from '@openapi/preorder-pgs';
import get from 'lodash/get';
import { notifyError } from '@utils/notify';
import { TableColumn } from '@/interfaces';
import { FpsOfficeDocument, searchRegistryBy } from '../utils/nsiService';

interface Pagination {
  page?: number;
  rowsPerPage?: number;
  descending?: boolean;
  sortBy?: string;
  rowsNumber?: number;
}
interface TableContext {
  pagination: Pagination;
}

@Component({})
export default class OfficeSelect extends Vue {
  @PropSync('open') popup: boolean;
  @PropSync('id') areaId: string;
  @PropSync('name') areaName: string;
  @Prop({ default: false }) fromFps: boolean;
  @Prop({ default: () => [] }) areaIdslist: string[];
  @Prop({ default: () => [] }) schedules: ScheduleDTO[];
  @Prop({ default: 'add' }) action: 'edit' | 'add';
  @Prop({ default: '' }) fpsCode: string;

  oldAreaId = '';
  oldAreaName = '';

  loading = false;

  public openPopup(): void {
    this.popup = true;
  }

  public closePopup(): void {
    this.popup = false;
  }

  model: FpsOfficeDocument[] = [];
  pagination: Pagination = {
    page: 1,
    rowsPerPage: 5,
    descending: false,
    sortBy: 'title',
    rowsNumber: 0,
  };

  queryString = '';
  fulltextString = '';

  get columns(): TableColumn<FpsOfficeDocument>[] {
    return [
      {
        align: 'left',
        field: (val) => get(val, 'title', ''),
        label: this.$t('OfficeSelect.columns.name'),
        name: 'title',
        sortable: true,
        handlerField: 'id',
        icon: 'people_outline',
      },
    ];
  }

  get userDomainId(): string {
    return get(this.$store.getters['oidcClient/currentUser'], 'domain_id', '');
  }

  save(areaId?: string, areaIName?: string): void {
    this.areaId = areaId || '';
    this.$emit('save', areaId, areaIName);
    this.closePopup();
  }

  @Watch('open', { immediate: true })
  onOpenChange(open: boolean): void {
    if (open) {
      this.fetch();
      this.oldAreaId = this.areaId;
    } else {
      this.oldAreaId = this.areaId = '';
    }
  }

  async fetch(): Promise<void> {
    if (!this.fpsCode) return;
    this.loading = true;
    this.model = [];
    try {
      const data = await searchRegistryBy<FpsOfficeDocument>(
        'PGS_FPS_office',
        this.pagination.page,
        this.pagination.rowsPerPage,
        `codeFPS==${this.fpsCode}`
      );

      this.model = get(data, 'records').filter((office) => {
        return !this.areaIdslist.includes(office.id);
      });
    } catch (error) {
      if (error instanceof Error) notifyError(error.message);
    }
    this.loading = false;
  }

  validateAreaId(areaId: string): string[] {
    const errors = [];

    if (/[$%&*+\-=@#!\\/|]/g.test(areaId)) errors.push('notValid');
    if (this.oldAreaId !== areaId && this.areaIdslist.includes(areaId)) {
      errors.push('notUniq');
    }
    return errors;
  }

  get isValid(): boolean {
    return !this.validateAreaId(this.areaId).length;
  }
}
</script>

<style lang="scss" scoped>
.service-select {
  &__name {
    text-transform: uppercase;
  }
  &__floating-badge {
    position: absolute;
    top: 6px;
    right: 5px;
  }
}
.select-table {
  &__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-left: 1rem;
    padding-right: 1rem;
  }
  &__title {
    font-size: 1.25rem;
  }
}
</style>
