import { Action, Selector, State, StateContext } from '@ngxs/store';
import { catchError, tap } from 'rxjs/operators';
import { ApplicationSettings as AppSettings } from '@nativescript/core';

import { wsEvents } from '~/constants/api.constants';
import { USER_TOKEN } from '~/constants/login-constants';
import { WebApiService } from '~/core/services/web-api.service';
import { CandidateContactAll, CandidateDetail, CandidateDetailPerson, CandidateEducationSeminaryAll, CandidateFunctionAll, CandidateQualificationAll, CandidateRecommendationAll, CongCandidateContactOutput, CongCandidateDetailOutput, CongCandidateDetailPersonOutput, CongCandidateEducationSeminaryOutput, CongCandidateFunctionOutput, CongCandidateQualificationOutput, CongCandidateRecommendationOutput } from '../../entities/cong-candidate-detail.types';
import { LoadCongCandidateDetail, LoadCongCandidatePersonDetail, LoadCongCandidateContacts, LoadCongCandidateEducation, LoadCongCandidateFunctions, LoadCongCandidateQualificaton } from './cong-candidate-detail.actions';
import { LoadCongCandidateRecommendation } from '~/pages/event/state-mgmt/cong/cong-candidate-detail.actions';

export interface CongCandidateDetailStateModel {
    candidateDetail: CongCandidateDetailOutput;
    candidatePersonDetail: CongCandidateDetailPersonOutput;
    contacts: CongCandidateContactOutput[],
    education: CongCandidateEducationSeminaryOutput[];
    recommendations: CongCandidateRecommendationOutput[];
    qualifications: CongCandidateQualificationOutput[];
    functions: CongCandidateFunctionOutput[];
}

const initialStateModel: CongCandidateDetailStateModel = {
    candidatePersonDetail: null,
    candidateDetail: null,
    contacts: [],
    education: [],
    recommendations: [],
    qualifications: [],
    functions: [],

};

@State<CongCandidateDetailStateModel>({
    name: 'congCandidateDetail',
    defaults: initialStateModel
})
export class CongCandidateDetailState {
    @Selector()
    static getCandiateDetail(state: CongCandidateDetailStateModel) {
        return state.candidateDetail;
    }

    @Selector()
    static getCandiatePersonDetail(state: CongCandidateDetailStateModel) {
        return state.candidatePersonDetail;
    }
    @Selector()
    static getContacts(state: CongCandidateDetailStateModel) {
        return state.contacts;
    }
    @Selector()
    static getEducation(state: CongCandidateDetailStateModel) {
        return state.education;
    }
    @Selector()
    static getQualifications(state: CongCandidateDetailStateModel) {
        return state.qualifications;
    }
    @Selector()
    static getRecommendations(state: CongCandidateDetailStateModel) {
        return state.recommendations;
    }
    @Selector()
    static getFunctions(state: CongCandidateDetailStateModel) {
        return state.functions;
    }

    constructor(
        private webApiService: WebApiService
    ) {
    }


    @Action(LoadCongCandidateDetail)
    loadCandidateDetail(ctx: StateContext<CongCandidateDetailStateModel>, action: LoadCongCandidateDetail) {
        const tk = AppSettings.getString(USER_TOKEN)
        console.log(tk)
        if (action.id) {
            return this.webApiService.call(
                new CandidateDetail(tk, action.id),
                () => new CongCandidateDetailOutput(),
                wsEvents
            ).pipe(
                tap((response: CongCandidateDetailOutput[]) => {
                    if (response.length === 1) {
                        ctx.patchState({
                            candidateDetail: response[0]
                        });
                    } else {
                        ctx.patchState({
                            candidateDetail: initialStateModel.candidateDetail
                        });
                        throw new Error('Nepodařilo se nalézt detail akce');
                    }
                }),
                catchError(e => {
                    ctx.patchState({
                        candidateDetail: initialStateModel.candidateDetail
                    });

                    throw e;
                })
            );
        }
    }

