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 { CampEventOutput, CampEventStateOutput } from '~/pages/event/entities/camp-event-search.types';
import { LoadCampEvents, LoadCampEventStates, SetCampEventSearchParams, SetCampEventSortParams } from '~/pages/event/state-mgmt/camp/camp-event-search-list.actions';
import { CampEventSearchListState, CampEventSearch } from '~/pages/event/state-mgmt/camp/camp-event-search-list.state';
import { GenEventOutput } from '~/pages/event/entities/gen-event-search.types';
import { CampEventSortKey, formattedCampEventSortKeys, SortDirection, SortParams } from '~/pages/event/types/EventSorting';
import { ActionBarAction, TOP_ACTION_BAR_HEIGHT } from '~/pages/event/components/common/disappearing-scroll-action-bar/disappearing-scroll-action-bar.component';
import { CampEventSearchModalComponent } from '~/pages/event/components/camp/camp-event-search-modal/camp-event-search-modal.component';
import { CampMapModal } from '~/pages/event/components/camp/camp-map-modal/camp-map-modal.component';
import { ScheduleType, EventRel } from '~/pages/event/types/GenEventSearch';
import { SortModalComponent } from '~/pages/event/components/common/sort-modal/sort-modal.component';
import { SortSearchTag, ModalType } from '~/pages/event/types/common.types';
import { sortCampEvents } from '~/pages/event/util/event';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import canEditEvent, { AuthEventType } from '~/pages/event/util/authorization';
import { addIcon, mapIcon, searchIcon, sortIcon } from '~/constants/icons';

@Component({
    selector: 'CampEventSearchList',
    moduleId: module.id,
    templateUrl: './camp-event-list-page.component.html',
})
export class CampEventListPageComponent implements OnInit {
    @Select(actionsExecuting([LoadCampEvents]))
    isLoading$: Observable<ActionsExecuting>;
    @Select(CampEventSearchListState.getEvents)
    eventList$: Observable<CampEventOutput[]>;
    @Select(CampEventSearchListState.getSortParams)
    sortParams$: Observable<SortParams>;
    @Select(CampEventSearchListState.getSearchParams)
    searchParams$: Observable<CampEventSearch>;
    @Select(CampEventSearchListState.getEventStates)
    eventStates$: Observable<CampEventStateOutput[]>;
    states: CampEventStateOutput[];
    @Select(CampEventSearchListState.isSearchSortDirty)
    isSearchSortDirty$: Observable<boolean>;

    eventList: CampEventOutput[];
    _sortParams: SortParams;
    searchParams: CampEventSearch;

    topBarHeight = TOP_ACTION_BAR_HEIGHT;

    actionBarActions: ActionBarAction[] = [
        { type: 'openMap', icon: mapIcon, title: 'Mapa' },
        { type: 'sort', icon: sortIcon },
        { type: 'search', icon: searchIcon },
        { type: 'new', icon: addIcon, disabled: !canEditEvent(null, AuthEventType.CAMP) },
    ]
    pageLoading: boolean;

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

    tags: Array<SortSearchTag> = []
    paramLabels = {
        [CampEventSortKey.NAME]: "Jméno",
        [CampEventSortKey.START]: "Začátek",
        [CampEventSortKey.END]: "Konec",
        [CampEventSortKey.UNIT]: "Pořádající jednotka",
        [CampEventSortKey.REGISTRATION_NUMBER]: "Evidenční číslo",
        [CampEventSortKey.STATE]: 'Stav',
        [SortDirection.ASC]: 'Vzestupně',
        [SortDirection.DESC]: 'Sestupně',
        [ScheduleType.FUTURE]: 'Teprve proběhne',
        [ScheduleType.PAST]: 'Již proběhla',
        [EventRel.ME_AND_MY_UNIT]: 'Týkající se mě a mého střediska',
        [EventRel.UNIT_PLACE]: 'Střediska přímo podřízené mé jednotce',
        [EventRel.ALL_UNIT_PLACE]: 'Všechna střediska pod mou jednotkou ',
    }

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

