import { Injectable } from '@angular/core';

import { ToastrService } from 'ngx-toastr';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { switchMap, map, catchError, tap, withLatestFrom } from 'rxjs/operators';

import { Attribute } from '../model';
import * as attributeActions from '../action/attribute.action';
import { AttributeService } from '../services/attribute.service';
import { Store } from "@ngrx/store";
import * as fromRouter from "@ngrx/router-store";
import * as utils from "../../shared/utils";
import * as fromSearch from "../../search/store/search.reducer";
import * as fromMetamodel from "../reducers";
import * as fromConeSearch from "../../shared/cone-search/store/cone-search.reducer";

@Injectable()
export class AttributeEffects {
    constructor(
        private actions$: Actions,
        private attributeService: AttributeService,
        private toastr: ToastrService,
        private store$: Store<{
            router: fromRouter.RouterReducerState<utils.RouterStateUrl>,
            search: fromSearch.State,
            metamodel: fromMetamodel.State,
            coneSearch: fromConeSearch.State
        }>
    ) { }

    @Effect()
    loadAttributeSearchMetaAction$ = this.actions$.pipe(
        ofType(attributeActions.LOAD_ATTRIBUTE_SEARCH_META),
        withLatestFrom(this.store$),
        switchMap(([action, state]) => {
            const loadAttributeSearchMetaAction = action as attributeActions.LoadAttributeSearchMetaAction;
            return this.attributeService.retrieveAttributeSearchMeta(loadAttributeSearchMetaAction.payload).pipe(
                map((attributeList: Attribute[]) => {
                    const module: string = state.router.state.url.split('/')[1];
                    if (module === 'search') {
                        new attributeActions.LoadAttributeSearchMetaSuccessAction(attributeList)
                    } else {
                        new attributeActions.LoadAttributeSearchMultipleMetaSuccessAction(attributeList)
                    }
                    }),
                catchError(() => of(new attributeActions.LoadAttributeSearchMetaFailAction()))
            )
        })
    );

    @Effect({ dispatch: false })
    loadAttributeSearchMetaFailedAction$ = this.actions$.pipe(
        ofType(attributeActions.LOAD_ATTRIBUTE_SEARCH_META_FAIL),
        tap(_ => this.toastr.error('Loading Failed!', 'Attribute search info loading failed'))
    );
}