<template>
  <widget-wrapper v-bind="$props" ref="widget">
    <template v-if="entityType === 'ЮЛ'">
      <ULSearchForm :formTitle="formTitle" :searching="isSearching" @search="onSearch" />
    </template>
    <template v-else-if="entityType === 'ИП'">
      <IPSearchForm :formTitle="formTitle" :searching="isSearching" @search="onSearch" />
    </template>
    <template v-else> <!-- ФЛ по умолчанию -->
      <FLSearchForm :formTitle="formTitle" :searching="isSearching" @search="onSearch" />
    </template>

    <q-dialog v-model="showPickDialog">
      <q-card style="width: 700px; max-width: 80vw;">
        <q-card-section>
          <div class="text-h6">{{ label }}</div>
        </q-card-section>
        <q-card-section class="q-pt-none">
          <template v-if="entityType === 'ЮЛ'">
            <ULSearchResultTable
              :data="foundEntities"
              :pagination="pagination"
              :loading="isSearching"
              @request="onPageChange"
              @row-click="onRowClick"
            />
          </template>
          <template v-else-if="entityType === 'ИП'">
            <IPSearchResultTable
              :data="foundEntities"
              :pagination="pagination"
              :loading="isSearching"
              @request="onPageChange"
              @row-click="onRowClick"
            />
          </template>
          <template v-else> <!-- ФЛ по умолчанию -->
            <FLSearchResultTable
              :data="foundEntities"
              :pagination="pagination"
              :loading="isSearching"
              @request="onPageChange"
              @row-click="onRowClick"
            />
          </template>
        </q-card-section>
        <q-card-actions align="right" class="bg-white text-teal">
          <q-btn flat label="Отмена" v-close-popup />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </widget-wrapper>
</template>
  
<script lang="ts">
import { Component, Mixins, Prop } from 'vue-property-decorator';
import {
  FormWidget,
  WidgetWrapper,
} from '@devsun/form-generator/dist';
import { TablePagination } from '@models/base/TablePagination';
import {
  PersonalAccountApi,
} from '@/openapi/personal-accounts';
import { DocumentApi } from '@openapi/document-registry';
import FLSearchForm from './entity-search/FLSearchForm.vue';
import IPSearchForm from './entity-search/IPSearchForm.vue';
import ULSearchForm from './entity-search/ULSearchForm.vue';
import FLSearchResultTable from './entity-search/FLSearchResultTable.vue';
import ULSearchResultTable from './entity-search/ULSearchResultTable.vue';
import IPSearchResultTable from './entity-search/IPSearchResultTable.vue';
import { extractValues, defaultProps, getExpands } from './entity-search/extract-mappings';

const personalAccountApi = new PersonalAccountApi();
const documentApi = new DocumentApi();

import {
  FormWidget,
  WidgetWrapper,
} from '@devsun/form-generator/dist';

@Component({
  inheritAttrs: false,
  components: {
    WidgetWrapper,
    FLSearchForm, IPSearchForm, ULSearchForm,
    FLSearchResultTable, ULSearchResultTable, IPSearchResultTable
  },
})
export default class EntitySearchForm extends Mixins(
  FormWidget
) {
  @Prop() formTitle: string;
  @Prop() propertyPath: string;
  @Prop() entityType: string; // ФЛ / ИП / ЮЛ - по умолчанию должен работать как ФЛ
  @Prop() extract: any; // extract: конфигурация с mapping-ом (пример в методе defaultProps(propPath))

  protected showPickDialog = false;
  private searchCriteria = {};

  foundEntities = [];

  isSearching = false;

  pagination = new TablePagination();

  get label(): string {
    return this.fieldNode?.rawAttrs?.label || 'Результаты поиска';
  }

  async selectEntity(rowId) {
    const selectedEntity: any = this.foundEntities.find(e => e.id === rowId);
    let extractedResults = extractValues(selectedEntity, this.extract || defaultProps(this.propertyPath, this.entityType));
    for (const [obj, path] of extractedResults) {
      await this.$store.commit('formGenerator/setFoundPerson', { obj, path });
    }
    this.showPickDialog = false;
  }

  async onSearch(searchCriteria) {
    this.searchCriteria = searchCriteria;

    this.isSearching = true;
    try {
      if (this.entityType === 'ЮЛ' || this.entityType === 'ИП') {
        await this.searchInDocumentRegistry(searchCriteria);
      } else { // ФЛ
        await this.searchInPersonalAccount(searchCriteria);
      }
    } finally {
      this.isSearching = false;
    }
  }

  async searchInPersonalAccount(searchCriteria, commonRequestProperties: Partial<TablePagination> = {}) {
    let searchOptions = {
      ...searchCriteria,
      ...commonRequestProperties,
    };
    Object.assign(searchOptions, {
      //expand: "persondocument,contactdata,personaddress"
      expand: getExpands(this.extract || defaultProps(this.propertyPath)).join(',')
    });
    const {
      data: { records: persons, totalRows, page, perPage }, 
    } = await personalAccountApi.fullSearchPerson(searchOptions);

    this.pagination.rowsNumber = totalRows;
    this.pagination.page = page;
    this.pagination.rowsPerPage = perPage;

    this.foundEntities = persons || [];
    this.showPickDialog = true;
  }

  async searchInDocumentRegistry(searchCriteria, commonRequestProperties: Partial<TablePagination> = {}) {
    const filters: Array<string> = [];
    if (searchCriteria.inn) {
      filters.push(`inn==${searchCriteria.inn}`);
    }
    if (this.entityType === "ЮЛ" && searchCriteria.ogrn) {
      filters.push(`ogrn==${searchCriteria.ogrn}`);
    }
    if (this.entityType === "ИП" && searchCriteria.ogrnip) {
      filters.push(`ogrnip==${searchCriteria.ogrnip}`);
    }
    const searchQuery = filters.join(' and ');

    const {
      data: { records: subjects, totalRows, page, perPage } 
    } = await documentApi.pagingDocuments(
      'Subject',
      commonRequestProperties.page || 1,
      commonRequestProperties.perPage || 10,
      searchQuery
    );

    this.pagination.rowsNumber = totalRows;
    this.pagination.page = page;
    this.pagination.rowsPerPage = perPage;

    this.foundEntities = subjects || [];
    this.showPickDialog = true;
  }

  async onPageChange(props) {
    const { page, rowsPerPage, sortBy, descending } = props.pagination;
    
    const commonRequestProperties = {
      page: page,
      perPage: rowsPerPage,
      sort: sortBy,
    }

    try {
      this.isSearching = true;
      if (this.entityType === 'ЮЛ' || this.entityType === 'ИП') {
        await this.searchInDocumentRegistry(this.searchCriteria, commonRequestProperties);
      } else { // ФЛ
        await this.searchInPersonalAccount(this.searchCriteria, commonRequestProperties);
      }
    } finally {
      this.isSearching = false;
    }
  }

  onRowClick(evt: Event, row: any, index: number) {
    this.selectEntity(row.id);
  }

  destroyed() {
    this.$store.commit('formGenerator/setFoundPerson', null);
  }
}

</script>
  