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

import { Observable } from 'rxjs';
import { Store } from '@ngrx/store';

import { environment } from '../../../environments/environment';
import { Criterion, SearchQueryParams, ConeSearch } from '../store/model';
import { Dataset, Attribute } from '../../metamodel/model';
import * as searchActions from '../store/search.action';
import * as datasetActions from '../../metamodel/action/dataset.action';
import * as fromSearch from '../store/search.reducer';
import * as fromMetamodel from '../../metamodel/reducers';
import * as searchSelector from '../store/search.selector';
import * as metamodelSelector from '../../metamodel/selectors';
import { ScrollTopService } from '../../shared/service/sroll-top.service';

interface StoreState {
    search: fromSearch.State;
    metamodel: fromMetamodel.State;
}

@Component({
    selector: 'app-result',
    templateUrl: 'result.component.html'
})
export class ResultComponent implements OnInit, OnDestroy {
    public datasetSearchMetaIsLoading: Observable<boolean>;
    public datasetSearchMetaIsLoaded: Observable<boolean>;
    public attributeSearchMetaIsLoading: Observable<boolean>;
    public attributeSearchMetaIsLoaded: Observable<boolean>;
    public apiPath: string = environment.apiUrl;
    public datasetName: Observable<string>;
    public currentStep: Observable<string>;
    public datasetList: Observable<Dataset[]>;
    public datasetAttributeList: Observable<Attribute[]>;
    public criteriaList: Observable<Criterion[]>;
    public coneSearch: Observable<ConeSearch>;
    public outputList: Observable<number[]>;
    public searchData: Observable<any[]>;
    public dataLength: Observable<number>;
    public selectedData: Observable<number[] | string[]>;
    public queryParams: Observable<SearchQueryParams>;
    public processWip: Observable<boolean>;
    public processDone: Observable<boolean>;
    public processId: Observable<string>;

    constructor(private store: Store<StoreState>, private scrollTopService: ScrollTopService) {
        this.datasetSearchMetaIsLoading = store.select(metamodelSelector.getDatasetSearchMetaIsLoading);
        this.datasetSearchMetaIsLoaded = store.select(metamodelSelector.getDatasetSearchMetaIsLoaded);
        this.attributeSearchMetaIsLoading = store.select(metamodelSelector.getAttributeSearchMetaIsLoading);
        this.attributeSearchMetaIsLoaded = store.select(metamodelSelector.getAttributeSearchMetaIsLoaded);
        this.datasetName = store.select(searchSelector.getDatasetName);
        this.currentStep = store.select(searchSelector.getCurrentStep);
        this.datasetList = store.select(metamodelSelector.getDatasetList);
        this.datasetAttributeList = this.store.select(metamodelSelector.getDatasetAttributeList);
        this.criteriaList = this.store.select(searchSelector.getCriteriaList);
        this.coneSearch = this.store.select(searchSelector.getConeSearch);
        this.outputList = this.store.select(searchSelector.getOutputList);
        this.searchData = this.store.select(searchSelector.getSearchData);
        this.dataLength = this.store.select(searchSelector.getDataLength);
        this.selectedData = this.store.select(searchSelector.getSelectedData);
        this.queryParams = this.store.select(searchSelector.getQueryParams);
        this.processWip = this.store.select(searchSelector.getProcessWip);
        this.processDone = this.store.select(searchSelector.getProcessDone);
        this.processId = this.store.select(searchSelector.getProcessId);
    }

    ngOnInit() {
        // Create a micro task that is processed after the current synchronous code
        // This micro task prevent the expression has changed after view init error
        Promise.resolve(null).then(() => this.store.dispatch(new searchActions.ChangeStepAction('result')));
        Promise.resolve(null).then(() => this.store.dispatch(new searchActions.ResultChecked()));
        Promise.resolve(null).then(() => this.store.dispatch(new searchActions.InitSearchByUrl()));
        this.store.dispatch(new datasetActions.LoadDatasetSearchMetaAction());
        this.scrollTopService.setScrollTop();
    }

    getSearchData(pagination: [number, number, number, string]): void {
        this.store.dispatch(new searchActions.RetrieveDataAction(pagination));
        this.store.dispatch(new searchActions.GetDataLengthAction());
    }

    addSearchData(data: number | string): void {
        this.store.dispatch(new searchActions.AddSelectedDataAction(data));
    }

    deleteSearchData(data: number | string): void {
        this.store.dispatch(new searchActions.DeleteSelectedDataAction(data));
    }

    executeProcess(typeProcess: string): void {
        this.store.dispatch(new searchActions.ExecuteProcessAction(typeProcess));
    }

    ngOnDestroy() {
        this.store.dispatch(new searchActions.DestroyResultsAction());
    }
}