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

import { wsEvents } from '~/constants/api.constants';
import { USER_TOKEN } from '~/constants/login-constants';
import { WebApiService } from '~/core/services/web-api.service';
import { EduEventMyEventRelationType, EduEventMySearchFormData } from '~/pages/event/types/EduEventSearch';
import { LoadMyEduEvents, SetEduEventMySearchParams, SetEduEventMySortParams } from './edu-event-search.actions';
import { EventEducationAllMyActions, EduEventMyActionsOutput } from '~/pages/event/entities/edu-event-search.types';
import { isEqualJson } from '../../util';
import { EduEventMySortKey, SortDirection } from '../../types/EventSorting';
import { SortParams } from '~/pages/event/types/EventSorting';
import { ScheduleType } from '~/pages/event/types/GenEventSearch';

export interface EduEventMySearchListStateModel {
    events: EduEventMyActionsOutput[];
    eventSearchParams: EduEventMySearchFormData;
    sortParams: SortParams;
}
const initialStateModel: EduEventMySearchListStateModel = {
    events: [],
    eventSearchParams: {
        year: (new Date()).getFullYear().toString(),
        type: null, relation: EduEventMyEventRelationType.PARTICIPANT,
        schedule: ScheduleType.ALL, unit: '',
    },
    sortParams: {
        sortByKey: EduEventMySortKey.NAME.toString(),
        sortDirection: SortDirection.ASC.toString(),
    },
};

@State<EduEventMySearchListStateModel>({
    name: 'eduEventMySearchList',
    defaults: initialStateModel
})

export class EduEventMySearchListState {

    @Selector()
    static isSearchSortDirty(state: EduEventMySearchListStateModel) {
        const sort = isEqualJson(initialStateModel.eventSearchParams, state.eventSearchParams)
        const search = isEqualJson(initialStateModel.sortParams, state.sortParams)
        return !sort || !search;
    }

    @Selector()
    static getEvents(state: EduEventMySearchListStateModel) {
        return state.events;
    }
    @Selector()
    static getSortParams(state: EduEventMySearchListStateModel) {
        return state.sortParams;
    }

    @Selector()
    static getEventSearchParams(state: EduEventMySearchListStateModel) {
        return state.eventSearchParams;
    }

    constructor(
        private webApiService: WebApiService
    ) {
    }

    @Action(LoadMyEduEvents)
    loadMyEvents(ctx: StateContext<EduEventMySearchListStateModel>) {
        const { year, type, schedule, relation } = ctx.getState().eventSearchParams;
        const tk = AppSettings.getString(USER_TOKEN);
        const input = new EventEducationAllMyActions(
            tk,
            schedule === ScheduleType.YEAR ? parseInt(year, 10) : undefined,
            schedule === ScheduleType.FUTURE ? true : schedule === ScheduleType.PAST ? false : undefined,
            type ? type && parseInt(type.id, 10) : undefined,
            relation === EduEventMyEventRelationType.ALL ? undefined : relation
        );

        return this.webApiService.call(
            input,
            () => new EduEventMyActionsOutput(),
            wsEvents
        ).pipe(
            tap((response: EduEventMyActionsOutput[]) => {
                ctx.patchState({
                    events: response
                });
            }),
            catchError(e => {
                ctx.patchState({
                    events: initialStateModel.events
                });

                throw e;
            })
        );
    }

    @Action(SetEduEventMySearchParams)
    setEventSearchParams(ctx: StateContext<EduEventMySearchListStateModel>, action: SetEduEventMySearchParams) {
        ctx.patchState({
            eventSearchParams: action.payload || { ...initialStateModel.eventSearchParams }
        });
    }


    @Action(SetEduEventMySortParams)
    setEventSortFilterParams(ctx: StateContext<EduEventMySearchListStateModel>, action: SetEduEventMySortParams) {
        ctx.patchState({ sortParams: action.payload || { ...initialStateModel.sortParams } })
    }

}
