import { Component, OnInit, ViewContainerRef } from '@angular/core';
import { actionsExecuting, ActionsExecuting } from '@ngxs-labs/actions-executing';
import { Select, Store } from '@ngxs/store';
import { ModalDialogOptions, ModalDialogService, RouterExtensions } from '@nativescript/angular';
import { Observable } from 'rxjs';
import { withLatestFrom } from 'rxjs/operators';
import { EduEventMySearchFormData, EduEventSortFilterFormData, formattedEduEventMyEventRel } from '~/pages/event/types/EduEventSearch';
import { EduEventMyActionsOutput, EduEventType, } from '~/pages/event/entities/edu-event-search.types';
import { LoadEduEventTypes, LoadMyEduEvents, SetEduEventMySortParams, SetEduEventMySearchParams } from '~/pages/event/state-mgmt/edu/edu-event-search.actions';
import { EduEventSearchListState } from '~/pages/event/state-mgmt/edu/edu-event-search-list.state';
import { isEqualJson } from '~/pages/event/util';
import { SortParams, formattedEduEventMySortKeys, formattedSortDirection } from '~/pages/event/types/EventSorting';
import { SortModalComponent } from '~/pages/event/components/common/sort-modal/sort-modal.component';
import { ActionBarAction, TOP_ACTION_BAR_HEIGHT } from '~/pages/event/components/common/disappearing-scroll-action-bar/disappearing-scroll-action-bar.component';
import { SortSearchTag, ModalType } from '~/pages/event/types/common.types';
import { EduEventMySearchListState } from '~/pages/event/state-mgmt/edu/edu-event-my-search-list.state';
import { EduEventMySearchModalComponent } from '~/pages/event/components/edu/edu-event-my-search-modal/edu-event-my-search-modal.component';
import { ScheduleType } from '~/pages/event/types/GenEventSearch';
import { sortFilterMyEduEvents } from '~/pages/event/util/event';
import { sortIcon, searchIcon } from '~/constants/icons';


@Component({
    selector: 'EduEventMyListPage',
    moduleId: module.id,
    templateUrl: './edu-event-my-list-page.component.html',
})
export class EduEventMyListPageComponent implements OnInit {
    @Select(actionsExecuting([LoadMyEduEvents]))
    isLoading$: Observable<ActionsExecuting>;
    @Select(EduEventMySearchListState.getEvents)
    eventList$: Observable<EduEventMyActionsOutput[]>;
    @Select(EduEventMySearchListState.getEventSearchParams)
    searchParams$: Observable<EduEventMySearchFormData>;
    @Select(EduEventMySearchListState.getSortParams)
    sortParams$: Observable<SortParams>;
    @Select(EduEventSearchListState.getEventTypes)
    eventTypes$: Observable<EduEventType[]>


    searchParams: EduEventMySearchFormData;
    eventList: EduEventMyActionsOutput[];
    sortParams: SortParams;
    @Select(EduEventMySearchListState.isSearchSortDirty)
    isSearchSortDirty$: Observable<boolean>;

    types: EduEventType[];

    topBarHeight = TOP_ACTION_BAR_HEIGHT;

    tags: Array<SortSearchTag> = [];
    paramLabels = {
        [ScheduleType.FUTURE]: 'Teprve proběhne',
        [ScheduleType.PAST]: 'Již proběhla',
    }

    actionBarActions: ActionBarAction[] = [
        { type: 'sort', icon: sortIcon },
        { type: 'search', icon: searchIcon },
    ]

    constructor(
        private routerExtensions: RouterExtensions,
        private store: Store,
        private _vcRef: ViewContainerRef,
        private _modalService: ModalDialogService,
    ) {
    }

