import { ApplicationSettings } from '@nativescript/core';
import { Action, Selector, State, StateContext } from '@ngxs/store';
import { catchError, tap } from 'rxjs/operators';
import { APP_ID, wsEvaluation } from '~/constants/api.constants';
import { USER_TOKEN } from '~/constants/login-constants';
import { WebApiService } from '~/core/services/web-api.service';
import { EvaluationSearch } from '../entities/evaluation-search';
import { EvaluationAll } from '../entities/input/evaluationAll';
import { EvaluationAllUnit } from '../entities/input/evaluationAllUnit';
import { EvaluationAllOutput } from '../entities/output/evaluationAllOutput';
import { EvaluationAllUnitOutput } from '../entities/output/evaluationAllUnitOutput';
import { LoadEvaluations, LoadUnitEvaluations, SetSearchEvaluationParams } from './evaluation-list.actions';

export interface SearchEvaluationListStateModel {
    loadingEvaluations: boolean;
    evaluations: EvaluationAllUnitOutput[];
    searchEvalParams: EvaluationSearch;
}

const initialStateModel: SearchEvaluationListStateModel = {
    loadingEvaluations: false,
    evaluations: [],
    searchEvalParams: null
};

@State<SearchEvaluationListStateModel>({
    name: 'evaluationList',
    defaults: initialStateModel
})

export class SearchEvaluationListState {

    @Selector()
    static getSearchEvalParams(state: SearchEvaluationListStateModel) {
        return state.searchEvalParams;
    }

    @Selector()
    static isLoading(state: SearchEvaluationListStateModel) {
        return state.loadingEvaluations;
    }

    @Selector()
    static getEvaluations(state: SearchEvaluationListStateModel) {
        return state.evaluations;
    }

    constructor(
        private webApiService: WebApiService
    ) {}

    @Action(SetSearchEvaluationParams)
    setSearchEvaluationParams(ctx: StateContext<SearchEvaluationListStateModel>, action: SetSearchEvaluationParams) {
        ctx.patchState({
            searchEvalParams: action.payload
        });
    }

    @Action(LoadUnitEvaluations)
    loadUnitEvaluations(ctx: StateContext<SearchEvaluationListStateModel>, action: LoadUnitEvaluations) {
        ctx.patchState({
            loadingEvaluations: true
        });

        return this.webApiService.call(
            new EvaluationAllUnit(APP_ID, ApplicationSettings.getString(USER_TOKEN), ctx.getState().searchEvalParams.state, ctx.getState().searchEvalParams.year, ctx.getState().searchEvalParams.unit),
            () => new EvaluationAllUnitOutput(),
            wsEvaluation
        ).pipe(
            tap((response: EvaluationAllUnitOutput[]) => {
                ctx.patchState({
                    loadingEvaluations: false,
                    evaluations: response
                });
            }),
            catchError(e => {
                ctx.patchState({
                    loadingEvaluations: false,
                    evaluations: initialStateModel.evaluations
                });
                throw e;
            })
        );
    }

    @Action(LoadEvaluations)
    loadEvaluations(ctx: StateContext<SearchEvaluationListStateModel>, action: LoadEvaluations) {
        ctx.patchState({
            loadingEvaluations: true
        });

        return this.webApiService.call(
            new EvaluationAll(APP_ID, ApplicationSettings.getString(USER_TOKEN), ctx.getState().searchEvalParams.state, ctx.getState().searchEvalParams.year, ctx.getState().searchEvalParams.unit),
            () => new EvaluationAllOutput(),
            wsEvaluation
        ).pipe(
            tap((response: EvaluationAllOutput[]) => {
                ctx.patchState({
                    loadingEvaluations: false,
                    evaluations: response
                });
            }),
            catchError(e => {
                ctx.patchState({
                    loadingEvaluations: false,
                    evaluations: initialStateModel.evaluations
                });
                throw e;
            })
        );
    }
}
