import { Component, OnInit, ViewContainerRef } from '@angular/core';
import { actionsExecuting, ActionsExecuting } from '@ngxs-labs/actions-executing';
import { Select, Store } from '@ngxs/store';
import { RouterExtensions, ModalDialogService, ModalDialogOptions } from '@nativescript/angular';
import { Observable } from 'rxjs';
import { withLatestFrom } from 'rxjs/operators';
import { transitionOptions } from '~/constants/shared.constants';
import { GenEventOutput } from '~/pages/event/entities/gen-event-search.types';
import { CongEventOutput } from '~/pages/event/entities/cong-event-search.types';
import { LoadCongEvents, SetCongEventSearchParams, SetCongEventSortParams } from '~/pages/event/state-mgmt/cong/cong-event-search-list.actions';
import { CongEventSearchListState, CongEventSearch } from '~/pages/event/state-mgmt/cong/cong-event-search-list.state';
import { CongEventSortKey, formattedCongEventSortKeys, SortDirection, SortParams } 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 { CongEventSearchForm, CongEventSearchModalComponent } from '~/pages/event/containers/cong/cong-event-search-modal/cong-event-search-modal.component';
import { ScheduleType } from '~/pages/event/types/GenEventSearch';
import { SortSearchTag, ModalType } from '~/pages/event/types/common.types';
import { sortCongEvents } from '~/pages/event/util/event';
import { formattedCongEventRel } from '~/pages/event/types/CongEventSearch';
import { sortIcon, searchIcon } from '~/constants/icons';

@Component({
    selector: 'CongEventSearchList',
    moduleId: module.id,
    templateUrl: './cong-event-list-page.component.html',
})
export class CongEventListPageComponent implements OnInit {
    @Select(actionsExecuting([LoadCongEvents]))
    isLoading$: Observable<ActionsExecuting>;
    @Select(CongEventSearchListState.getEvents)
    eventList$: Observable<CongEventOutput[]>;
    @Select(CongEventSearchListState.getSortParams)
    sortParams$: Observable<SortParams>;
    @Select(CongEventSearchListState.getSearchParams)
    searchParams$: Observable<CongEventSearch>;
    @Select(CongEventSearchListState.isSearchSortDirty)
    isSearchSortDirty$: Observable<boolean>;

    eventList: CongEventOutput[];
    _sortParams: SortParams;
    searchParams: CongEventSearch;

    topBarHeight = TOP_ACTION_BAR_HEIGHT;


    actionBarActions: ActionBarAction[] = [
        { type: 'sort', icon: sortIcon },
        { type: 'search', icon: searchIcon },
    ]
    constructor(
        private routerExtensions: RouterExtensions,
        private store: Store,
        private _modalService: ModalDialogService,
        private _vcRef: ViewContainerRef,

    ) {
    }

    tags: Array<SortSearchTag> = []
    paramLabels = {
        [CongEventSortKey.NAME]: "Jméno",
        [CongEventSortKey.START]: "Začátek",
        [CongEventSortKey.END]: "Konec",
        [CongEventSortKey.UNIT]: "Pořádající jednotka",
        [SortDirection.ASC]: 'Vzestupně',
        [SortDirection.DESC]: 'Sestupně',
        [ScheduleType.FUTURE]: 'Teprve proběhne',
        [ScheduleType.PAST]: 'Již proběhla',
    }

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

    refreshTags({ sortByKey, sortDirection }: SortParams, search: CongEventSearch) {
        const { relation, schedule, unit } = search

        this.tags = [
            { text: `Seřaděno dle: ${this.paramLabels[sortByKey]}`, modalType: ModalType.Sort },
            { text: `Směr: ${this.paramLabels[sortDirection]}`, modalType: ModalType.Sort },
            schedule && schedule !== ScheduleType.YEAR && { text: `Termín: ${this.paramLabels[schedule]}`, modalType: ModalType.Search },
            relation && { text: `Vztah k akci: ${formattedCongEventRel.find(c => c.key === relation).label}`, modalType: ModalType.Search },
            unit && { text: `Pořádající jednotka: ${unit.DisplayName}`, modalType: ModalType.Search },
        ].filter(s => s)
    }

    refreshEvents() {
        this.eventList = [];
        this.store.dispatch(new LoadCongEvents())
            .pipe(withLatestFrom(this.eventList$, this.sortParams$, this.searchParams$))
            .subscribe(([_, evs, sortParams, searchParams]) => {
                this.searchParams = searchParams;
                this.eventList = evs;
                this.eventList = sortCongEvents(evs, sortParams);
                this.refreshTags(sortParams, searchParams);
            })
    }

    ngOnInit(): void {
        this.refreshEvents();
    }

    onShowUnit(unitId: number) {
        setTimeout(() => {
            this.routerExtensions.navigate(['unit',
                unitId], { transition: transitionOptions });
        }, 10);
    }

    onShowEvent(event: GenEventOutput) {
        setTimeout(() => {
            this.routerExtensions.navigate(['event/congressDetail/',
                event.ID], { transition: transitionOptions });
        }, 10);
    }

    openSortingModal() {
        this._sortParams = this.store.selectSnapshot(CongEventSearchListState.getSortParams)
        const options: ModalDialogOptions = {
            viewContainerRef: this._vcRef,
            context: { sortParams: this._sortParams, formattedSortByKeys: formattedCongEventSortKeys },
            fullscreen: false,
        };
        this._modalService.showModal(SortModalComponent, options)
            .then((formResult: SortParams) => {
                if (formResult) {
                    this.store.dispatch(new SetCongEventSortParams(formResult))
                        .pipe(withLatestFrom(this.eventList$, this.sortParams$, this.searchParams$))
                        .subscribe(([_, events, sortParams, searchParams]) => {
                            this._sortParams = sortParams
                            this.eventList = sortCongEvents(events, sortParams);
                            this.refreshTags(sortParams, searchParams)
                        })
                }
            });
    }

    openSearchModal() {
        this.searchParams = this.store.selectSnapshot(CongEventSearchListState.getSearchParams)
        const { unit, schedule, relation } = this.searchParams
        const searchParams: CongEventSearchForm = { schedule, relation, unitId: unit && unit.ID.toString() }
        const options: ModalDialogOptions = {
            viewContainerRef: this._vcRef,
            context: { searchParams, selectedUnitData: this.searchParams.unit },
            fullscreen: false,
        };

        this._modalService.showModal(CongEventSearchModalComponent, options)
            .then((formResult: CongEventSearch) => {
                if (formResult) {
                    this.store.dispatch(new SetCongEventSearchParams(formResult))
                        .subscribe((_) => {
                            this.refreshEvents();
                        })
                }
            });
    }
    onAction(action: ActionBarAction) {
        if (action.type === "sort") {
            this.openSortingModal();
        } else if (action.type === "search") {
            this.openSearchModal();
        }
    }

}
