import { Component, ElementRef, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { ModalDialogOptions, ModalDialogService, RouterExtensions } from '@nativescript/angular';
import { ApplicationSettings, EventData, TextField } from '@nativescript/core';
import { action } from '@nativescript/core/ui/dialogs';
import { Select, Store } from '@ngxs/store';
import { FeedbackType } from 'nativescript-feedback';
import { Observable } from 'rxjs';
import { withLatestFrom } from 'rxjs/operators';
import { USER_PERSON_NAME } from '~/constants/login-constants';
import { ModalDatePickerComponent } from '../../components/modal-view-date-picker/modal-view-date-picker.component';
import { WarehouseAllOutput } from '../../entities/output/warehouseAllOutput';
import { WarehouseItemReservationInsertOutput } from '../../entities/output/warehouseItemReservationInsertOutput';
import { CreateReservationInsert, LoadWarehouseAll } from '../../state-mgmt/reservation-new.action';
import { ReservationNewState } from '../../state-mgmt/reservation-new.state';
import { feedbackMessage } from '../../utils/feedback-messages';
import { czechStringfromDate, dateFromCzechString } from '../../utils/myFunctions';

@Component({
    selector: 'ReservationNew',
    moduleId: module.id,
    templateUrl: './reservation-new.component.html',
    providers: [ModalDialogService],
    styleUrls: ['./reservation-new.component.scss']
})

export class ReservationNewComponent implements OnInit {
    @ViewChild('warehouse', {static: true}) warehouse: ElementRef;
    @ViewChild('dateFrom', {static: true}) dateFrom: ElementRef;
    @ViewChild('dateTo', {static: true}) dateTo: ElementRef;
    @ViewChild('person', {static: true}) person: ElementRef;
    @ViewChild('personTelephone', {static: true}) personTelephone: ElementRef;
    @ViewChild('personEmail', {static: true}) personEmail: ElementRef;

    @Select(ReservationNewState.getReservationInsert) reservation$: Observable<WarehouseItemReservationInsertOutput>;
    @Select(ReservationNewState.getWarehouseAll) warehouses$: Observable<WarehouseAllOutput[]>;
    @Select(ReservationNewState.isLoading) isLoading$: Observable<boolean>;
    reservation: WarehouseItemReservationInsertOutput = null;
    warehouses: WarehouseAllOutput[];

    item: {id: number, name: string, idUnit: number} = null;
    othersIsLoading: boolean;
    constructor(
        private router: Router,
        private route: ActivatedRoute,
        private routerExtensions: RouterExtensions,
        private store: Store,
        private viewContainerRef: ViewContainerRef,
        private modalService: ModalDialogService
    ) {
        this.router.events.subscribe((val) => {
            if (val instanceof NavigationEnd) {
                if (RegExp('\/material\/reservationNew\/[0-9]+\/[^/]+\/[0-9]+').test(this.router.url)) {
                    this.othersIsLoading = false;
                }
            }
        });
    }

    ngOnInit(): void {
        this.item = {
            id: +this.route.snapshot.params['id'],
            name: this.route.snapshot.params['name'],
            idUnit: +this.route.snapshot.params['idUnit']
        };
        this.store.dispatch(new LoadWarehouseAll())
        .pipe(withLatestFrom(this.warehouses$))
        .subscribe(([_, warehouses]) => {
            this.warehouses = warehouses;
            this.warehouse.nativeElement.text = this.warehouses[0].DisplayName;
        }, err => {
            feedbackMessage(FeedbackType.Error, 'Načtení skladů', 'Nepodařilo se načíst sklady.');
            console.log(err);
        });

        this.dateFrom.nativeElement.text = czechStringfromDate(new Date());
        this.dateTo.nativeElement.text = '';
        this.person.nativeElement.text = ApplicationSettings.getString(USER_PERSON_NAME);
    }

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

    onDateFromChange() {
        if (this.dateTo.nativeElement.text !== ''
        && dateFromCzechString(this.dateFrom.nativeElement.text) > dateFromCzechString(this.dateTo.nativeElement.text)) {
            this.dateTo.nativeElement.text = this.dateFrom.nativeElement.text;
        }
    }

    showModal(args: EventData) {
        const txtField = <TextField>args.object;
        const date = txtField.text.split('.');
        // console.log("txtField: " + txtField.text);
        let minDate = new Date();
        if (txtField.id === 'dateTo' &&
            (txtField.text === '' || (txtField.text !== ''
        && dateFromCzechString(this.dateFrom.nativeElement.text) >= dateFromCzechString(this.dateTo.nativeElement.text)))) {
            const d = this.dateFrom.nativeElement.text.split('.');
            minDate = new Date(+d[2].trim(), +d[1].trim() - 1, +d[0].trim());
        }
        const options: ModalDialogOptions = {
            viewContainerRef: this.viewContainerRef,
            context: {
                day: date.length === 3 ? date[0].trim() : new Date().getDate(),
                month: date.length === 3 ? date[1].trim() : new Date().getMonth() + 1,
                year: date.length === 3 ? date[2].trim() : new Date().getFullYear(),
                minDate
            },

            fullscreen: false
        };

        this.modalService.showModal(ModalDatePickerComponent, options)
            .then((result: Date) => {
                if (result) {
                    txtField.text = czechStringfromDate(result);
                }
            });
    }

    onTapWarehouseSelect(args: EventData) {
        const options = {
            message: 'Zvolte sklad',
            cancelButtonText: 'Zrušit',
            actions: this.warehouses.map(obj => obj.DisplayName)
        };

        action(options).then(async (result) => {
            (<TextField>args.object).text = this.warehouses.find(obj => obj.DisplayName === result).DisplayName;
        });
    }

    onConfirm() {
        if (this.warehouse.nativeElement.text === '') {
            feedbackMessage(FeedbackType.Error, 'Rezervace položky', `Vyberte sklad.`);
        } else if (this.person.nativeElement.text === '') {
            feedbackMessage(FeedbackType.Error, 'Rezervace položky', `Vyplňte kontaktní osobu.`);
        } else if (this.personEmail.nativeElement.text !== '' && !RegExp('^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$').test(this.personEmail.nativeElement.text)) {
            feedbackMessage(FeedbackType.Error, 'Rezervace položky', `Email není ve správném formátu.`);
        } else {
            const dateTo = dateFromCzechString(this.dateTo.nativeElement.text);
            this.store.dispatch(new CreateReservationInsert(this.item.id,
                this.warehouses.find(obj => obj.DisplayName === this.warehouse.nativeElement.text).ID,
                this.item.idUnit,
                dateFromCzechString(this.dateFrom.nativeElement.text).toISOString(),
                (dateTo ? dateTo.toISOString() : undefined),
                this.person.nativeElement.text,
                this.personTelephone.nativeElement.text,
                this.personEmail.nativeElement.text))
                    .pipe(withLatestFrom(this.reservation$))
                    .subscribe(
                        ([_, result]) => {
                            const name = this.item.name;
                            feedbackMessage(FeedbackType.Success, 'Rezervace', `Rezervace položky ${name} byla dokončena.`);
                            this.routerExtensions.back();
                        }, err => {
                            console.log(err);
                            feedbackMessage(FeedbackType.Error, 'Rezervace', `Při rezervaci položky ${name} došlo k chybě. Zkuste to prosím později.`);
                        });
        }
    }

    get confirmIcon() {
        return String.fromCharCode(0xf00c);
    }
}
