import { ApplicationSettings } from '@nativescript/core';
import { Action, Selector, State, StateContext } from '@ngxs/store';
import { catchError, tap } from 'rxjs/operators';
import { APP_ID, wsOrganizationUnit } from '~/constants/api.constants';
import { USER_TOKEN } from '~/constants/login-constants';
import { WebApiService } from '~/core/services/web-api.service';
import { UnitRegistrationAll } from '~/pages/unit/entities/input/unitRegistrationAll';
import { UnitRegistrationMembers } from '~/pages/unit/entities/input/unitRegistrationMembers';
import { UnitRegistrationAllOutput } from '~/pages/unit/entities/output/unitRegistrationAllOutput';
import { UnitRegistrationMembersAgeOutput } from '~/pages/unit/entities/output/unitRegistrationMembersAgeOutput';
import { UnitRegistrationMembersCategoryOutput } from '~/pages/unit/entities/output/unitRegistrationMembersCategoryOutput';
import { UnitRegistrationMembersOutput } from '~/pages/unit/entities/output/unitRegistrationMembersOutput';
import { UnitRegistrationMembersUnitsOutput } from '~/pages/unit/entities/output/unitRegistrationMembersUnitsOutput';
import { WebApiUnitMembersService } from '~/pages/unit/services/web-api-unit-members.service';
import { LoadUnitRegistrationMembers, LoadUnitRegistrations } from '~/pages/unit/state-mgmt/unit-stats.actions';

export interface UnitStatsStateModel {
    loadingUnitRegistration: boolean;
    loadingUnitRegistrationMembers: boolean;
    unitRegistrations: UnitRegistrationAllOutput[];
    unitRegistrationMembers: UnitRegistrationMembersOutput;
    unitRegistrationMembersUnits: UnitRegistrationMembersUnitsOutput[];
    unitRegistrationMembersAges: UnitRegistrationMembersAgeOutput[];
    unitRegistrationMembersCategories: UnitRegistrationMembersCategoryOutput[];
}

const initialStateModel: UnitStatsStateModel = {
    loadingUnitRegistration: false,
    loadingUnitRegistrationMembers: false,
    unitRegistrations: [],
    unitRegistrationMembers: null,
    unitRegistrationMembersUnits: [],
    unitRegistrationMembersAges: [],
    unitRegistrationMembersCategories: []
};

@State<UnitStatsStateModel>({
    name: 'unitStats',
    defaults: initialStateModel
})

export class UnitStatsState {

    @Selector()
    static getUnitRegistrations(state: UnitStatsStateModel) {
        return state.unitRegistrations;
    }

    @Selector()
    static getUnitRegistrationMembers(state: UnitStatsStateModel) {
        return state.unitRegistrationMembers;
    }

    @Selector()
    static getUnitRegistrationMembersAges(state: UnitStatsStateModel) {
        return state.unitRegistrationMembersAges;
    }

    @Selector()
    static getUnitRegistrationMembersCategories(state: UnitStatsStateModel) {
        return state.unitRegistrationMembersCategories;
    }

    @Selector()
    static getUnitRegistrationMembersUnits(state: UnitStatsStateModel) {
        return state.unitRegistrationMembersUnits;
    }

    @Selector()
    static isLoading(state: UnitStatsStateModel) {
        return state.loadingUnitRegistration || state.loadingUnitRegistrationMembers;
    }

    constructor(
        private webApiService: WebApiService,
        private webApiUnitMembersService: WebApiUnitMembersService
    ) {
    }

    @Action(LoadUnitRegistrations)
    loadUnitRegistrations(ctx: StateContext<UnitStatsStateModel>, action: LoadUnitRegistrations) {
        ctx.patchState({
            loadingUnitRegistration: true
        });

        if (action.unitId) {
            return this.webApiService.call(
                new UnitRegistrationAll(APP_ID, ApplicationSettings.getString(USER_TOKEN), action.unitId),
                () => new UnitRegistrationAllOutput(),
                wsOrganizationUnit
            ).pipe(
                tap((response: UnitRegistrationAllOutput[]) => {
                    ctx.patchState({
                        loadingUnitRegistration: false,
                        unitRegistrations: response
                    });
                }),
                catchError(e => {
                    ctx.patchState({
                        loadingUnitRegistration: false,
                        unitRegistrations: initialStateModel.unitRegistrations,
                        unitRegistrationMembers: initialStateModel.unitRegistrationMembers,
                        unitRegistrationMembersUnits: initialStateModel.unitRegistrationMembersUnits,
                        unitRegistrationMembersAges: initialStateModel.unitRegistrationMembersAges,
                        unitRegistrationMembersCategories: initialStateModel.unitRegistrationMembersCategories
                    });

                    throw e;
                })
            );
        } else {
            ctx.patchState({
                loadingUnitRegistration: false
            });
        }
    }

    @Action(LoadUnitRegistrationMembers)
    loadUnitRegistrationMembers(ctx: StateContext<UnitStatsStateModel>, action: LoadUnitRegistrationMembers) {
        ctx.patchState({
            loadingUnitRegistrationMembers: true
        });

        if (action.registrationYearId) {
            return this.webApiUnitMembersService.call(
                new UnitRegistrationMembers(APP_ID, ApplicationSettings.getString(USER_TOKEN), action.registrationYearId),
                () => new UnitRegistrationMembersOutput(),
                wsOrganizationUnit
            ).pipe(
                tap((response: UnitRegistrationMembersOutput) => {
                    ctx.patchState({
                        loadingUnitRegistrationMembers: false,
                        unitRegistrationMembers: response,
                        unitRegistrationMembersUnits: response.Units ? response.Units : [],
                        unitRegistrationMembersAges: response.MembersAge ? response.MembersAge : [],
                        unitRegistrationMembersCategories: response.MembersCategory ? response.MembersCategory : []
                    });
                }),
                catchError(e => {
                    ctx.patchState({
                        loadingUnitRegistrationMembers: false,
                        unitRegistrationMembers: initialStateModel.unitRegistrationMembers,
                        unitRegistrationMembersUnits: initialStateModel.unitRegistrationMembersUnits,
                        unitRegistrationMembersAges: initialStateModel.unitRegistrationMembersAges,
                        unitRegistrationMembersCategories: initialStateModel.unitRegistrationMembersCategories
                    });

                    throw e;
                })
            );
        } else {
            ctx.patchState({
                loadingUnitRegistrationMembers: false
            });
        }
    }
}
