import { RouterExtensions } from '@nativescript/angular';
import { ApplicationSettings } from '@nativescript/core';
import { Action, Selector, State, StateContext } from '@ngxs/store';
import { catchError, tap } from 'rxjs/operators';
import { APP_ID, wsUserManagement } from '~/constants/api.constants';
import { USER_ID, USER_PERSON_ID, USER_PERSON_NAME, USER_TOKEN } from '~/constants/login-constants';
import { transitionOptions } from '~/constants/shared.constants';
import { LoginDataService } from '~/core/services/login-data.service';
import { WebApiService } from '~/core/services/web-api.service';
import { UserDetail } from '~/pages/login/entities/input/userDetail';
import { UserDetailOutput } from '~/pages/login/entities/output/userDetailOutput';
import {
    LoadUserDetail,
    StartSkautISLoading,
    StartSkautISPageLoading,
    StopSkautISLoading,
    StopSkautISPageLoading
} from '~/pages/login/state-mgmt/login.actions';

export interface LoginStateModel {
    loadingSkautISPage: boolean;
    loadingSkautIS: boolean;
    loadingUserDetail: boolean;
    userDetail: UserDetailOutput;
}

const initialStateModel: LoginStateModel = {
    loadingSkautISPage: false,
    loadingSkautIS: false,
    loadingUserDetail: false,
    userDetail: null
};

@State<LoginStateModel>({
    name: 'login',
    defaults: initialStateModel
})

export class LoginState {

    @Selector()
    static getUserDetail(state: LoginStateModel) {
        return state.userDetail;
    }

    @Selector()
    static isLoading(state: LoginStateModel) {
        return state.loadingSkautISPage || state.loadingSkautIS || state.loadingUserDetail;
    }

    constructor(
        private webApiService: WebApiService,
        private loginDataSrv: LoginDataService,
        private routerExtensions: RouterExtensions
    ) {
    }

    @Action(StartSkautISPageLoading)
    startSkautISPageLoading(ctx: StateContext<LoginStateModel>, action: StartSkautISPageLoading) {
        ctx.patchState({
            loadingSkautISPage: true
        });
    }

    @Action(StopSkautISPageLoading)
    stopSkautISPageLoading(ctx: StateContext<LoginStateModel>, action: StopSkautISPageLoading) {
        ctx.patchState({
            loadingSkautISPage: false
        });
    }

    @Action(StartSkautISLoading)
    startSkautISLoading(ctx: StateContext<LoginStateModel>, action: StartSkautISLoading) {
        ctx.patchState({
            loadingSkautIS: true
        });
    }

    @Action(StopSkautISLoading)
    stopSkautISLoading(ctx: StateContext<LoginStateModel>, action: StopSkautISLoading) {
        ctx.patchState({
            loadingSkautIS: false
        });
    }

    @Action(LoadUserDetail)
    loadUserDetail(ctx: StateContext<LoginStateModel>, action: LoadUserDetail) {
        ctx.patchState({
            loadingUserDetail: true
        });

        return this.webApiService.call(
            new UserDetail(APP_ID, ApplicationSettings.getString(USER_TOKEN, '')),
            () => new UserDetailOutput(),
            wsUserManagement
        ).pipe(
            tap((response: UserDetailOutput[]) => {
                if (response.length === 1) {
                    ApplicationSettings.setNumber(USER_ID, response[0].ID);
                    ApplicationSettings.setNumber(USER_PERSON_ID, response[0].ID_Person);
                    ApplicationSettings.setString(USER_PERSON_NAME, response[0].Person);
                    this.loginDataSrv.updateUserData();
                    this.routerExtensions.navigate(['/home/profile'], {
                        clearHistory: true,
                        transition: transitionOptions
                    });

                    ctx.patchState({
                        loadingUserDetail: false,
                        userDetail: response[0]
                    });
                } else {
                    ctx.patchState({
                        loadingUserDetail: false,
                        userDetail: initialStateModel.userDetail
                    });
                    throw new Error('Nepodařilo se načíst uživatelská data.');
                }
            }),
            catchError(e => {
                ctx.patchState({
                    loadingUserDetail: false,
                    userDetail: initialStateModel.userDetail
                });

                throw e;
            })
        );
    }
}
