package ru.micord.ervu.account_applications.component.service;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import model.AutocompleteModel;
import org.springframework.stereotype.Service;
import property.enums.DisplayType;
import property.grid.ColumnSort;
import ru.micord.ervu.account_applications.dao.RecruitmentDao;
import service.field.AbstractAutocompleteService;
import utils.QueryUtils;

import ru.cg.webbpm.modules.database.api.bean.TableRow;
import ru.cg.webbpm.modules.database.api.dao.option.LoadOptions;
import ru.cg.webbpm.modules.database.api.dao.option.SortOrder;
import ru.cg.webbpm.modules.database.bean.filter.EntityFilter;
import ru.cg.webbpm.modules.database.bean.filter.EntityFilterGroup;
import ru.cg.webbpm.modules.database.bean.filter.FilterOperation;
import ru.micord.ervu.account_applications.security.context.SecurityContext;

/**
 * @author Adel Kalimullin
 */
@Service
public class RecruitmentAutoCompleteService extends AbstractAutocompleteService<AutocompleteModel> {
  private final RecruitmentDao recruitmentDao;
  private final SecurityContext securityContext;

  public RecruitmentAutoCompleteService(RecruitmentDao recruitmentDao,
      SecurityContext securityContext) {
    this.recruitmentDao = recruitmentDao;
    this.securityContext = securityContext;
  }

  protected AutocompleteModel convertToSearchModel(TableRow row) {
    String dropdownLabel = this.getDropDownLabelValue(row);
    String displayLabel = this.getDisplayLabelValue(row);
    return new AutocompleteModel(row.get(QueryUtils.getIdField(this.loadDao)),
        row.get(this.businessIdColumn), displayLabel,
        (Boolean) row.get(this.loadDao.getValidEntityColumn()), dropdownLabel
    );
  }

  protected List<AutocompleteModel> load(String inputString, Integer inputPage,
      LoadOptions loadOptions) {
    List<String> recruitmentIds = getRecruitmentIdsForCurrentUser();
    loadOptions.getEntityFilters().add(getEntityFilterForRecruitmentIds(recruitmentIds));
    loadOptions.setLimit(this.valuesLimit);
    loadOptions.setOffset(inputPage * this.valuesLimit);
    if (this.columnSorts.length > 0) {
      ColumnSort[] var4 = this.columnSorts;
      int var5 = var4.length;

      for (int var6 = 0; var6 < var5; ++var6) {
        ColumnSort columnSort = var4[var6];
        loadOptions.addSortField(columnSort.field, columnSort.sortOrder);
      }
    }
    else if (this.displayType == DisplayType.MULTI_COLUMN) {
      Arrays.stream(this.displayColumns).forEach((searchDisplayColumn) -> {
        loadOptions.addSortField(searchDisplayColumn.getEntityColumn(), SortOrder.ASC);
      });
    }
    else if (this.displayType == DisplayType.ONE_COLUMN) {
      loadOptions.addSortField(this.displayColumn, SortOrder.ASC);
    }

    List<String> searchStrings = this.getSearchString(inputString);
    EntityFilterGroup entityFilterGroup = this.getEntityFilterGroup(searchStrings, loadOptions);
    loadOptions.setEntityFilterGroup(entityFilterGroup);
    List<TableRow> loadedData = this.loadDao.load(this.getColumnsToLoad(), loadOptions);
    return (List) loadedData.stream().map(this::convertToSearchModel).collect(Collectors.toList());
  }

  private List<String> getSearchString(String inputString) {
    if (this.displayType == DisplayType.MULTI_COLUMN) {
      return (List) Arrays.stream(inputString.trim().split(" ")).filter((token) -> {
        return !token.isEmpty();
      }).collect(Collectors.toList());
    }
    else if (this.displayType == DisplayType.ONE_COLUMN) {
      return Collections.singletonList(inputString.trim());
    }
    else {
      throw new RuntimeException("Incorrect search column type " + this.displayType);
    }
  }

  private List<String> getRecruitmentIdsForCurrentUser() {
    String recruitmentId = securityContext.getDomainId();
    return recruitmentDao.getRecruitmentIdsWithParentByDomainId(recruitmentId);
  }

  private EntityFilter getEntityFilterForRecruitmentIds(List<String> ids) {
    return new EntityFilter(ids, FilterOperation.IN, this.businessIdColumn);
  }
}
