import ReTable from '@/recruits/components/common/r-table/index.vue';
import UrlIntegratedSearch from '@/recruits/mixins/url-integrated-search';
import { UrlQueryParams } from '@/recruits/models';
import { RTableColumn } from '@/interfaces';
import { prepareApiParams } from '@/recruits/utils/prepare-api-params';
import SortBar from '@/recruits/components/common/sort-bar.vue';
import SearchBar from './components/search-bar.vue';
import { QSelectOption } from '@/models/models-ui';
import { Component, Mixins, Watch } from 'vue-property-decorator';
import { USER_SCOPES } from '@/constants/entities/Scope';
import { DomainApi, Organization, Department } from '@openapi/idm';
import Centered1280Box from '@/recruits/components/common/centered-1280-box.vue';
import WhiteCard from '@/recruits/components/common/white-card.vue';
import IconCell from '@/recruits/components/common/cells/icon/index.vue';
import LinkCell from '@/recruits/components/common/cells/link.vue';
import {
  OrganizationsSearchFilter,
  ALL_QUERY_TYPE,
  DEPARTMENTS_QUERY_TYPE,
  ORGANIZATIONS_QUERY_TYPE,
} from './components/organizations-search-filter';
import RSelect from '@/recruits/components/common/r-select.vue';
import CreateModal from './components/CreateModal.vue';
const domainApi = new DomainApi();

@Component({
  components: {
    SortBar,
    ReTable,
    SearchBar,
    Centered1280Box,
    WhiteCard,
    IconCell,
    LinkCell,
    RSelect,
    CreateModal,
  },
})
export default class Organizations extends Mixins(UrlIntegratedSearch) {
  private sortByDefault = 'modified';

  private subjectsType: Array<QSelectOption> = [
    {
      label: 'Все',
      value: ALL_QUERY_TYPE,
    },
    {
      label: 'Организации',
      value: ORGANIZATIONS_QUERY_TYPE,
    },
    {
      label: 'Подразделения',
      value: DEPARTMENTS_QUERY_TYPE,
    },
  ];

  get handler(): 'myRegion' | 'my' | 'managed' | undefined {
    if (this.$AC.haveScope(USER_SCOPES.SECURITY_ADMINISTRATOR)) {
      return undefined;
    }
    if (this.$AC.haveScope(USER_SCOPES.MILITARY_COMMISSARIAT_ADMINISTRATOR)) {
      return 'my';
    }
    return 'my';
  }

  /**
   * Computed свойство проверяющее возможность просмотра подразделения и возможность кликать в селектор
   */
  get canChangeSubjectType(): boolean {
    return (
      !this.$AC.haveScope(USER_SCOPES.MILITARY_COMMISSARIAT_ADMINISTRATOR) ||
      this.$AC.haveScope(USER_SCOPES.SECURITY_ADMINISTRATOR)
    );
  }

  modalCreateOrganization = false;

  public data: Array<Organization | Department> | undefined = [];
  public filter = new OrganizationsSearchFilter();

  public sortButtons: Array<{ label: string; value: string }> = [
    { label: 'По наименованию', value: 'fullname' },
    { label: 'По ИНН', value: 'inn' },
    { label: 'По ОГРН', value: 'ogrn' },
  ];

  public finishCreateOrganization(): void {
    this.modalCreateOrganization = false;
    this.executeSearch();
  }

  public async fetchData(
    query: UrlQueryParams
  ): Promise<{ totalRows: number | undefined }> {
    const params = prepareApiParams(query);
    const searchFields = ['fullname', 'inn', 'ogrn'];
    const condition = 'or';
    const escapeString = function (term: string) {
      term = term.replace(/\\/g, '');
      term = term.replace(/'/g, "\\'");
      term = term.replace(/"/g, '\\"');
      return term;
    };
    const generateQuery = (fields: string[], term: string): string => {
      return fields
        .flatMap((field) => [
          `${field}=searchphrase="${escapeString(term)}"`,
          `${field}=search="${escapeString(term)}"`,
        ])
        .join(` ${condition} `);
    };

    const arrFulltext: (string | null)[] = [
      params.search.search
        ? generateQuery(searchFields, params.search.search)
        : null,
    ];

    const fulltext = arrFulltext
      .filter((filter: string | null) => !!filter)
      .join(' and ');

    let querySchema = 'schema=in=(Organization,Department)';

    // При возможности менять селект добалвем проверку от переменной
    // чтобы избежать хака с изменением урл и получением данных
    if (this.canChangeSubjectType) {
      switch (this.filter.subjectType) {
        case DEPARTMENTS_QUERY_TYPE:
          querySchema = 'schema==Department';
          break;
        case ORGANIZATIONS_QUERY_TYPE:
          querySchema = 'schema==Organization';
          break;
      }
    }

    const { data } = await domainApi.pagingDomains(
      this.handler,
      params.pagination.page,
      params.pagination.rowsPerPage,
      querySchema,
      fulltext,
      `${params.pagination.descending === 'false' ? '+' : '-'}${
        params.pagination.sortBy || this.sortByDefault
      }`
    );
    this.data = data.records || [];
    return {
      totalRows: data.totalRows,
    };
  }

  get columns(): RTableColumn<Array<Organization | Department>>[] {
    const defaultColumns = [
      {
        name: 'fullname',
        label: 'Полное наименование',
        field: 'fullname',
        width: '2fr',
      },
      {
        name: 'inn',
        label: 'ИНН',
        field: 'inn',
      },
      {
        name: 'ogrn',
        label: 'ОГРН',
        field: 'ogrn',
      },
    ];
    if (this.filter.subjectType !== DEPARTMENTS_QUERY_TYPE) {
      defaultColumns.push({
        name: 'enabled',
        label: 'Блокировка',
        field: 'enabled',
      });
    }
    return defaultColumns;
  }

  // Функция проверяющая активна ли еще организация
  // Если активна возвращает строку 'icon', в противоположном случае - ''
  isShowIcon(domain: Organization | Department): 'icon' | '' {
    return !domain.enabled && domain.schema?.toLowerCase() !== 'department'
      ? 'icon'
      : '';
  }

  // computed свойство нужно ли показывать кнопку
  get canCreate(): boolean {
    return this.$AC.haveOneOfScope([
      USER_SCOPES.CLOUD_ADMIN,
      USER_SCOPES.REGION_ADMIN,
      USER_SCOPES.ORGANIZATION_ADMIN,
      USER_SCOPES.SECURITY_ADMINISTRATOR,
    ]);
  }

  // Если изменился r-select то перезапускаем поиск
  @Watch('filter.subjectType')
  private handlerFilterSubjectType(): void {
    this.executeSearch();
  }
}
