import { Component, OnInit, ViewContainerRef } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { ModalDialogService, PageRoute, RouterExtensions } from '@nativescript/angular';
import { Actions, ofActionSuccessful, Select, Store } from '@ngxs/store';
import { Feedback, FeedbackType } from 'nativescript-feedback';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { transitionOptions } from '~/constants/shared.constants';
import { StsDetailUpdateFupModalComponent } from '~/pages/sts/components/sts-detail-update-fup-modal/sts-detail-update-fup-modal.component';
import { EnrollNumberAllPersonOutput } from '~/pages/sts/entities/output/enrollNumberAllPersonOutput';
import { EnrollNumberDetailOutput } from '~/pages/sts/entities/output/enrollNumberDetailOutput';
import { FupTypeAllOutput } from '~/pages/sts/entities/output/fupTypeAllOutput';
import { TariffDetailOutput } from '~/pages/sts/entities/output/tariffDetailOutput';
import { TariffNumberService } from '~/pages/sts/entities/tariff-number-service';
import { CreateEnrollNumberUpdateFup, LoadEnrollNumber, LoadFupTypes } from '~/pages/sts/state-mgmt/sts-detail.actions';
import { StsDetailState } from '~/pages/sts/state-mgmt/sts-detail.state';

@Component({
    selector: 'StsDetail',
    moduleId: module.id,
    templateUrl: './sts-detail.component.html',
    styleUrls: ['./_sts-detail.component.scss']
})
export class StsDetailComponent implements OnInit {
    @Select(StsDetailState.getEnrollNumber) stsNumber$: Observable<EnrollNumberAllPersonOutput>;
    @Select(StsDetailState.getEnrollNumberDetail) stsNumberDetail$: Observable<EnrollNumberDetailOutput>;
    @Select(StsDetailState.getTariffDetail) tariffDetail$: Observable<TariffDetailOutput>;
    @Select(StsDetailState.getTariffServicesWithNumberServices) tariffServices$: Observable<TariffNumberService[]>;
    @Select(StsDetailState.getFupTypes) fupTypes$: Observable<FupTypeAllOutput[]>;
    @Select(StsDetailState.isLoading) isLoading$: Observable<boolean>;
    phoneNumber: string;
    stsNumberDetail: EnrollNumberDetailOutput;
    fupTypes: FupTypeAllOutput[];
    feedback: Feedback;
    othersIsLoading: boolean;

    constructor(
        private router: Router,
        private routerExtensions: RouterExtensions,
        private pageRoute: PageRoute,
        private modalDialogSrv: ModalDialogService,
        private vcRef: ViewContainerRef,
        private store: Store,
        private actions$: Actions
    ) {
        this.feedback = new Feedback();
        this.router.events.subscribe((val) => {
            if (val instanceof NavigationEnd) {
                if (RegExp('\/sts\/detail\/[0-9]+').test(this.router.url)) {
                    this.othersIsLoading = false;
                }
            }
        });
    }

    /**
     * In OnInit hook It take number from params and dispatch action for Load enrollNumber and fup types.
     * It add action handler to Succeess action CreateEnrollNumberUpdateFup which is called when update FUP was successful -> show feedback
     *
     * @returns {Promise<void>}
     */
    async ngOnInit() {
        this.othersIsLoading = false;
        this.pageRoute.activatedRoute
            .pipe(
                switchMap(activatedRoute => activatedRoute.params)
            )
            .forEach(params => {
                this.phoneNumber = params['number'];

                if (this.phoneNumber) {
                    this.store.dispatch(new LoadEnrollNumber(this.phoneNumber));
                    this.store.dispatch(new LoadFupTypes());
                }
            });

        this.stsNumberDetail$.subscribe((stsNumberDetail: EnrollNumberDetailOutput) => {
            this.stsNumberDetail = stsNumberDetail;
        });

        this.fupTypes$.subscribe((fupTypes: FupTypeAllOutput[]) => {
            this.fupTypes = fupTypes;
        });

        this.actions$.pipe(ofActionSuccessful(CreateEnrollNumberUpdateFup)).subscribe(() => {
            this.feedback.show({
                title: 'SUCCESS',
                type: FeedbackType.Success,
                message: 'Požadavek o navýšení FUP byl úspěšně odeslán.'
            });
        });
    }

    onNav(route: string) {
        this.othersIsLoading = true;
        setTimeout(() => {
            this.routerExtensions.navigate([route, this.phoneNumber], { transition: transitionOptions });
        }, 10);
    }

    /**
     * Callback called when user clik on button for update FUP.
     * It subscribe data from fupTypes$, prepare it for dialod and show modal dialog for choose of how much fup should be increase
     */
    showModalUpdateFUP() {
        const options = {
            context: {fupTypes: this.fupTypes, wasUpdated: !this.isBeforeDay(this.stsNumberDetail.DateFup)},
            fullscreen: false,
            viewContainerRef: this.vcRef
        };
        this.modalDialogSrv.showModal(StsDetailUpdateFupModalComponent, options).then(fupType => {
            if (fupType) {
                this.store.dispatch(new CreateEnrollNumberUpdateFup(this.stsNumberDetail.ID, fupType.ID));
            }
        });
    }

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

    get fupIcon() {
        return String.fromCharCode(0xf161);
    }

    get billIcon() {
        return String.fromCharCode(0xf53a);
    }

    get statsIcon() {
        return String.fromCharCode(0xf080);
    }

    /**
     * It return boolean if last update was before 24 hours, if lastUpdate is not set return it true (like it was before day)
     * @param {string} lastUpdate in format forexample: 2018-10-24T14:15:29.787
     * @return boolean
     */
    private isBeforeDay(lastUpdate: string) {
        const [date, time] = lastUpdate.split('T');
        if ((!date || date.length === 0) && (!time || time.length === 0)) {
            return true;
        }

        const [year, month, day] = date.split('-');
        const [hours, minutes, seconds] = time.substring(0, time.indexOf('.')).split(':');
        const today = new Date();
        const lastUpdateDate = new Date(+year, +month - 1, +day, +hours, +minutes, +seconds);

        return Math.round((lastUpdateDate.getTime() - today.getTime()) / (24 * 60 * 60 * 1000)) > 1;
    }
}
