/********************************************************************************
 * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 ********************************************************************************/


import {Component, ViewChild, OnInit, OnDestroy} from '@angular/core';

import {SearchService, SearchDefinition, SearchAttribute, SearchLayout} from './search.service';
import {of as observableOf, combineLatest as observableCombineLatest} from 'rxjs';

import {defaultIfEmpty, mergeMap, tap} from 'rxjs/operators';

import {FilterService, SearchFilter, Condition} from './filter.service';
import {NodeService} from '../navigator/node.service';
import {BasketService} from '../basket/basket.service';
import {QueryService, SearchResult } from '../tableview/query.service';

import {LocalizationService} from '../localization/localization.service';
import {MDMNotificationService} from '../core/mdm-notification.service';

import {Node} from '../navigator/node';

import {TableviewComponent} from '../tableview/tableview.component';
import {ViewComponent} from '../tableview/view.component';

import {ModalDirective} from 'ngx-bootstrap';
import {AccordionPanelComponent} from 'ngx-bootstrap/accordion';

import {MenuItem} from 'primeng/primeng';
import {EditSearchFieldsComponent} from './edit-searchFields.component';
import {OverwriteDialogComponent} from '../core/overwrite-dialog.component';

import {classToClass, serialize, deserialize} from 'class-transformer';
import {SelectItem} from 'primeng/primeng';

import { TranslateService } from '@ngx-translate/core';
import { streamTranslate, TRANSLATE } from '../core/mdm-core.module';

@Component({
  selector: 'mdm-search',
  templateUrl: 'mdm-search.component.html',
})
export class MDMSearchComponent implements OnInit, OnDestroy {

  maxResults = 1000;

  filters: SearchFilter[] = [];
  currentFilter: SearchFilter;
  filterName = '';

  environments: Node[];
  selectedEnvironments: Node[] = [];

  definitions: SearchDefinition[] = [];

  results: SearchResult = new SearchResult();
  allSearchAttributes: { [type: string]: { [env: string]: SearchAttribute[] }} = {};
  allSearchAttributesForCurrentResultType: { [env: string]: SearchAttribute[] } = {};

  isAdvancedSearchOpen = false;
  isAdvancedSearchActive = true;
  isSearchResultsOpen = false;

  layout: SearchLayout = new SearchLayout;

  public dropdownModel: SelectItem[] = [];
  public selectedEnvs: string[] = [];

  searchFields: { group: string, attribute: string }[] = [];

  subscription: any;
  searchExecuted = false;

  selectedRow: SearchFilter;
  lazySelectedRow: SearchFilter;
  loading = false;

  contextMenuItems: MenuItem[] = [
    { label: 'Add to shopping basket', icon: 'fa fa-shopping-cart', command: (event) => this.addSelectionToBasket() }
  ];

  @ViewChild(ViewComponent)
  viewComponent: ViewComponent;

  @ViewChild(TableviewComponent)
  tableViewComponent: TableviewComponent;

  @ViewChild('lgSaveModal')
  childSaveModal: ModalDirective;

  @ViewChild(EditSearchFieldsComponent)
  editSearchFieldsComponent: EditSearchFieldsComponent;

  @ViewChild(OverwriteDialogComponent)
  overwriteDialogComponent: OverwriteDialogComponent;

  @ViewChild('advancedSearch')
  advancedSearchPanel: AccordionPanelComponent;

  @ViewChild('searchResults')
  searchResultsPanel: AccordionPanelComponent;

  constructor(private searchService: SearchService,
    private queryService: QueryService,
    private filterService: FilterService,
    private nodeService: NodeService,
    private localService: LocalizationService,
    private notificationService: MDMNotificationService,
    private basketService: BasketService,
    private translateService: TranslateService) { }