    @Action(LoadCongCandidatePersonDetail)
    loadCandidatePersonDetail(ctx: StateContext<CongCandidateDetailStateModel>, action: LoadCongCandidatePersonDetail) {
        const tk = AppSettings.getString(USER_TOKEN)
        if (action.id) {
            return this.webApiService.call(
                new CandidateDetailPerson(tk, action.id),
                () => new CongCandidateDetailPersonOutput(),
                wsEvents
            ).pipe(
                tap((response: CongCandidateDetailPersonOutput[]) => {
                    if (response.length === 1) {
                        ctx.patchState({
                            candidatePersonDetail: response[0]
                        });
                    } else {
                        ctx.patchState({
                            candidatePersonDetail: initialStateModel.candidatePersonDetail
                        });
                        throw new Error('Nepodařilo se nalézt detail akce');
                    }
                }),
                catchError(e => {
                    ctx.patchState({
                        candidatePersonDetail: initialStateModel.candidatePersonDetail
                    });

                    throw e;
                })
            );
        }
    }

    @Action(LoadCongCandidateContacts)
    loadCandidateContacts(ctx: StateContext<CongCandidateDetailStateModel>, action: LoadCongCandidateContacts) {
        const tk = AppSettings.getString(USER_TOKEN);
        if (action.id) {
            return this.webApiService.call(
                new CandidateContactAll(tk, action.id),
                () => new CongCandidateContactOutput(),
                wsEvents
            ).pipe(
                tap((response: CongCandidateContactOutput[]) => {
                    ctx.patchState({
                        contacts: response
                    });

                }),
                catchError(e => {
                    ctx.patchState({
                        contacts: initialStateModel.contacts
                    });

                    throw e;
                })
            );
        }
    }
    @Action(LoadCongCandidateEducation)
    loadCandidateEducationSeminary(ctx: StateContext<CongCandidateDetailStateModel>, action: LoadCongCandidateEducation) {
        const tk = AppSettings.getString(USER_TOKEN);
        if (action.id) {
            return this.webApiService.call(
                new CandidateEducationSeminaryAll(tk, action.id),
                () => new CongCandidateEducationSeminaryOutput(),
                wsEvents
            ).pipe(
                tap((response: CongCandidateEducationSeminaryOutput[]) => {
                    ctx.patchState({
                        education: response
                    });
                }),
                catchError(e => {
                    ctx.patchState({
                        education: initialStateModel.education
                    });

                    throw e;
                })
            );
        }
    }

    @Action(LoadCongCandidateFunctions)
    loadCandidateFunctions(ctx: StateContext<CongCandidateDetailStateModel>, action: LoadCongCandidateFunctions) {
        const tk = AppSettings.getString(USER_TOKEN);
        if (action.id) {
            return this.webApiService.call(
                new CandidateFunctionAll(tk, action.id),
                () => new CongCandidateFunctionOutput(),
                wsEvents
            ).pipe(
                tap((response: CongCandidateFunctionOutput[]) => {
                    ctx.patchState({
                        functions: response
                    });
                }),
                catchError(e => {
                    ctx.patchState({
                        functions: initialStateModel.functions
                    });

                    throw e;
                })
            );
        }
    }
    @Action(LoadCongCandidateRecommendation)
    loadCandidateRecommendations(ctx: StateContext<CongCandidateDetailStateModel>, action: LoadCongCandidateRecommendation) {
        const tk = AppSettings.getString(USER_TOKEN);
        if (action.id) {
            return this.webApiService.call(
                new CandidateRecommendationAll(tk, action.id),
                () => new CongCandidateRecommendationOutput(),
                wsEvents
            ).pipe(
                tap((response: CongCandidateRecommendationOutput[]) => {
                    ctx.patchState({
                        recommendations: response
                    });
                }),
                catchError(e => {
                    ctx.patchState({
                        recommendations: initialStateModel.recommendations
                    });

                    throw e;
                })
            );
        }
    }

    @Action(LoadCongCandidateQualificaton)
    loadCandidateQualifications(ctx: StateContext<CongCandidateDetailStateModel>, action: LoadCongCandidateQualificaton) {
        const tk = AppSettings.getString(USER_TOKEN);
        if (action.id) {
            return this.webApiService.call(
                new CandidateQualificationAll(tk, action.id),
                () => new CongCandidateQualificationOutput(),
                wsEvents
            ).pipe(
                tap((response: CongCandidateQualificationOutput[]) => {
                    ctx.patchState({
                        qualifications: response
                    });
                }),
                catchError(e => {
                    ctx.patchState({
                        qualifications: initialStateModel.qualifications
                    });

                    throw e;
                })
            );
        }
    }


}
