import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { ModalDialogService, RouterExtensions } from '@nativescript/angular';
import { Page, SearchBar } from '@nativescript/core';
import { Select, Store } from '@ngxs/store';
import { FeedbackType } from 'nativescript-feedback';
import { isAndroid } from 'nativescript-platform';
import { Observable } from 'rxjs';
import { withLatestFrom } from 'rxjs/operators';
import { transitionOptions } from '~/constants/shared.constants';
import { dismissSoftKeybaord } from '~/core/utils/dismiss-keyboard';
import { latinise } from '~/core/utils/functions';
import { WarehouseAllOutput } from '../../entities/output/warehouseAllOutput';
import { WarehouseItemAllBorrowableOutput } from '../../entities/output/warehouseItemAllBorrowableOutput';
import { WarehouseItemReservationInsertOutput } from '../../entities/output/warehouseItemReservationInsertOutput';
import { LoadBorrowableItems, LoadWarehouseAll } from '../../state-mgmt/reservation.action';
import { ReservationState } from '../../state-mgmt/reservation.state';
import { feedbackMessage } from '../../utils/feedback-messages';

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

export class ReservationComponent implements OnInit {
    @ViewChild('city', {static: true}) city: ElementRef;
    @ViewChild('maxPrice', {static: true}) maxPrice: ElementRef;
    @Select(ReservationState.getWarehouseBorrowableItems) borrowableItems$: Observable<WarehouseItemAllBorrowableOutput[]>;
    @Select(ReservationState.getWarehouseAll) warehouses$: Observable<WarehouseAllOutput[]>;
    @Select(ReservationState.isLoading) isLoading$: Observable<boolean>;
    reservation: WarehouseItemReservationInsertOutput = null;
    borrowableItems: WarehouseItemAllBorrowableOutput[];
    warehouses: WarehouseAllOutput[];
    othersIsLoading: boolean;
    itemsHolder: WarehouseItemAllBorrowableOutput[];
    filterExpanded: boolean;

    constructor(
        private router: Router,
        private routerExtensions: RouterExtensions,
        private store: Store,
        private page: Page
    ) {
        this.router.events.subscribe((val) => {
            if (val instanceof NavigationEnd) {
                if (this.router.url === '/material/reservation') {
                    this.othersIsLoading = false;
                }
            }
        });
     }

    ngOnInit(): void {

        this.othersIsLoading = false;
        this.filterExpanded = false;
        this.store.dispatch(new LoadBorrowableItems())
            .pipe(withLatestFrom(this.borrowableItems$))
            .subscribe(([_, borrowableItems]) => {
            this.itemsHolder = borrowableItems;
            this.borrowableItems = borrowableItems.sort((item1, item2) => {
                return item1.DisplayName.toLowerCase()
                    .localeCompare(item2.DisplayName.toLowerCase(), 'cs', {
                    numeric: true,
                    sensitivity: 'base'
                    });
            });
            this.store.dispatch(new LoadWarehouseAll())
            .pipe(withLatestFrom(this.warehouses$))
            .subscribe(([_, warehouses]) => {
                this.warehouses = warehouses;
            });

        });

    }

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

    onFilterExpand() {
        this.filterExpanded = !this.filterExpanded;
    }

    onSearchLoaded(): void {
        this.searchClearFocus();
    }

    onFilterTap() {
        this.othersIsLoading = true;
        dismissSoftKeybaord();
        const isCity = this.city.nativeElement.text.toLowerCase().trim() !== '';
        const isPrice = this.maxPrice.nativeElement.text.trim() !== '';
        if (isCity || isPrice) {
            this.borrowableItems = this.borrowableItems.filter(item => {
                item.expanded = false;

                return (!isCity || (item.City && latinise(item.City.toLowerCase()).indexOf(latinise(this.city.nativeElement.text.toLowerCase().trim())) !== -1))
                && (!isPrice || (item.RentPrice && (item.RentPrice <= +(this.maxPrice.nativeElement.text.trim()))));
            });
        } else {
            const searchBar = <SearchBar>this.page.getViewById('searchBar');
            if (searchBar.text !== '') {
                this.onSearchSubmit();
            } else {
                this.borrowableItems = this.itemsHolder;
            }
        }
        this.othersIsLoading = false;
    }

    searchClearFocus() {
        const searchBar = <SearchBar>this.page.getViewById('searchBar');
        searchBar.text = '';
        if (isAndroid) {
            searchBar.android.clearFocus();
        }
    }

    onSearchClear(): void {
        this.borrowableItems = this.itemsHolder;
        const isCity = this.city.nativeElement.text.toLowerCase().trim() !== '';
        const isPrice = this.maxPrice.nativeElement.text.trim() !== '';
        if (isCity || isPrice) {
            this.onFilterTap();
        }
    }

    onSearchSubmit(): void {
        const searchBar = <SearchBar>this.page.getViewById('searchBar');
        const searchTerm = searchBar.text.toLowerCase();
        this.borrowableItems = this.itemsHolder;
        if (searchTerm !== '') {

            this.borrowableItems = this.borrowableItems.filter(item => {
                return latinise(item.DisplayName.toLowerCase()).indexOf(latinise(searchTerm)) !== -1;
            });
            const isCity = this.city.nativeElement.text.toLowerCase().trim() !== '';
            const isPrice = this.maxPrice.nativeElement.text.trim() !== '';
            if (isCity || isPrice) {
                this.onFilterTap();
            }

        }
        dismissSoftKeybaord();
    }

    makeReservation(item: WarehouseItemAllBorrowableOutput) {
        if (!this.warehouses || this.warehouses.length === 0) {
            feedbackMessage(FeedbackType.Warning, 'Rezervace', `Pro možnost rezervace je nutné mít založený alespoň 1 sklad.`);

            return;
        }

        this.othersIsLoading = true;
        setTimeout(() => {
            this.routerExtensions.navigate(['material/reservationNew', item.ID, item.DisplayName, item.ID_Unit], {transition: transitionOptions});
        }, 10);
    }

    get downIcon() {
        return String.fromCharCode(0xf107);
    }

    get leftIcon() {
        return String.fromCharCode(0xf104);
    }
}
