import { ApplicationSettings } from '@nativescript/core';
import { Action, Selector, State, StateContext } from '@ngxs/store';
import { catchError, tap } from 'rxjs/operators';
import { APP_ID, wsMessage } from '~/constants/api.constants';
import { USER_TOKEN } from '~/constants/login-constants';
import { WebApiService } from '~/core/services/web-api.service';
import { MessageDetail } from '~/pages/message/entities/input/messageDetail';
import { MessageUpdateDelete } from '~/pages/message/entities/input/messageUpdateDelete';
import { MessageDetailOutput } from '~/pages/message/entities/output/messageDetailOutput';
import { MessageUpdateDeleteOutput } from '~/pages/message/entities/output/messageUpdateDeleteOutput';
import { CreateMessageUpdatedDelete, LoadMessageDetail } from '~/pages/message/state-mgmt/message-detail.actions';

export interface MessageDetailStateModel {
    loadingMessageDetail: boolean;
    loadingCreateUpdateDeleteMessage: boolean;
    messageDetail: MessageDetailOutput;
}

const initialStateModel: MessageDetailStateModel = {
    loadingMessageDetail: false,
    loadingCreateUpdateDeleteMessage: false,
    messageDetail: null,
};

@State<MessageDetailStateModel>({
    name: 'messageDetail',
    defaults: initialStateModel
})

export class MessageDetailState {

    @Selector()
    static getMessageDetail(state: MessageDetailStateModel) {
        return state.messageDetail;
    }

    @Selector()
    static isLoading(state: MessageDetailStateModel) {
        return state.loadingMessageDetail
            || state.loadingCreateUpdateDeleteMessage;
    }

    constructor(
        private webApiService: WebApiService
    ) {
    }

    /**
     * Load message detail by id
     *
     * @param {StateContext<StsStateModel>} ctx
     * @param {LoadEnrollNumbers} action
     * @returns {Observable<any>}
     */
    @Action(LoadMessageDetail)
    loadMessageDetail(ctx: StateContext<MessageDetailStateModel>, action: LoadMessageDetail) {
        ctx.patchState({
            loadingMessageDetail: true
        });

        return this.webApiService.call(
            new MessageDetail(APP_ID, ApplicationSettings.getString(USER_TOKEN), action.id),
            () => new MessageDetailOutput(),
            wsMessage
        ).pipe(
            tap((response: MessageDetailOutput[]) => {
                if (response.length === 1) {
                    ctx.patchState({
                        loadingMessageDetail: false,
                        messageDetail: response[0]
                    });
                } else {
                    ctx.patchState({
                        loadingMessageDetail: false,
                        messageDetail: initialStateModel.messageDetail
                    });
                }
            }),
            catchError(e => {
                ctx.patchState({
                    loadingMessageDetail: false,
                    messageDetail: initialStateModel.messageDetail
                });

                throw e;
            })
        );
    }

    /**
     * It create request for Delete message
     *
     * @param {StateContext<MessageDetailState>} ctx
     * @param {CreateMessageUpdatedDelete} action
     * @returns {Observable<any>}
     */
    @Action(CreateMessageUpdatedDelete)
    createMessageUpdateDelete(ctx: StateContext<MessageDetailStateModel>, action: CreateMessageUpdatedDelete) {
        ctx.patchState({
            loadingCreateUpdateDeleteMessage: true
        });

        if (action.id && action.deleteMessage) {
            return this.webApiService.call(
                new MessageUpdateDelete(APP_ID, ApplicationSettings.getString(USER_TOKEN), action.id, action.deleteMessage),
                () => new MessageUpdateDeleteOutput(),
                wsMessage
            ).pipe(
                tap((response: MessageUpdateDeleteOutput) => {
                    ctx.patchState({
                        loadingCreateUpdateDeleteMessage: false
                    });
                }),
                catchError(e => {
                    ctx.patchState({
                        loadingCreateUpdateDeleteMessage: false
                    });
                    throw e;
                })
            );
        } else {
            ctx.patchState({
                loadingCreateUpdateDeleteMessage: false
            });
        }
    }
}
