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 } from '~/constants/login-constants';
import { WebApiService } from '~/core/services/web-api.service';
import { WarehouseDetail } from '../entities/input/warehouseDetail';
import { WarehouseUpdate } from '../entities/input/warehouseUpdate';
import { WarehouseDetailOutput } from '../entities/output/warehouseDetailOutput';
import { WarehouseUpdateOutput } from '../entities/output/warehouseUpdateOutput';
import { CreateWarehouseUpdate, LoadWarehouseDetail } from './warehouse-update.action';

export interface WarehouseUpdateStateModel {
    loadingWarehouseDetail: boolean;
    loadingWarehouseUpdate: boolean;
    warehouseDetail: WarehouseDetailOutput;
    warehouseUpdate: WarehouseUpdateOutput;
}

const initialStateModel: WarehouseUpdateStateModel = {
    loadingWarehouseDetail: false,
    loadingWarehouseUpdate: false,
    warehouseDetail: null,
    warehouseUpdate: null
};

@State<WarehouseUpdateStateModel>({
    name: 'warehouseUpdate',
    defaults: initialStateModel
})
export class WarehouseUpdateState {
    @Selector()
    static getWarehouseDetail(state: WarehouseUpdateStateModel) {
        return state.warehouseDetail;
    }

    @Selector()
    static getWarehouseUpdate(state: WarehouseUpdateStateModel) {
        return state.warehouseUpdate;
    }

    @Selector()
    static isLoading(state: WarehouseUpdateStateModel) {
        return state.loadingWarehouseDetail || state.loadingWarehouseUpdate;
    }

    constructor(
        private webApiService: WebApiService
    ) {
    }

    /**
     * Load warehouse detail
     *
     * @param {StateContext<WarehouseUpdateStateModel>} ctx
     * @param {LoadWarehouseDetail} action
     * @returns {Observable<any>}
     */
    @Action(LoadWarehouseDetail)
    loadWarehouseDetail(ctx: StateContext<WarehouseUpdateStateModel>, action: LoadWarehouseDetail) {
        ctx.patchState({
            loadingWarehouseDetail: true
        });

        if (action.id) {
            return this.webApiService.call(
                new WarehouseDetail(APP_ID, ApplicationSettings.getString(USER_TOKEN), action.id),
                () => new WarehouseDetailOutput(),
                wsMaterial
            ).pipe(
                tap((response: WarehouseDetailOutput[]) => {
                    if (response.length === 1) {
                        ctx.patchState({
                            loadingWarehouseDetail: false,
                            warehouseDetail: response[0]
                        });
                    } else {
                        ctx.patchState({
                            loadingWarehouseDetail: false,
                            warehouseDetail: initialStateModel.warehouseDetail
                        });
                        throw new Error('Nepodařilo se nalézt detail skladu');
                    }
                }),
                catchError(e => {
                    ctx.patchState({
                        loadingWarehouseDetail: false,
                        warehouseDetail: initialStateModel.warehouseDetail
                    });

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

    /**
     * It create request for rent insert
     *
     * @param {StateContext<WarehouseUpdateStateModel>} ctx
     * @param {CreateWarehouseUpdate} action
     * @returns {Observable<any>}
     */
    @Action(CreateWarehouseUpdate)
    createWarehouseUpdate(ctx: StateContext<WarehouseUpdateStateModel>, action: CreateWarehouseUpdate) {
        ctx.patchState({
            loadingWarehouseUpdate: true
        });

        return this.webApiService.call(
            new WarehouseUpdate(
                APP_ID, ApplicationSettings.getString(USER_TOKEN), action.id, action.name, action.idWarType, action.warType,
                action.idUnit, action.unit, action.regNumber, action.unitFullName, action.idWarMain ? action.idWarMain : undefined,
                action.warMain, action.street, action.city, action.postcode, action.note, action.idEvent ? action.idEvent : undefined,
                action.idDistrict ? action.idDistrict : undefined, action.gpsLat ? action.gpsLat : undefined,
                action.gpsLong ? action.gpsLong : undefined, action.idUnitCentral ? action.idUnitCentral : undefined),
            () => new WarehouseUpdateOutput(),
            wsMaterial
        ).pipe(
            tap((response: WarehouseUpdateOutput) => {
                ctx.patchState({
                    loadingWarehouseUpdate: false,
                    warehouseUpdate: response
                });
            }),
            catchError(e => {
                ctx.patchState({
                    loadingWarehouseUpdate: false,
                    warehouseUpdate: initialStateModel.warehouseUpdate
                });
                throw e;
            })
        );
    }
}