  ngOnInit() {
    this.currentFilter = this.filterService.EMPTY_FILTER;

    streamTranslate(this.translateService, TRANSLATE('search.mdm-search.add-to-shopping-basket')).subscribe(
            (msg: string) => this.contextMenuItems[0].label = msg);

    this.nodeService.getNodes().pipe(
      mergeMap(envs => observableCombineLatest([
        observableOf(envs),
        this.searchService.loadSearchAttributesStructured(envs.map(env => env.sourceName)),
        this.filterService.getFilters().pipe(defaultIfEmpty([this.currentFilter])),
        this.searchService.getDefinitionsSimple()
      ]))).subscribe(
        ([envs, attrs, filters, definitions]) => this.init(envs, attrs, filters, definitions),
        error => this.notificationService.notifyError(
          this.translateService.instant('search.mdm-search.err-cannot-load-data-sources'), error)
      );

    // event handlers
    this.viewComponent.viewChanged$.subscribe(
      () => this.onViewChanged(),
      error => this.notificationService.notifyError(this.translateService.instant('search.mdm-search.err-cannot-update-view'), error)
    );
  }

  ngOnDestroy() {
     this.saveState();
  }

  init(envs: Node[], attrs: { [type: string]: { [env: string]: SearchAttribute[] }},
      filters: SearchFilter[], definitions: SearchDefinition[]) {
    this.environments = envs;
    this.allSearchAttributes = attrs;
    this.filters = filters;
    this.definitions = definitions;

    this.dropdownModel = envs.map(env => <SelectItem>{ value: env.sourceName, label: env.name });
    this.selectedEnvs = envs.map(env => env.sourceName);

    this.updateSearchAttributesForCurrentResultType();
    this.selectedEnvironmentsChanged();

    this.loadState();
  }

  loadState() {

    this.results = deserialize(SearchResult, sessionStorage.getItem('mdm-search.searchResult')) || new SearchResult();
    this.selectFilter(deserialize(SearchFilter, sessionStorage.getItem('mdm-search.currentFilter')) || this.filterService.EMPTY_FILTER);
    this.isAdvancedSearchActive = !('false' === sessionStorage.getItem('mdm-search.isAdvancedSearchActive'));
    this.advancedSearchPanel.isOpen = !('false' === sessionStorage.getItem('mdm-search.isAdvancedSearchOpen'));
    this.searchResultsPanel.isOpen = !('false' === sessionStorage.getItem('mdm-search.isSearchResultsOpen'));
  }

  saveState() {
    sessionStorage.setItem('mdm-search.isSearchResultsOpen', serialize(this.searchResultsPanel.isOpen));
    sessionStorage.setItem('mdm-search.isAdvancedSearchOpen', serialize(this.advancedSearchPanel.isOpen));
    sessionStorage.setItem('mdm-search.currentFilter', serialize(this.currentFilter));
    sessionStorage.setItem('mdm-search.searchResult', serialize(this.results));
    sessionStorage.setItem('mdm-search.isAdvancedSearchActive', this.isAdvancedSearchActive.toString());
  }

  onViewClick(e: Event) {
    e.stopPropagation();
  }

  onCheckBoxClick(event: any) {
    event.stopPropagation();
    this.isAdvancedSearchActive = event.target.checked;
  }

  onViewChanged() {
    if (this.searchExecuted) {
      this.onSearch();
    }
  }

  selectedEnvironmentsChanged() {
    this.currentFilter.environments = this.selectedEnvs;
    if (this.environments) {
      let envs = this.environments.filter(env =>
        this.currentFilter.environments.find(envName => envName === env.sourceName));

      if (envs.length === 0) {
        this.selectedEnvironments = this.environments;
      } else {
        this.selectedEnvironments = envs;
      }
    }
    this.calcCurrentSearch();
  }

  loadFilters() {
    this.filters = [];
    this.filterService.getFilters().pipe(
      defaultIfEmpty([this.currentFilter]))
      .subscribe(
        filters => this.filters = this.filters.concat(filters),
        error => this.notificationService.notifyError(
          this.translateService.instant('search.mdm-search.err-cannot-load-search-filter'), error)
      );
  }

  selectFilterByName(defaultFilterName: string) {
    this.selectFilter(this.filters.find(f => f.name === defaultFilterName));
  }

  removeSearchField(searchField: { group: string, attribute: string }) {
    let index = this.searchFields.findIndex(sf => sf.group === searchField.group && sf.attribute === searchField.attribute);
    this.searchFields.splice(index, 1);
  }

