import { Component, OnInit } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { RouterExtensions } from '@nativescript/angular';
import { EventData, Page, SearchBar, Switch } 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 { WarehouseItemAllOutput } from '../../entities/output/warehouseItemAllOutput';
import { LoadWarehouseItemAll, LoadWarehouseItemDeleted } from '../../state-mgmt/material-unit.action';
import { MaterialUnitState } from '../../state-mgmt/material-unit.state';
import { feedbackMessage } from '../../utils/feedback-messages';

@Component({
    selector: 'MaterialUnit',
    moduleId: module.id,
    templateUrl: './material-unit.component.html',
    styleUrls: ['./material-unit.component.scss']
})

export class MaterialUnitComponent implements OnInit {
    @Select(MaterialUnitState.getWarehouseItems) items$: Observable<WarehouseItemAllOutput[]>;
    @Select(MaterialUnitState.getWarehouseDeletedItems) deletedItems$: Observable<WarehouseItemAllOutput[]>;
    @Select(MaterialUnitState.isLoading) isLoading$: Observable<boolean>;

    items: WarehouseItemAllOutput[];
    deletedItems: WarehouseItemAllOutput[];
    itemsAll: WarehouseItemAllOutput[];
    itemsAllHolder: WarehouseItemAllOutput[];
    othersIsLoading: boolean;
    showDeleted: 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/materialUnit') {
                    this.othersIsLoading = false;
                }
            }
        });
    }

    ngOnInit(): void {
        this.othersIsLoading = false;
        this.deletedItems = null;
        this.showDeleted = false;
    }

    /**
     * event added because of reloading new items or updated items
     */
    onLoad() {
        this.store.dispatch(new LoadWarehouseItemAll())
            .pipe(withLatestFrom(this.items$))
            .subscribe(([_, items]) => {
                this.items = items.sort((item1, item2) => {
                    return item1.DisplayName.toLowerCase()
                        .localeCompare(item2.DisplayName.toLowerCase(), 'cs', {
                            numeric: true,
                            sensitivity: 'base'
                        });
                });
                this.itemsAll = this.items;
                if (this.showDeleted && this.deletedItems) {
                    this.itemsAll = this.itemsAll.concat(this.deletedItems).sort((item1, item2) => {
                        return item1.DisplayName.toLowerCase()
                            .localeCompare(item2.DisplayName.toLowerCase(), 'cs', {
                                numeric: true,
                                sensitivity: 'base'
                            });
                    });

                } else {
                    this.showDeleted = false;
                }
                this.itemsAllHolder = this.itemsAll;
                this.searchClearFocus();

            }, err => {
                feedbackMessage(FeedbackType.Error, 'Načtení položek', 'Nepodařilo se načíst položky.');
                console.log(err);
            });
    }

    switchClicked(args: EventData) {
        this.onSearchClear();
        this.searchClearFocus();
        this.showDeleted = (<Switch>args.object).checked;
        if ((<Switch>args.object).checked) {
            if (this.deletedItems === null) {
                this.deletedLoaded();
            } else {
                this.itemsAll = this.itemsAll.concat(this.deletedItems).sort((item1, item2) => {
                    return item1.DisplayName.toLowerCase()
                        .localeCompare(item2.DisplayName.toLowerCase(), 'cs', {
                            numeric: true,
                            sensitivity: 'base'
                        });
                });
            }
        } else {
            this.itemsAll = this.items;
        }
        this.itemsAllHolder = this.itemsAll;
    }

    /**
     * load deleted items
     */
    deletedLoaded() {
        this.store.dispatch(new LoadWarehouseItemDeleted())
            .pipe(withLatestFrom(this.deletedItems$))
            .subscribe(([_, deletedItems]) => {
                this.deletedItems = deletedItems;
                this.itemsAll = this.itemsAll.concat(this.deletedItems).sort((item1, item2) => {
                    return item1.DisplayName.toLowerCase()
                        .localeCompare(item2.DisplayName.toLowerCase(), 'cs', {
                            numeric: true,
                            sensitivity: 'base'
                        });
                });
                this.itemsAllHolder = this.itemsAll;
            }, err => {
                feedbackMessage(FeedbackType.Error, 'Načtení vyřazených položek', 'Nepodařilo se načíst vyřazené položky.');
                console.log(err);
            });

    }

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

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

    onSearchClear(): void {
        this.itemsAll = this.itemsAllHolder;
    }

    onSearchSubmit(eventData): void {
        const searchBar = eventData.object;
        const searchTerm = searchBar.text.toLowerCase();
        this.itemsAll = this.itemsAllHolder;
        if (searchTerm !== '') {
            this.itemsAll = this.itemsAll.filter(item => {
                return latinise(item.DisplayName.toLowerCase()).indexOf(latinise(searchTerm)) !== -1;
            });
        }
    }

    /**
     * Takes photo of item.
     *
     * You need to add imports:
     *      import * as camera from "nativescript-camera";
     *      import { Image } from "@nativescript/core/ui/image";
     * You need to install plugin:
     *      tns plugin add nativescript-camera
     * You need to add permission in App_Resources\Android\src\main\AndroidManifest.xml:
     *      <uses-permission android:name="android.permission.CAMERA"/>
     *
     */
    // onTakePhotoTap(item: WarehouseItemAllOutput) {
    // camera.requestPermissions().then(
    //     (success) => {
    //         const options = {
    //             width: 300,
    //             height: 300,
    //             keepAspectRatio: false,
    //             saveToGallery: false
    //         };

    //         camera.takePicture(options)
    //         .then((imageAsset) => {
    //             item.image = new Image();
    //             item.image.src = imageAsset;
    //              //TODO load image on server
    //         }).catch((err) => {
    //             console.log("Error -> " + err.message);
    //         });
    //     },
    //     err => {
    //         // permission request rejected
    //         // ... tell the user ...
    //     }
    // );

    // }

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

    onTapItem(item: WarehouseItemAllOutput) {
        this.searchClearFocus();
        this.othersIsLoading = true;
        setTimeout(() => {
            this.routerExtensions.navigate(['material/materialDetail', item.ID], { transition: transitionOptions });
        }, 10);
    }

    newItem() {
        this.searchClearFocus();
        // this.othersIsLoading = true;
        setTimeout(() => {
            this.routerExtensions.navigate(['material/materialNew', (-1).toString()], { transition: transitionOptions });
        }, 10);
    }

    get newIcon() {
        return String.fromCharCode(0xf271);
    }
}
