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 { openUrl } from "@nativescript/core/utils/utils";
import { withLatestFrom } from 'rxjs/operators';
import { transitionOptions } from '~/constants/shared.constants';
import EduEventSearch, { EduEventSortFilter, EduEventSortFilterFormData } from '~/pages/event/types/EduEventSearch';
import { EduEventOutput, EduEventType, EduEventGroup } from '~/pages/event/entities/edu-event-search.types';
import { LoadEduEvents, LoadEduEventTypes, SetEduEventSortFilterParams, LoadEduEventGroups, SetEduEventSearchParams } 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 { SortDirection, EduEventSortKey } from '~/pages/event/types/EventSorting';
import { formattedEduEventSortKeys } from '../../../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 { EduEventSearchModalComponent, EduEventSearchResult } from '~/pages/event/components/edu/edu-event-search-modal/edu-event-search-modal.component';
import { SKAUTIS_EDU_EVENT_ENROLL_URL, sortFilterEduEvents } from '~/pages/event/util/event';
import { sortIcon, searchIcon } from '~/constants/icons';


@Component({
    selector: 'EduEventSearchList',
    moduleId: module.id,
    templateUrl: './edu-event-list-page.component.html',
})
export class EduEventListPageComponent implements OnInit {
    @Select(actionsExecuting([LoadEduEvents]))
    isLoading$: Observable<ActionsExecuting>;
    @Select(EduEventSearchListState.getEvents)
    eventList$: Observable<EduEventOutput[]>;
    @Select(EduEventSearchListState.getEventSearchParams)
    searchParams$: Observable<EduEventSearch>;
    @Select(EduEventSearchListState.getSortFilterParams)
    sortFilterParams$: Observable<EduEventSortFilter>;
    @Select(EduEventSearchListState.getEventTypes)
    eventTypes$: Observable<EduEventType[]>
    @Select(EduEventSearchListState.getEventGroups)
    eventGroups$: Observable<EduEventGroup[]>

    searchParams: EduEventSearch;
    eventList: EduEventOutput[];
    sortFilterParams: EduEventSortFilter;
    @Select(EduEventSearchListState.isSearchSortDirty)
    isSearchSortDirty$: Observable<boolean>;

    types: EduEventType[];
    groups: EduEventGroup[];

    topBarHeight = TOP_ACTION_BAR_HEIGHT;

    tags: SortSearchTag[] = [];
    sortDirections = {
        [SortDirection.ASC]: 'Vzestupně',
        [SortDirection.DESC]: 'Sestupně'
    }
    sortBy = {
        [EduEventSortKey.NAME]: 'Dle jména',
        [EduEventSortKey.REGISTRATION]: 'Dle přihlašování',
        [EduEventSortKey.START]: 'Dle začátku kurzu',
    }
    paramLabels = {
        [EduEventSortKey.NAME]: "Jméno",
        [EduEventSortKey.START]: "Začátek",
        [EduEventSortKey.TYPE]: 'Typ',
        [EduEventSortKey.CAPACITY]: 'Kapacita',
        [EduEventSortKey.REGISTRATION]: 'Uzávěrka přihlášek',
        [SortDirection.ASC]: 'Vzestupně',
        [SortDirection.DESC]: 'Sestupně',
    }

    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(EduEventSearchListState.getEventSearchParams);
        this.sortFilterParams = this.store.selectSnapshot(EduEventSearchListState.getSortFilterParams);
        const { type, year, eventName, group } = this.searchParams
        const qual = this.sortFilterParams.onlyQualification
        this.tags = [
            { text: `Seřaděno dle: ${this.paramLabels[this.sortFilterParams.sortByKey]}`, modalType: ModalType.Sort },
            { text: `Směr: ${this.paramLabels[this.sortFilterParams.sortDirection]}`, modalType: ModalType.Sort },
            year && { text: `Rok: ${year}`, modalType: ModalType.Search },
            type && { text: `Typ: ${type.displayName}`, modalType: ModalType.Search },
            group && { text: `Skupina: ${group.displayName}`, modalType: ModalType.Search },
            eventName && { text: `Název akce: ${eventName}`, modalType: ModalType.Search },
            { text: `Pouze s kvalifikací: ${qual ? 'ano' : 'ne'}`, modalType: ModalType.Search },
        ].filter(s => s);

    }

    refreshEvents() {
        this.eventList = []
        this.refreshTags()

        this.store.dispatch(new LoadEduEvents())
            .pipe(withLatestFrom(this.eventList$, this.eventTypes$))
            .subscribe(([_, evs, types]) => {
                if (evs.length === 0) {
                    this.eventList = []
                }
                this.eventList = sortFilterEduEvents(evs, this.sortFilterParams, types);
            })
    }

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

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

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

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

        this._modalService.showModal(EduEventSearchModalComponent, options)
            .then((formResult: EduEventSearchResult) => {
                if (formResult) {
                    this.store.dispatch([
                        new SetEduEventSortFilterParams({
                            ...this.sortFilterParams,
                            onlyQualification: formResult.onlyQualification
                        }),
                        new SetEduEventSearchParams(formResult.eventSearch)
                    ]).pipe(withLatestFrom(this.searchParams$,
                        this.sortFilterParams$, this.eventList$))
                        .subscribe(([_, search, sort, events]) => {
                            if (!isEqualJson(search, searchParams)) {
                                this.refreshEvents();
                            } else if (!isEqualJson(sort, sortFilterParams)) {
                                this.eventList = sortFilterEduEvents(events, sort, types)
                                this.refreshTags()
                            }
                        })
                }

            });
    }

    openSortingModal() {
        this.sortFilterParams = this.store.selectSnapshot(EduEventSearchListState.getSortFilterParams)

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

        this._modalService.showModal(SortModalComponent, options)
            .then((formResult: EduEventSortFilterFormData) => {
                if (formResult) {
                    this.sortFilterParams = {
                        ...formResult,
                        onlyQualification: this.sortFilterParams.onlyQualification
                    };
                    this.store.dispatch(new SetEduEventSortFilterParams(this.sortFilterParams))
                        .pipe(withLatestFrom(this.eventList$, this.eventTypes$,
                            this.sortFilterParams$))
                        .subscribe(([_, events, types, sortParams]) => {
                            const sorted = sortFilterEduEvents(events, sortParams, types)
                            this.eventList = sorted;
                            this.refreshTags()
                        })
                }
            });
    }

    onEnrollEvent(event: EduEventOutput) {
        const skuatIsUrl = `${SKAUTIS_EDU_EVENT_ENROLL_URL}?ID_EventEducationCourse=${event.ID_EventEducationCourse}&ID_EventEducation=${event.ID}`;
        let url = event.LoginSkautis ? skuatIsUrl : event.LoginLocation;
        if (!url.startsWith('http://') && !url.startsWith('https://')) {
            url = 'http://' + url
        }
        openUrl(url)
    }

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

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

}