  onResultTypeChane(e: any) {
    this.selectResultType(e.value);
  }

  selectResultType(type: any) {
    this.currentFilter.resultType = type.type;
    this.updateSearchAttributesForCurrentResultType();
  }

  updateSearchAttributesForCurrentResultType() {
    if (this.allSearchAttributes.hasOwnProperty(this.getSelectedDefinition())) {
      this.allSearchAttributesForCurrentResultType = this.allSearchAttributes[this.getSelectedDefinition()];
    }
  }

  getSearchDefinition(type: string) {
    return this.definitions.find(def => def.type === type);
  }

  getSelectedDefinition() {
    let def = this.getSearchDefinition(this.currentFilter.resultType);
    if (def) {
      return def.value;
    }
  }

  onSearch() {
    let query;
    this.loading = true;
    this.isSearchResultsOpen = true;
    if (this.isAdvancedSearchActive) {
      query = this.searchService.convertToQuery(this.currentFilter, this.allSearchAttributes, this.viewComponent.selectedView);
    } else {
      let filter = classToClass(this.currentFilter);
      filter.conditions = [];
      query = this.searchService.convertToQuery(filter, this.allSearchAttributes, this.viewComponent.selectedView);
    }
    this.queryService.query(query).pipe(
      tap(result => this.generateWarningsIfMaxResultsReached(result)))
      .subscribe(
        result => {
          this.results = result;
          this.isSearchResultsOpen = true;
          this.searchExecuted = true;
          this.loading = false;
        },
        error => this.notificationService.notifyError(
          this.translateService.instant('search.mdm-search.err-cannot-process-search-query'), error)
      );
  }

  generateWarningsIfMaxResultsReached(result: SearchResult) {
    let resultsPerSource = result.rows
      .map(r => r.source)
      .reduce((prev, item) => { (prev[item]) ? prev[item] += 1 : prev[item] = 1; return prev; }, {});

    Object.keys(resultsPerSource)
      .filter(source => resultsPerSource[source] > this.maxResults)
      .forEach(source => this.notificationService.notifyWarn(
        this.translateService.instant('search.mdm-search.errheading-too-many-search-results'),
        this.translateService.instant('search.mdm-search.err-too-many-search-results', {'numresults': this.maxResults, 'source': source})));
  }

  calcCurrentSearch() {
    let environments = this.currentFilter.environments;
    let conditions = this.currentFilter.conditions;
    let type = this.getSelectedDefinition();
    this.layout = SearchLayout.createSearchLayout(environments, this.allSearchAttributesForCurrentResultType, conditions);
  }

  onFilterChange(e: any) {
    this.selectFilter(e.value);
  }

  selectFilter(filter: SearchFilter) {
    this.currentFilter = classToClass(filter);
    this.selectedEnvs = this.currentFilter.environments;
    this.updateSearchAttributesForCurrentResultType();
    this.selectedEnvironmentsChanged();
    this.calcCurrentSearch();
  }

  resetConditions(e: Event) {
    e.stopPropagation();
    this.currentFilter.conditions.forEach(cond => cond.value = []);
    this.selectFilter(this.currentFilter);
  }

  clearResultlist(e: Event) {
    e.stopPropagation();
    this.results = new SearchResult();
  }

  deleteFilter(e: Event) {
    e.stopPropagation();
    if (this.currentFilter.name === this.filterService.NO_FILTER_NAME
          || this.currentFilter.name === this.filterService.NEW_FILTER_NAME) {
      this.notificationService
        .notifyInfo(this.translateService.instant('search.mdm-search.errheading-cannot-delete-search-filter-none-selected'),
        this.translateService.instant('search.mdm-search.err-cannot-delete-search-filter-none-selected'));
    } else {
      this.layout = new SearchLayout;
      this.filterService.deleteFilter(this.currentFilter.name).subscribe(
        () => {
          this.loadFilters();
          this.selectFilter(new SearchFilter(this.filterService.NO_FILTER_NAME, [], 'Test', '', []));
        },
        error => this.notificationService.notifyError(
          this.translateService.instant('search.mdm-search.err-cannot-delete-search-filter'), error)
      );
    }
  }

