import { Component, OnInit } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { PageRoute, RouterExtensions } from '@nativescript/angular';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { transitionOptions } from '~/constants/shared.constants';
import { MEMBERSHIP_CATEGORY_AGES } from '~/constants/unit.constants';
import { PickerProvider } from '~/core/entities/picker-provider';
import { MembershipAllOutput } from '~/pages/unit/entities/output/membershipAllOutput';
import { LoadUnitMemberships } from '~/pages/unit/state-mgmt/unit-memberships.actions';
import { UnitMembershipsState } from '~/pages/unit/state-mgmt/unit-memberships.state';
import { Item } from '~/shared/components/item-picker/item';

@Component({
    selector: 'UnitMembers',
    moduleId: module.id,
    templateUrl: './unit-members.component.html',
    styleUrls: ['./_unit-members.component.scss']
})
export class UnitMembersComponent implements OnInit {
    @Select(UnitMembershipsState.getUnitMemberships) unitMemberships$: Observable<MembershipAllOutput[]>;
    @Select(UnitMembershipsState.isLoading) isLoading$: Observable<boolean>;
    unitId: number;
    origUnitMemberships: MembershipAllOutput[];
    unitMemberships: MembershipAllOutput[];
    unitsProvider: PickerProvider[];
    categoriesProvider: PickerProvider[];
    unit: Item;
    category: Item;
    othersIsLoading: boolean;

    constructor(
        private router: Router,
        private routerExtensions: RouterExtensions,
        private pageRoute: PageRoute,
        private store: Store
    ) {
        this.router.events.subscribe((val) => {
            if (val instanceof NavigationEnd) {
                if (RegExp('\/unit\/members\/[0-9]+').test(this.router.url)) {
                    this.othersIsLoading = false;
                }
            }
        });
    }

    /**
     * In hook I dispatch action for loading data using unitId from params.
     * It subscribe data too. In subsribing data, it retrive data from response
     * and modify them for Picker of categories and units which are contained in response.
     *
     */
    ngOnInit(): void {
        this.othersIsLoading = false;
        this.pageRoute.activatedRoute
            .pipe(
                switchMap(activatedRoute => activatedRoute.params)
            )
            .forEach((params) => {
                this.unitId = +params['unitId'];

                if (this.unitId) {
                    this.store.dispatch(new LoadUnitMemberships(this.unitId));
                }
            });

        this.unitMemberships$.subscribe((members: MembershipAllOutput[]) => {
            this.origUnitMemberships = members;
            this.unitMemberships = members;

            const tmpUnits = members
                .filter((member: MembershipAllOutput, index, self) =>
                    index === self.findIndex((t) => (t.ID_Unit === member.ID_Unit))
                )
                .map((member: MembershipAllOutput) => new PickerProvider(member.ID_Unit, member.Unit))
                .sort((mA, mB) => mA.label.localeCompare(mB.label));
            this.unitsProvider = [new PickerProvider(0, 'Všechny'), ...tmpUnits];

            const tmpCategories = members
                .filter((member: MembershipAllOutput, index, self) =>
                    index === self.findIndex((t) => (t.ID_MembershipCategory === member.ID_MembershipCategory))
                )
                .map((member: MembershipAllOutput) => new PickerProvider(member.ID_MembershipCategory, `${member.MembershipCategory} ${MEMBERSHIP_CATEGORY_AGES[member.ID_MembershipCategory]}`))
                .sort((mA, mB) => {
                    const regex = /\d+/g;
                    const mANumS = mA.label.match(regex);
                    const mBNumS = mB.label.match(regex);
                    if (!mANumS || mANumS.length === 0) {
                        return 0;
                    }
                    if (!mBNumS || mBNumS.length === 0) {
                        return 0;
                    }
                    const mANumber = parseInt(mANumS[0], 10);
                    const mBNumber = parseInt(mBNumS[0], 10);

                    return mANumber > mBNumber ? 1 : mANumber < mBNumber ? -1 : 0;
                });
            this.categoriesProvider = [new PickerProvider('not', 'Všechny'), ...tmpCategories];
        });
    }

    /**
     * Callback called if unit from picker was select / change,
     * then set property and filter unitMembership for show
     *
     * @param {number|string} unitId
     */
    onSelectedUnit(unitId: number | string) {
        if (!this.unit || this.unit.id !== unitId) {
            this.unit = new Item(unitId);
            this.filterUnitMemberShips();
        }
    }

    /**
     * Callback called if category from picker was select / change,
     * then set property and dispatch action for load category info
     *
     * @param {number|string} categoryId
     */
    onSelectedCategory(categoryId: number | string) {
        if (!this.category || this.category.id !== categoryId) {
            this.category = new Item(categoryId);
            this.filterUnitMemberShips();
        }
    }

    onItemTap(personId: number) {
        this.othersIsLoading = true;
        setTimeout(() => {
            this.routerExtensions.navigate(['search/list', personId, false], { transition: transitionOptions });
        }, 10);
    }

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

    private filterUnitMemberShips() {
        this.unitMemberships = this.origUnitMemberships
            .filter((member: MembershipAllOutput) => {
                if ((this.unit.id !== 0) && (this.unit.id !== member.ID_Unit)) {
                    return false;
                }

                return !((this.category.id !== 'not') && (this.category.id !== member.ID_MembershipCategory));
            });
    }
}
