// angular
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
// libs
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
// libs
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
// app
import { QueryAction, ToggleSelectedAction, SetEntriesAction, SetSelectedAction } from '../actions/loop-scenario.action';
import { APIDispatcher, APIRequestOptions, ResponseBody } from '../utils/index';
import { LoopScenarioState } from '../states/loop-scenario.state';

@Injectable()
export class LoopScenarioService extends APIDispatcher {

    constructor(public http: Http, public store: Store<LoopScenarioState>) {
        super(http, store);
    }

    fetch(identities: string[]): Observable<any> {
        return this.post('ma_loop/api/v3/scenarios/fetch', identities)
            .map(res => res.json())
            .catch(this.handleError);
    }

    fetchForStore(identities: string[]): any {
        return this.fetch(identities)
            .subscribe((response: ResponseBody) => {
                this.loaded = true;
                this.store.dispatch(new QueryAction(response.content));
            });
    }

    query(page: number = 0, size: number = 10, options: APIRequestOptions = {}): Observable<any> {
        return Observable.create((observer: any) => {
            if(this.lastRequest) {
                if(this.lastRequest.options !== options) {
                    this.lastRequest.currentPage = page;
                    this.lastRequest.requestSize = size;
                    this.lastRequest.options = options;
                }
            }
            this.get('ma_loop/api/v3/scenarios/fetch', page, size, options).map(res => res.json())
                .catch(this.handleError)
                .subscribe((response: ResponseBody) => {
                    this.loaded = true;
                    this.lastRequest = response;
                    this.lastRequest.currentPage = page;
                    this.lastRequest.requestSize = size;
                    this.lastRequest.options = options;
                    this.store.dispatch(new QueryAction(response.content));
                    observer.next(response);
                    observer.complete();
                });
        });
    }

    getNextPage() {
        if(this.hasNext && !this.fetchingNext) {
            this.fetchingNext = true;
            this.query(this.lastRequest.currentPage + 1, this.lastRequest.requestSize, this.lastRequest.options).subscribe(() => {
                this.fetchingNext = false;
            });
        }
    }

    find(identity: string) {
        return this.get('ma_loop/api/v3/scenarios/' + identity).map(res => res.json());
    }

    /**
     * Toggles the selection of a scenario
     *
     * @param {string} identity The identity of the scenario
     *
     * @memberOf LoopScenarioService
     */
    selectEntry(identity: string) {
        this.store.dispatch(new ToggleSelectedAction(identity));
    }

    /**
     * Resets the entries in the app-state slice for Loop Documents
     *
     *
     * @memberOf LoopDocumentService
     */
    resetEntries() {
        this.loaded = false;
        this.lastRequest = undefined;
        this.store.dispatch(new SetEntriesAction([]));
    }

    /**
     * Resets the selected entries in the app-state slice for Loop Documents
     *
     *
     * @memberOf LoopDocumentService
     */
    resetSelectedEntries() {
        this.store.dispatch(new SetSelectedAction([]));
    }

}

