import { Action, Selector, State, StateContext } from '@ngxs/store';
import { tap, catchError } from 'rxjs/operators';
import { wsEvents } from '~/constants/api.constants';
import { USER_TOKEN } from '~/constants/login-constants';
import { WebApiService } from '~/core/services/web-api.service';
import { ApplicationSettings as AppSettings } from '@nativescript/core';

import { CongEventOutput, EventCongressAll } from '../../entities/cong-event-search.types';
import { LoadCongEvents, SetCongEventSearchParams, SetCongEventSortParams } from './cong-event-search-list.actions';
import { isEqualJson } from '../../util';
import { CongEventSortKey, SortDirection, SortParams } from '../../types/EventSorting';
import { UnitOutput } from '~/pages/event/entities/gen-event-new.types';
import { CongScheduleType, CongEventRel } from '../../types/CongEventSearch';




export interface CongEventSearchListStateModel {
    sortParams: SortParams;
    events: CongEventOutput[];
    searchParams: CongEventSearch;
}
export interface CongEventSearch {
    schedule: string;
    relation: string;
    unit: UnitOutput;
}

const initialStateModel: CongEventSearchListStateModel = {
    events: [],
    searchParams: {
        schedule: CongScheduleType.PAST,
        relation: CongEventRel.ME_AND_MY_UNIT,
        unit: null
    },
    sortParams: {
        sortByKey: CongEventSortKey.NAME,
        sortDirection: SortDirection.ASC,
    }
};


@State<CongEventSearchListStateModel>({
    name: 'CongEventSearchList',
    defaults: initialStateModel
})

export class CongEventSearchListState {
    constructor(
        private webApiService: WebApiService
    ) {
    }
    @Selector()
    static isSearchSortDirty(state: CongEventSearchListStateModel) {
        const search = isEqualJson(initialStateModel.searchParams, state.searchParams)
        const sort = isEqualJson(initialStateModel.sortParams, state.sortParams)
        return !sort || !search;
    }

    @Selector()
    static getEvents(state: CongEventSearchListStateModel) {
        return state.events;
    }

    @Selector()
    static getSearchParams(state: CongEventSearchListStateModel) {
        return state.searchParams;
    }
    @Selector()
    static getSortParams(state: CongEventSearchListStateModel) {
        return state.sortParams;
    }

    @Action(LoadCongEvents)
    loadEvents(ctx: StateContext<CongEventSearchListStateModel>) {
        const { schedule, relation, unit } = ctx.getState().searchParams;
        const tk = AppSettings.getString(USER_TOKEN)
        const model = new EventCongressAll(tk,
            unit ? unit.ID : undefined,
            schedule === CongScheduleType.FUTURE ?
                true : schedule === CongScheduleType.PAST ? false : undefined,
            relation === CongEventRel.UNIT_PLACE || undefined,
            relation === CongEventRel.ALL_UNIT_PLACE || undefined,
            relation === CongEventRel.ME_AND_MY_UNIT || undefined,
        );
        return this.webApiService.call(model,
            () => new CongEventOutput(),
            wsEvents
        ).pipe(
            tap((response: CongEventOutput[]) => {
                ctx.patchState({
                    events: response
                });
            }),
            catchError(e => {
                ctx.patchState({
                    events: initialStateModel.events
                });

                throw e;
            })
        );
    }

    @Action(SetCongEventSortParams)
    setSortParams(ctx: StateContext<CongEventSearchListStateModel>,
        { payload }: SetCongEventSortParams) {
        ctx.patchState({
            sortParams: payload || initialStateModel.sortParams
        })
    }
    @Action(SetCongEventSearchParams)
    setSearchParams(ctx: StateContext<CongEventSearchListStateModel>,
        { payload }: SetCongEventSearchParams) {
        ctx.patchState({
            searchParams: payload || initialStateModel.searchParams
        })
    }


}