    refreshEvents() {
        this.eventList = [];
        this.store.dispatch(new LoadCampEvents())
            .pipe(withLatestFrom(this.eventList$, this.sortParams$, this.searchParams$, this.eventStates$))
            .subscribe(([_, evs, sortParams, searchParams, states]) => {
                this.searchParams = searchParams;
                this.eventList = sortCampEvents(evs, sortParams);
                const { year, state, relation, schedule, name, registrationNumber, location } = this.searchParams

                this.tags = [
                    { text: `Seřaděno dle: ${this.paramLabels[sortParams.sortByKey]}`, modalType: ModalType.Sort },
                    { text: `Směr: ${this.paramLabels[sortParams.sortDirection]}`, modalType: ModalType.Sort },
                    name && { text: `Název: ${name}`, modalType: ModalType.Search },
                    location && { text: `Místo konání: ${location}`, modalType: ModalType.Search },
                    registrationNumber && { text: `Evidenční číslo: ${registrationNumber}`, modalType: ModalType.Search },
                    year && schedule == ScheduleType.YEAR && { text: `Rok: ${year}`, modalType: ModalType.Search },
                    state && { text: `Stav: ${states.find(t => t.ID === state).DisplayName}`, modalType: ModalType.Search },
                    schedule && schedule !== ScheduleType.YEAR && { text: `Termín: ${this.paramLabels[schedule]}`, modalType: ModalType.Search },
                    relation && { text: `Vztah k akci: ${this.paramLabels[relation]}`, modalType: ModalType.Search },
                ].filter(s => s)
            })
    }

    ngOnInit(): void {
        this.router.events.subscribe((val) => {
            if (val instanceof NavigationEnd) {
                if (this.router.url === '/event/camp') {
                    this.pageLoading = false;
                }
            }
        });
        this.route.queryParams.subscribe(res => {
            if (res && res.eventId) {
                setTimeout(() => {
                    this.routerExtensions.navigate(['event/campDetail',
                        res.eventId], { transition: transitionOptions });
                }, 10);
            }
        })
        this.store.dispatch([new LoadCampEventStates()])
            .pipe(withLatestFrom(this.eventStates$))
            .subscribe(([_, states]) => {
                this.states = states;
            })
        this.refreshEvents();
    }

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

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

    openSortingModal() {
        this._sortParams = this.store.selectSnapshot(CampEventSearchListState.getSortParams)
        const options: ModalDialogOptions = {
            viewContainerRef: this._vcRef,
            context: { sortParams: this._sortParams, formattedSortByKeys: formattedCampEventSortKeys },
            fullscreen: false,
        };
        this._modalService.showModal(SortModalComponent, options)
            .then((formResult: SortParams) => {
                if (formResult) {
                    this.store.dispatch(new SetCampEventSortParams(formResult))
                        .pipe(withLatestFrom(this.eventList$, this.sortParams$))
                        .subscribe(([_, events, sortParams]) => {
                            this._sortParams = sortParams
                            this.tags = [
                                { text: `Seřaděno dle: ${this.paramLabels[sortParams.sortByKey]}`, modalType: ModalType.Sort },
                                { text: `Směr: ${this.paramLabels[sortParams.sortDirection]}`, modalType: ModalType.Sort },
                                , ...this.tags.filter(t => t.modalType === ModalType.Search)]
                            this.eventList = sortCampEvents(events, sortParams);
                        })
                }
            });
    }

    openSearchModal() {
        this.searchParams = this.store.selectSnapshot(CampEventSearchListState.getSearchParams)
        const { searchParams, states } = this;
        const options: ModalDialogOptions = {
            viewContainerRef: this._vcRef,
            context: { searchParams, states },
            fullscreen: false,
        };

        this._modalService.showModal(CampEventSearchModalComponent, options)
            .then((formResult: CampEventSearch) => {
                if (formResult) {
                    this.store.dispatch(new SetCampEventSearchParams(formResult))
                        .subscribe((_) => {
                            this.refreshEvents();
                        })
                }
            });
    }

    openMapModal() {
        const camps = this.store.selectSnapshot(CampEventSearchListState.getEvents)
        const options: ModalDialogOptions = {
            viewContainerRef: this._vcRef,
            context: { camps },
            fullscreen: true,
        };
        this._modalService.showModal(CampMapModal, options)
            .then(() => {
                console.log('map closed')
            });
    }

    onUpdateEvent(eventId: number) {
        this.pageLoading = true;
        setTimeout(() => {
            this.routerExtensions.navigate(['event/campUpdate/', eventId],
                { transition: transitionOptions });
        }, 10);
    }

    onAction(action: ActionBarAction) {
        if (action.type === "sort") {
            this.openSortingModal();
        } else if (action.type === "search") {
            this.openSearchModal();
        } else if (action.type === "openMap") {
            this.openMapModal();
        } else if (action.type === "new") {
            this.pageLoading = true;
            setTimeout(() => {
                this.routerExtensions.navigate(['event/campNew',],
                    { transition: transitionOptions });
            }, 10);
        }
    }

}
