import { Component, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Select, Store } from '@ngxs/store';
import { ModalDialogOptions, ModalDialogService, RouterExtensions } from '@nativescript/angular';
import { withLatestFrom } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { ActionsExecuting, actionsExecuting } from '@ngxs-labs/actions-executing';
import { CampEventDetailState } from '~/pages/event/state-mgmt/camp/camp-event-detail.state';
import { CampEventDetailOutput } from '~/pages/event/entities/camp-event-detail.types';
import { LoadCampEventDetail } from '~/pages/event/state-mgmt/camp/camp-event-detail.actions';
import { CampEventParticipantState } from '../../../state-mgmt/camp/camp-event-participant.state';
import { CampEventMultiPersonOutput } from '~/pages/event/entities/camp-event-participant.types';
import { CampParticipantSearchPerson, InsertMultiCampEventParticipant, LoadCampEventPersonMulti } from '~/pages/event/state-mgmt/camp/camp-event-participant.actions';
import { ListViewEventData } from 'nativescript-ui-listview';
import { RadListViewComponent } from 'nativescript-ui-listview/angular';
import { transitionOptions } from '~/constants/shared.constants';
import { SortParams, SortDirection, formattedCampMultiPersonAddSortKeys, CampMultiPersonAddSortKey } from '~/pages/event/types/EventSorting';
import { SortModalComponent } from '~/pages/event/components/common/sort-modal/sort-modal.component';
import { sortItems } from '~/pages/event/util';
import { isAndroid } from 'nativescript-platform';
import { arrowUp, sortIcon } from '~/constants/icons';

interface ListType extends CampEventMultiPersonOutput {
    selected: boolean;
}

@Component({
    selector: 'CampEventParticipantMutliAddPage',
    moduleId: module.id,
    templateUrl: './camp-event-participant-multiadd-page.component.html',
    styleUrls: ['./_camp-event-participant-multiadd-page.component.scss']

})
export class CampEventParticipantMutliAddPage implements OnInit {
    @Select(actionsExecuting([
        LoadCampEventDetail,
        CampParticipantSearchPerson,
        InsertMultiCampEventParticipant,
    ]))
    isLoading$: Observable<ActionsExecuting>;

    @Select(CampEventDetailState.getEventDetail)
    eventDetail$: Observable<CampEventDetailOutput>;
    @Select(CampEventParticipantState.getMultiPersonList)
    personList$: Observable<CampEventMultiPersonOutput[]>
    sortParams: SortParams = { sortByKey: 'DisplayName', sortDirection: SortDirection.ASC };

    isSelectedAll = false;
    @ViewChild("listView", { static: false })
    listView: RadListViewComponent;
    eventId: number;
    personList: ListType[] = [];
    newParticipants = new Set();
    scrollButton = false;
    sortIcon = sortIcon;
    arrowUp = arrowUp;

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

    ngOnInit(): void {
        this.route.params.subscribe(params => {
            this.eventId = parseInt(params['id'], 10);
            this.refreshData();
        })
    }

    refreshData() {
        this.store.dispatch([
            new LoadCampEventDetail(this.eventId),
            new LoadCampEventPersonMulti(this.eventId)
        ]).pipe(withLatestFrom(this.personList$)).subscribe(([_, people]) => {
            this.personList = this.sortPeople(people, this.sortParams)
                .map(p => ({ ...p, selected: false }));
        })
    }

    sortPeople(ppl, sortParams: SortParams) {
        return sortItems(ppl, sortParams, sortParams.sortByKey === CampMultiPersonAddSortKey.BIRTHDAY);
    }
    onItemTap(event: ListViewEventData) {
        const listView = event.object,
            rowIndex = event.index,
            dataItem = event.view.bindingContext as ListType;
        if (dataItem.IsParticipant) {
            return;
        }
        dataItem.selected = !dataItem.selected;
        const { ID, ID_Unit } = dataItem;

        if (this.newParticipants.has(ID + '-' + ID_Unit)) {
            this.newParticipants.delete(ID + '-' + ID_Unit)
        } else {
            this.newParticipants.add(ID + '-' + ID_Unit)
        }

        if (isAndroid) {
            listView.androidListView.getAdapter().notifyItemChanged(rowIndex);
        }
    }
    templateSelector = (item: ListType, index: number, items: any): string => {
        this.scrollButton = index > 8;
        if (item.IsParticipant) return 'selected';
        if (item.selected) return 'new-selected';
    }

    submit() {
        // removing duplicates
        const peopleList = Array.from(new Set(Array.from(this.newParticipants)
            .map((i: string) => parseInt(i.split('-')[0]))))
        this.store.dispatch(new InsertMultiCampEventParticipant(
            peopleList,
            this.eventId)).subscribe(res => {
                setTimeout(() => {
                    this.routerExtensions.navigate(['/event/campDetail/', this.eventId, 2],
                        { transition: transitionOptions });
                }, 1000);
            }, () => {
                this.refreshData();
                this.selectAll();
            }
            )
    }
    goToTop() {
        this.listView.listView.scrollToIndex(0, true)
        this.scrollButton = false;
    }

    selectAll() {
        if (this.isSelectedAll) {
            this.newParticipants = new Set();
        } else {
            this.personList.forEach(p => {
                if (!p.IsParticipant) {
                    this.newParticipants.add(p.ID + '-' + p.ID_Unit);
                }
            })
        }
        this.isSelectedAll = !this.isSelectedAll;
    }
    openSortModal() {
        const options: ModalDialogOptions = {
            viewContainerRef: this._vcRef,
            context: { sortParams: this.sortParams, formattedSortByKeys: formattedCampMultiPersonAddSortKeys },
            fullscreen: false,
        };
        this._modalService.showModal(SortModalComponent, options)
            .then((formResult: SortParams) => {
                if (formResult) {
                    this.sortParams = formResult;
                    this.personList = this.sortPeople(this.personList, formResult);
                }
            });
    }

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

}
