import { ApplicationSettings } from '@nativescript/core';
import { Action, Selector, State, StateContext } from '@ngxs/store';
import { catchError, tap } from 'rxjs/operators';
import { APP_ID, wsMaterial } from '~/constants/api.constants';
import { USER_TOKEN, USER_UNIT_ID } from '~/constants/login-constants';
import { WebApiService } from '~/core/services/web-api.service';
import { WarehouseItemAll } from '../entities/input/warehouseItemAll';
import { WarehouseItemAllOutput } from '../entities/output/warehouseItemAllOutput';
import { LoadWarehouseItemAll, LoadWarehouseItemDeleted } from './material-unit.action';

export interface MaterialUnitStateModel {
    loadingWarehouseItemAll: boolean;
    loadingWarehouseItemsDeleted: boolean;
    warehouseItems: WarehouseItemAllOutput[];
    deletedItems: WarehouseItemAllOutput[];
}

const initialStateModel: MaterialUnitStateModel = {
    loadingWarehouseItemAll: false,
    loadingWarehouseItemsDeleted: false,
    warehouseItems: [],
    deletedItems: []
};

@State<MaterialUnitStateModel>({
    name: 'materialUnit',
    defaults: initialStateModel
})
export class MaterialUnitState {
    @Selector()
    static getWarehouseItems(state: MaterialUnitStateModel) {
        return state.warehouseItems;
    }

    @Selector()
    static getWarehouseDeletedItems(state: MaterialUnitStateModel) {
        return state.deletedItems;
    }

    @Selector()
    static isLoading(state: MaterialUnitStateModel) {
        return state.loadingWarehouseItemAll || state.loadingWarehouseItemsDeleted;
    }

    constructor(
        private webApiService: WebApiService
    ) {
    }

    /**
     * Load warehouses items (not deleted items)
     *
     * @param {StateContext<MaterialUnitStateModel>} ctx
     * @param {LoadWarehouseItemAll} action
     * @returns {Observable<any>}
     */
    @Action(LoadWarehouseItemAll)
    loadWarehouseItemNotDeleted(ctx: StateContext<MaterialUnitStateModel>, action: LoadWarehouseItemAll) {
        ctx.patchState({
            loadingWarehouseItemAll: true
        });

        return this.webApiService.call(
            new WarehouseItemAll(APP_ID, ApplicationSettings.getString(USER_TOKEN), ApplicationSettings.getNumber(USER_UNIT_ID), false),
            () => new WarehouseItemAllOutput(),
            wsMaterial
        ).pipe(
            tap((response: WarehouseItemAllOutput[]) => {
                ctx.patchState({
                    loadingWarehouseItemAll: false,
                    warehouseItems: response
                });
            }),
            catchError(e => {
                ctx.patchState({
                    loadingWarehouseItemAll: false,
                    warehouseItems: initialStateModel.warehouseItems
                });

                throw e;
            })
        );
    }

    /**
     * Load warehouse deleted items
     *
     * @param {StateContext<MaterialUnitStateModel>} ctx
     * @param {LoadWarehouseItemDeleted} action
     * @returns {Observable<any>}
     */
    @Action(LoadWarehouseItemDeleted)
    loadWarehouseItemDeleted(ctx: StateContext<MaterialUnitStateModel>, action: LoadWarehouseItemDeleted) {
        ctx.patchState({
            loadingWarehouseItemsDeleted: true
        });

        return this.webApiService.call(
            new WarehouseItemAll(APP_ID, ApplicationSettings.getString(USER_TOKEN), ApplicationSettings.getNumber(USER_UNIT_ID), true),
            () => new WarehouseItemAllOutput(),
            wsMaterial
        ).pipe(
            tap((response: WarehouseItemAllOutput[]) => {
                ctx.patchState({
                    loadingWarehouseItemsDeleted: false,
                    deletedItems: response
                });
            }),
            catchError(e => {
                ctx.patchState({
                    loadingWarehouseItemsDeleted: false,
                    deletedItems: initialStateModel.deletedItems
                });

                throw e;
            })
        );
    }
}