  saveFilter(e: Event) {
    e.stopPropagation();
    if (this.filters.find(f => f.name === this.filterName) != undefined) {
      this.childSaveModal.hide();
      this.overwriteDialogComponent.showOverwriteModal(this.translateService.instant('search.mdm-search.a-filter')).subscribe(
        needSave => this.saveFilter2(needSave),
        error => {
          this.saveFilter2(false);
          this.notificationService.notifyError(this.translateService.instant('search.mdm-search.err-cannot-save-search-filter'), error);
        }
      );
    } else {
      this.saveFilter2(true);
    }
  }

  saveFilter2(save: boolean) {
    if (save) {
      let filter = this.currentFilter;
      filter.name = this.filterName;
      this.filterService.saveFilter(filter).subscribe(
        () => {
          this.loadFilters();
          this.selectFilter(filter);
        },
        error => this.notificationService.notifyError(
          this.translateService.instant('search.mdm-search.err-cannot-save-search-filter'), error)
      );
      this.childSaveModal.hide();
    } else {
      this.childSaveModal.show();
    }
  }

  removeCondition(condition: Condition) {
    this.currentFilter.conditions = this.currentFilter.conditions
      .filter(c => !(c.type === condition.type && c.attribute === condition.attribute));

    this.calcCurrentSearch();
  }

  selected2Basket(e: Event) {
    e.stopPropagation();
    this.tableViewComponent.selectedViewRows.forEach(row => this.basketService.add(row.getItem()));
  }

  showSaveModal(e: Event) {
    e.stopPropagation();
    if (this.currentFilter.name === this.filterService.NO_FILTER_NAME
            || this.currentFilter.name === this.filterService.NEW_FILTER_NAME) {
      this.filterName = '';
    } else {
      this.filterName = this.currentFilter.name;
    }
    this.childSaveModal.show();
  }

  showSearchFieldsEditor(e: Event, conditions?: Condition[]) {
    e.stopPropagation();
    this.editSearchFieldsComponent.show(conditions).subscribe(
      conds => {
        if (!conditions) {
          let filter = new SearchFilter(this.filterService.NEW_FILTER_NAME, this.currentFilter.environments, 'Test', '', conds);
          this.selectFilter(filter);
        }
        this.currentFilter.conditions = conds;
        this.calcCurrentSearch();
      },
      error => this.notificationService.notifyError(
        this.translateService.instant('search.mdm-search.err-cannot-display-search-field-editor'), error)
    );
  }

  addSelectionToBasket() {
    this.basketService.add(this.tableViewComponent.menuSelectedRow.getItem());
  }

  mapSourceNameToName(sourceName: string) {
    return NodeService.mapSourceNameToName(this.environments, sourceName);
  }

  getSaveFilterBtnTitle () {
    return this.filterName
      ? TRANSLATE('search.mdm-search.tooltip-save-search-filter')
      : TRANSLATE('search.mdm-search.tooltip-no-name-set') ;
  }

  getAdvancedSearchCbxTitle() {
    return this.isAdvancedSearchActive
      ? TRANSLATE('search.mdm-search.tooltip-disable-advanced-search')
      : TRANSLATE('search.mdm-search.tooltip-enable-advanced-search');
  }

/*
  private loadSearchAttributes(environments: string[]) {
    this.searchService.loadSearchAttributesStructured(environments)
      .subscribe(
        attrs => { this.allSearchAttributes = attrs; this.updateSearchAttributesForCurrentResultType(); },
        error => this.notificationService.notifyError(
          this.translateService.instant('search.mdm-search.err-cannot-load-attributes'), error));
  }
*/
  onRowSelect(e: any) {
    if (this.lazySelectedRow !== e.data) {
      this.selectedRow = e.data;
      this.filterName = e.data.name;
    } else {
      this.selectedRow = undefined;
      this.filterName = '';
    }
    this.lazySelectedRow = this.selectedRow;
  }
}
