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 { EvaluationDetail } from '../entities/input/evaluationDetail';
import { EvaluationDetailOutput } from '../entities/output/evaluationDetailOutput';
import { LoadEvaluationDetail, SetSearchEvaluationDetailID } from './evaluation-detail.actions';

export interface SearchEvaluationDetailStateModel {
    loadingDetail: boolean;
    evaluationDetail: EvaluationDetailOutput;
    searchEvaluationDetailID: number;
}

const initialStateModel: SearchEvaluationDetailStateModel = {
    loadingDetail: false,
    evaluationDetail: null,
    searchEvaluationDetailID: 0
};

@State<SearchEvaluationDetailStateModel>({
    name: 'evaluationDetail',
    defaults: initialStateModel
})

export class SearchEvaluationDetailState {

    @Selector()
    static getSearchEvaluationDetailID(state: SearchEvaluationDetailStateModel) {
        return state.searchEvaluationDetailID;
    }

    @Selector()
    static isLoading(state: SearchEvaluationDetailStateModel) {
        return state.loadingDetail;
    }

    @Selector()
    static getEvaluationDetail(state: SearchEvaluationDetailStateModel) {
        return state.evaluationDetail;
    }

    constructor(
        private webApiService: WebApiService
    ) {}

    @Action(SetSearchEvaluationDetailID)
    setSearchEvaluationParams(ctx: StateContext<SearchEvaluationDetailStateModel>, action: SetSearchEvaluationDetailID) {
        ctx.patchState({
            searchEvaluationDetailID: action.payload
        });
    }

    @Action(LoadEvaluationDetail)
    loadEvaluationDetail(ctx: StateContext<SearchEvaluationDetailStateModel>, action: LoadEvaluationDetail) {
        ctx.patchState({
            loadingDetail: true
        });

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