import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { actionsExecuting, ActionsExecuting } from '@ngxs-labs/actions-executing';
import { Select, Store } from '@ngxs/store';
import { RouterExtensions } from '@nativescript/angular';
import { combineLatest, Observable } from 'rxjs';
import { Person } from '~/pages/event/types/common.types';
import { EduEventLeaderDetailOutput, EduEventInstructorsOutput, EduEventAssistantOutput } from '~/pages/event/entities/edu-event-people.types';
import { LoadEventLeaderDetail, LoadEventAssistantDetail, LoadEventInstructors } from '~/pages/event/state-mgmt/edu/edu-event-people.actions';
import { EduEventPeopleDetailState } from '~/pages/event/state-mgmt/edu/edu-event-people.state';
import { map, withLatestFrom } from 'rxjs/operators';
import { EduEventDetailState } from '~/pages/event/state-mgmt/edu/edu-event-detail.state';
import { EduEventDetailOutput, EduEventCourseOutput, EduEventLocationDetailOutput } from '~/pages/event/entities/edu-event-detail.types';
import { EduEventCoursesTermsOutput } from './../../../entities/edu-event-detail.types';
import { LoadEduEventDetail, LoadEduEventCourses, LoadEduEventCoursesTerms, LoadEduEventCoursesTermsLocations } from '~/pages/event/state-mgmt/edu/edu-event-detail.action';
import { EduEventOtherDetailOutput, EduEventIllustrativePhotoOutput } from '~/pages/event/entities/edu-event-other-detail.types';
import { EduEventOtherDetailState } from '~/pages/event/state-mgmt/edu/edu-event-other-detail.state';
import { LoadEventOtherDetail, LoadEventOtherDetailPhotos } from '~/pages/event/state-mgmt/edu/edu-event-other-detail.actions';
import { EduEventOutput } from '~/pages/event/entities/edu-event-search.types';
import { EduEventSearchListState } from '~/pages/event/state-mgmt/edu/edu-event-search-list.state';
import { LoadEduEvents } from '~/pages/event/state-mgmt/edu/edu-event-search.actions';
import { transitionOptions } from '~/constants/shared.constants';
import { editIcon } from '~/constants/icons';
import canEditEvent from './../../../util/authorization';
import { groupByPersonId, mergePersonMap } from '~/pages/event/util';

@Component({
    selector: 'EduEventDetailPage',
    moduleId: module.id,
    templateUrl: './edu-event-detail-page.component.html',
})
export class EduEventDetailPageComponent implements OnInit {

    @Select(EduEventDetailState.getEventDetail)
    eventDetail$: Observable<EduEventDetailOutput>;
    @Select(EduEventSearchListState.getEvents)
    eventList$: Observable<EduEventOutput[]>;
    @Select(EduEventPeopleDetailState.getEventLeaderDetail)
    eventLeaders$: Observable<EduEventLeaderDetailOutput[]>;
    @Select(EduEventPeopleDetailState.getEventInstructors)
    eventInstructors$: Observable<EduEventInstructorsOutput[]>;
    @Select(EduEventPeopleDetailState.getEventAssistantsDetail)
    eventAssistants$: Observable<EduEventAssistantOutput[]>;
    @Select(EduEventDetailState.getEventCourses)
    eventCourses$: Observable<EduEventCourseOutput[]>;
    @Select(EduEventDetailState.getEventCoursesTerms)
    eventCoursesTerms$: Observable<EduEventCoursesTermsOutput[]>;
    @Select(EduEventDetailState.getEventTermsLocationDetails)
    termsLocationDetails$: Observable<EduEventLocationDetailOutput[]>;

    @Select(EduEventOtherDetailState.getEventOtherDetail)
    eventOtherDetail$: Observable<EduEventOtherDetailOutput>;
    @Select(EduEventOtherDetailState.getEventOtherDetailPhotos)
    illustrativePhotos$: Observable<EduEventIllustrativePhotoOutput[]>;
    @Select(EduEventDetailState.getEventCourses)
    courses$: Observable<EduEventCourseOutput[]>;

