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 { EvaluationPersonInsert } from '../entities/input/personInsertInput';
import { PersonInsertOutput } from '../entities/output/personInsertOutput';
import { InsertIndivEvaluation } from './evaluation-person-insert.actions';

export interface InsertIndivEvaluationStateModel {
    loadingEvaluations: boolean;
    insertOutput: PersonInsertOutput;
    ID_EvaluationSubtype: number;
    Year: number;
}

const initialStateModel: InsertIndivEvaluationStateModel = {
    loadingEvaluations: false,
    insertOutput: null,
    ID_EvaluationSubtype: 0,
    Year: 0
};

@State<InsertIndivEvaluationStateModel>({
    name: 'insertPerson',
    defaults: initialStateModel
})

export class InsertIndivEvaluationState {

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

    @Selector()
    static getInsertOutput(state: InsertIndivEvaluationStateModel) {
        return state.insertOutput;
    }

    constructor(
        private webApiService: WebApiService
    ) {}

    @Action(InsertIndivEvaluation)
    loadEvaluations(ctx: StateContext<InsertIndivEvaluationStateModel>, action: InsertIndivEvaluation) {
        ctx.patchState({
            loadingEvaluations: true,
            ID_EvaluationSubtype: action.evaluationSubtypeId,
            Year: action.year
        });

        return this.webApiService.call(
            new EvaluationPersonInsert(APP_ID, ApplicationSettings.getString(USER_TOKEN), ctx.getState().ID_EvaluationSubtype, ctx.getState().Year),
            () => new PersonInsertOutput(),
            wsEvaluation
        ).pipe(
            tap((response: PersonInsertOutput[]) => {
                // Only one result should be returned, since there should be no elements with "Output" suffix
                if (response.length === 1) {
                    ctx.patchState({
                        loadingEvaluations: false,
                        insertOutput: response[0]
                    });
                } else {
                    ctx.patchState({
                        loadingEvaluations: false,
                        insertOutput: initialStateModel.insertOutput
                    });
                    throw new Error('Nepodařilo se nalézt nové hodnocení - opakujte akci');
                }
            }),
            catchError(e => {
                ctx.patchState({
                    loadingEvaluations: false,
                    insertOutput: initialStateModel.insertOutput
                });
                throw e;
            })
        );
    }
}
