import { Action, Selector, State, StateContext } from '@ngxs/store';
import { catchError, tap } from 'rxjs/operators';
import { ApplicationSettings as AppSettings } from '@nativescript/core';

import { wsOrganizationUnit } from '~/constants/api.constants';
import { USER_TOKEN } from '~/constants/login-constants';
import { WebApiService } from '~/core/services/web-api.service';
import { SortDirection, SortParams } from '~/pages/event/types/EventSorting';
import { isEqualJson } from '~/pages/event/util';
import { UnitAll } from '../entities/input/unitAll';
import { UnitAllOutput } from './../entities/output/unitAllOutput';
import { LoadUnits, SetUnitSearchParams, SetUnitSortParams } from './unit-search.actions';


export enum UnitSortKey {
    NAME = "DisplayName",
    REGISTRATION_NUMBER = "RegistrationNumber",
    TYPE = 'UnitType',
    LOCATION = "Location"
};

export interface UnitSearch {
    name: string
    registrationNumber: string;
    location: string;
    alignment: number;
    regNumberStart: boolean;
    accountNumber: string;
    ic: string;
}
export interface UnitSearchStateModel {

    units: UnitAllOutput[];
    sortParams: SortParams;
    searchParams: UnitSearch
}

const initialStateModel: UnitSearchStateModel = {
    units: [],
    searchParams: {
        name: null,
        registrationNumber: null,
        location: null,
        regNumberStart: false,
        ic: null,
        accountNumber: null,
        alignment: null,
    },
    sortParams: {
        sortByKey: UnitSortKey.REGISTRATION_NUMBER,
        sortDirection: SortDirection.ASC,
    },
};

@State<UnitSearchStateModel>({
    name: 'unitSearch',
    defaults: initialStateModel
})
export class UnitSearchState {

    @Selector()
    static getUnits(state: UnitSearchStateModel) {
        return state.units;
    }

    @Selector()
    static getSearchParams(state: UnitSearchStateModel) {
        return state.searchParams;
    }
    @Selector()
    static getSortParams(state: UnitSearchStateModel) {
        return state.sortParams;
    }
    @Selector()
    static isSearchSortDirty(state: UnitSearchStateModel) {
        const search = isEqualJson(initialStateModel.searchParams, state.searchParams)
        const sort = isEqualJson(initialStateModel.sortParams, state.sortParams)
        return !sort || !search;
    }

    constructor(
        private webApiService: WebApiService
    ) {
    }

    @Action(SetUnitSortParams)
    setSortParams(ctx: StateContext<UnitSearchStateModel>, { payload }: SetUnitSortParams) {
        ctx.patchState({
            sortParams: payload || { ...initialStateModel.sortParams },
        })
    }
    @Action(SetUnitSearchParams)
    setSearchParams(ctx: StateContext<UnitSearchStateModel>, { payload }: SetUnitSearchParams) {
        ctx.patchState({
            searchParams: payload || { ...initialStateModel.searchParams }
        })
    }

    @Action(LoadUnits)
    searchUnits(ctx: StateContext<UnitSearchStateModel>) {
        const { name, registrationNumber, alignment, location, accountNumber, regNumberStart, ic } = ctx.getState().searchParams;
        const ent = new UnitAll(AppSettings.getString(USER_TOKEN),
            name, registrationNumber, regNumberStart,
            location, accountNumber, ic, alignment)

        return this.webApiService.call(
            ent,
            () => new UnitAllOutput(),
            wsOrganizationUnit
        ).pipe(
            tap((response: UnitAllOutput[]) => {
                ctx.patchState({
                    units: response
                });

            }),
            catchError(e => {
                ctx.patchState({
                    units: initialStateModel.units
                });

                throw e;
            })
        );

    }
}