    @Select(actionsExecuting([
        LoadEventLeaderDetail, LoadEventAssistantDetail,
        LoadEventInstructors, LoadEduEventDetail, LoadEduEvents,
        LoadEduEventCourses, LoadEduEventCoursesTerms,
        LoadEventOtherDetail, LoadEventOtherDetailPhotos,
        LoadEduEventCoursesTermsLocations,
    ]))
    isLoading$: Observable<ActionsExecuting>;
    selectedIndex = 0;
    eventId: number;
    eventListData: EduEventOutput;
    isEditable: boolean = false;
    team$: Observable<Person[]>;

    constructor(
        private routerExtensions: RouterExtensions,
        private route: ActivatedRoute,
        private store: Store,
    ) {
    }
    ngOnInit(): void {
        this.route.params.subscribe(params => {
            this.eventId = parseInt(params['id'], 10);
            this.selectedIndex = parseInt(params['section'], 10) || 0;
            this.eventDetail$.subscribe(res => {
                this.isEditable = res && canEditEvent(res.ID_Unit)
            })
        })

        this.team$ = combineLatest([this.eventLeaders$, this.eventAssistants$, this.eventInstructors$])
            .pipe(map(
                ([leaders, assistants, instructors]) => {
                    const leadersList = this.mapFunctions(leaders).filter(l => l.id);

                    const assistantList = this.mapFunctions(assistants)
                    const instructorList: Person[] = instructors.map(i => ({
                        id: i.ID_Person, name: i.Person,
                        roles: [i.InstructorType], otherInfo: '',
                        extendedInfo: [
                            { title: 'Skautská praxe', value: i.ScoutExperience },
                            { title: 'Zaměření instruktora', value: i.EventFocus },
                            { title: 'Profesní zkušenosti', value: i.ProfessionalExperience },
                        ].filter(info => info.value.length > 0)
                    }))

                    const groups = groupByPersonId([...leadersList, ...assistantList, ...instructorList])

                    return mergePersonMap(groups)
                        .map(p => ({
                            ...p, roles: [],
                            otherInfo: p.roles.join(', ')
                        }));
                }));
    }

    refreshBaseDetail() {
        this.store.dispatch([
            new LoadEduEventDetail(this.eventId),
            new LoadEduEventCourses(this.eventId, this.eventId),
            new LoadEduEventCoursesTerms(this.eventId, this.eventId),
        ]).pipe(withLatestFrom(this.eventCoursesTerms$, this.eventDetail$)).subscribe(([_, terms, event]) => {
            if (!this.eventListData) {
                const year = new Date(event.StartDate).getFullYear().toString();
                this.store.dispatch(new LoadEduEvents({ year }))
                    .pipe(withLatestFrom(this.eventList$))
                    .subscribe(([_, evs]) => {
                        this.eventListData = evs.find(e => e.ID === this.eventId)
                    })

            }
            this.store.dispatch(new LoadEduEventCoursesTermsLocations(
                terms.map(t => t.ID_EventEducationLocation)
            ))
        });
        const events = this.store.selectSnapshot(EduEventSearchListState.getEvents)
        this.eventListData = events.find(e => e.ID === this.eventId)


    }

    refreshEventStateDetail() {
        this.store.dispatch([new LoadEduEventDetail(this.eventId)])
    }

    refreshTeam() {
        this.store.dispatch([
            new LoadEventLeaderDetail(this.eventId),
            new LoadEventAssistantDetail(this.eventId),
            new LoadEventInstructors(this.eventId)
        ])
    }

    onEditTeam() {
        setTimeout(() => {
            this.routerExtensions.navigate(['/event/educationUpdateFunctions/', this.eventId],
                { transition: transitionOptions });
        }, 10);
    }
    onEditInstructors() {
        setTimeout(() => {
            this.routerExtensions.navigate(['/event/educationInstructors/', this.eventId],
                { transition: transitionOptions });
        }, 10);
    }
    onBackButton(): void {
        this.routerExtensions.back();
    }

    setIndex(i) {
        this.selectedIndex = i.newIndex;
    }
    get editIcon() { return editIcon; }

    private mapFunctions(fns: { ID_Person: any; Person: any; EventFunctionType: any; Note: any; }[]): Person[] {
        return fns.map(({ ID_Person, Person, EventFunctionType, Note }) =>
        ({
            id: ID_Person, name: Person,
            roles: [EventFunctionType], otherInfo: '',
            extendedInfo: Note ? [{ title: EventFunctionType + ' poznámka', value: Note }] : [],
        }))
    }
}