    refreshTags() {
        this.searchParams = this.store.selectSnapshot(EduEventMySearchListState.getEventSearchParams);
        this.sortParams = this.store.selectSnapshot(EduEventMySearchListState.getSortParams);
        const { type, year, unit, relation, schedule } = this.searchParams
        this.tags = [
            { text: `Seřaděno dle: ${formattedEduEventMySortKeys.find(k => k.key === this.sortParams.sortByKey).label}`, modalType: ModalType.Sort },
            { text: `Směr: ${formattedSortDirection.find(d => d.key === this.sortParams.sortDirection).label}`, modalType: ModalType.Sort },
            year && schedule === ScheduleType.YEAR && { text: `Rok: ${year}`, modalType: ModalType.Search },
            type && { text: `Typ: ${type.displayName}`, modalType: ModalType.Search },
            unit && { text: `Název pořadatele: ${unit}`, modalType: ModalType.Search },
            schedule && schedule !== ScheduleType.YEAR && { text: `Termín: ${this.paramLabels[schedule]}`, modalType: ModalType.Search },
            relation && { text: `Vztah k akci: ${formattedEduEventMyEventRel.find(r => r.key === relation).label}`, modalType: ModalType.Search },
        ].filter(s => s);

    }

    refreshEvents() {
        this.eventList = []
        this.refreshTags()
        this.store.dispatch(new LoadMyEduEvents())
            .pipe(withLatestFrom(this.eventList$, this.searchParams$, this.sortParams$))
            .subscribe(([_, evs, search, sort]) => {
                if (evs.length === 0) {
                    this.eventList = []
                }
                this.eventList = sortFilterMyEduEvents(evs, sort, search);
            })
    }

    ngOnInit(): void {
        this.store.dispatch([new LoadEduEventTypes()])
        this.refreshEvents();
    }

    onBackButton(): void {
        this.routerExtensions.back();
    }

    openSearchModal() {
        this.searchParams = this.store.selectSnapshot(EduEventMySearchListState.getEventSearchParams)
        this.sortParams = this.store.selectSnapshot(EduEventMySearchListState.getSortParams)
        this.types = this.store.selectSnapshot(EduEventSearchListState.getEventTypes)
        const { searchParams, sortParams: sortFilterParams, types } = this;
        const options: ModalDialogOptions = {
            viewContainerRef: this._vcRef,
            context: { searchParams, types, sortFilterParams },
            fullscreen: false,
        };

        this._modalService.showModal(EduEventMySearchModalComponent, options)
            .then((formResult: EduEventMySearchFormData) => {
                if (formResult) {
                    this.store.dispatch(
                        new SetEduEventMySearchParams(formResult)
                    ).pipe(withLatestFrom(this.searchParams$,
                        this.sortParams$, this.eventList$))
                        .subscribe(([_, search, sort, events]) => {
                            if (!isEqualJson(search, searchParams)) {
                                this.refreshEvents();
                            } else if (!isEqualJson(sort, sortFilterParams)) {
                                this.eventList = sortFilterMyEduEvents(events, sort, searchParams)
                            }
                        })
                }

            });
    }

    openSortingModal() {
        this.sortParams = this.store.selectSnapshot(EduEventMySearchListState.getSortParams)

        const options: ModalDialogOptions = {
            viewContainerRef: this._vcRef,
            context: { sortParams: { ...this.sortParams, onlyQualification: undefined }, formattedSortByKeys: formattedEduEventMySortKeys },
            fullscreen: false,
        };

        this._modalService.showModal(SortModalComponent, options)
            .then((formResult: EduEventSortFilterFormData) => {
                if (formResult) {
                    this.sortParams = {
                        ...formResult,
                    };
                    this.store.dispatch(new SetEduEventMySortParams(this.sortParams))
                        .pipe(withLatestFrom(this.eventList$, this.sortParams$, this.searchParams$))
                        .subscribe(([_, events, sortParams, search]) => {
                            this.eventList = sortFilterMyEduEvents(events, sortParams, search)
                            this.refreshTags()
                        })
                }
            });
    }

    resetSortSearch() {
        this.store.dispatch([
            new SetEduEventMySortParams(),
            new SetEduEventMySearchParams()])
            .subscribe(() => {
                this.refreshEvents();
            })
    }

    onAction(action: ActionBarAction) {
        if (action.type === "sort") {
            this.openSortingModal();
        } else if (action.type === "search") {
            this.openSearchModal();
        }
    }

}

