import { Component, OnInit, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { ModalDialogOptions, ModalDialogService, RouterExtensions } from '@nativescript/angular';
import { Connectivity } from '@nativescript/core';
import { confirm } from '@nativescript/core/ui/dialogs';
import { BarcodeScanner } from 'nativescript-barcodescanner';
import { FeedbackType } from 'nativescript-feedback';
import { ListViewEventData } from 'nativescript-ui-listview';
import { transitionOptions } from '~/constants/shared.constants';
import { ModalHelpComponent } from '../../components/modal-view-help/modal-view-help.component';
import { StockTakingAllOutput } from '../../entities/output/stockTakingAllOutput';
import { WarehouseAllOutput } from '../../entities/output/warehouseAllOutput';
import { WarehouseItemAllOutput } from '../../entities/output/warehouseItemAllOutput';
import { DatabaseService } from '../../services/database.service';
import { feedbackMessage } from '../../utils/feedback-messages';

@Component({
    selector: 'InventoryWarehouse',
    moduleId: module.id,
    templateUrl: './inventory-warehouse.component.html',
    styleUrls: ['./inventory-warehouse.component.scss']
})

export class InventoryWarehouseComponent implements OnInit {

    idWarehouse: number;
    nameWarehouse: string;
    warehouse: WarehouseAllOutput = null;
    currentInventory: StockTakingAllOutput = null;
    items: WarehouseItemAllOutput[];
    othersIsLoading: boolean;
    everyLocalChangeOrLastID: boolean = false;

    constructor(
        private router: Router,
        private routerExtensions: RouterExtensions,
        private route: ActivatedRoute,
        private database: DatabaseService,
        private modalService: ModalDialogService,
        private viewContainerRef: ViewContainerRef
    ) {
        this.items = null;
        this.router.events.subscribe((val) => {
            if (val instanceof NavigationEnd) {
                if (RegExp('\/material\/inventoryWarehouse\/[0-9]+\/[^/]+').test(this.router.url)) {
                    this.othersIsLoading = false;
                }
            }
        });
    }

    onLoad() {
        this.othersIsLoading = true;
        this.idWarehouse = +this.route.snapshot.params['id'];
        this.nameWarehouse = this.route.snapshot.params['name'];

        this.database.loadItems(this.idWarehouse)
            .then((items) => {
                this.items = items.sort((item1: { DisplayName: string; }, item2: { DisplayName: string; }) => {
                    return item1.DisplayName.toLowerCase()
                        .localeCompare(item2.DisplayName.toLowerCase(), 'cs', {
                        numeric: true,
                        sensitivity: 'base'
                    });
                });

                this.everyLocalChangeOrLastID = (this.items.filter(i => i.localChange === true).length
                    + this.items.filter(i => i.idLastInventory !== null).length) === this.items.length;
                this.database.loadWarehouse(this.idWarehouse)
                    .then((warehouse) => {
                        this.warehouse = warehouse[0];
                        this.othersIsLoading = false;
                        this.database.loadStockTaking(this.warehouse.DisplayName.trim())
                            .then((inventory) => {
                                if (inventory.length === 1) {
                                    this.currentInventory = inventory[0];
                                    this.othersIsLoading = false;
                                }
                            }, err => {
                                feedbackMessage(FeedbackType.Warning, 'Inventarizace', `V daném skladu neprobíhá žádná inventura.`);
                                this.othersIsLoading = false;
                                console.log(err);
                            });
                    }, err => {
                        feedbackMessage(FeedbackType.Error, 'Inventarizace', `Nelze najít sklad.`);
                        this.othersIsLoading = false;
                        console.log(err);
                    });
            }, err => {
                feedbackMessage(FeedbackType.Error, 'Inventarizace', `Nelze načíst položky.`);
                this.othersIsLoading = false;
                console.log(err);
            });
    }

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

    toConfirmed() {
        this.othersIsLoading = true;
        setTimeout(() => {
            this.routerExtensions.navigate(['material/inventoryConfirmed', this.warehouse.ID], {transition: transitionOptions});
        }, 10);
    }

    toInventory() {
        this.othersIsLoading = true;
        setTimeout(() => {
            this.routerExtensions.navigate(['material/inventoryWaitingConfirm', this.warehouse.ID], {transition: transitionOptions});
        }, 10);
    }

    onTapItem(event: ListViewEventData) {
        this.items[event.index].expanded = !this.items[event.index].expanded;
    }

    /**
     * if there is no internet connection, dialog of leaving appears
     */
    onBackButton(): void {
        this.othersIsLoading = true;
        const connectionType = Connectivity.getConnectionType();
        if (connectionType === Connectivity.connectionType.none) {
            const options = {
                title: 'Inventarizace',
                message: 'Pokud odejdete, dojde k odhlášení a nebudete se moct vrátit dříve, než se opět přihlásíte. Položky zůstanou ve stavu, v jakém je zanecháte. Opravdu chcete odejít?',
                okButtonText: 'Ano',
                cancelButtonText: 'Ne'
            };
            this.othersIsLoading = false;
            confirm(options).then((result: boolean) => {
                if (result) {
                    this.routerExtensions.back();
                }
            });
        } else {
            this.othersIsLoading = false;
            this.routerExtensions.back();
        }
    }

    templateSelector(): string {
        return 'default';
    }

    /**
     * add item to 'waiting items' - item is inventorized localy and is waiting for internet connection to confirm inventorizing
     *
     * @param item which will be added to waiting items
     * @param fromScanner flag for setting timeout because of slow closing scanner
     */
    inventorizeItem(item: WarehouseItemAllOutput, fromScanner: boolean = false) {
        this.othersIsLoading = true;
        if (item.idLastInventory !== null && item.idLastInventory === this.currentInventory.ID) {
            if (!fromScanner) {
                setTimeout(() => {
                    feedbackMessage(FeedbackType.Warning, 'Inventarizace', `Předmět ${item.DisplayName} už byl inventarizován.`);
                }, 20);
            } else {
                feedbackMessage(FeedbackType.Warning, 'Inventarizace', `Předmět ${item.DisplayName} už byl inventarizován.`);
            }
            this.othersIsLoading = false;

            return;
        }

        item.localChange = true;
        this.database.updateItemLocal(item);
        item.expanded = false;
        this.everyLocalChangeOrLastID = (this.items.filter(i => i.localChange === true).length
                    + this.items.filter(i => i.idLastInventory !== null).length) === this.items.length;
        if (!fromScanner) {
            setTimeout(() => {
                feedbackMessage(FeedbackType.Success, 'Inventarizace', `Předmět ${item.DisplayName} byl přidán k inventarizování.`);
            }, 20);
        } else {
            feedbackMessage(FeedbackType.Success, 'Inventarizace', `Předmět ${item.DisplayName} byl přidán k inventarizování.`);
        }
        this.othersIsLoading = false;
    }

    /**
     * scan barcode or qr code
     * if the result is id of not inventorized item, it will be added to waiting items
     */
    onScanTap() {
        new BarcodeScanner().scan({
            formats: 'QR_CODE, EAN_13',
            showFlipCameraButton: true,
            preferFrontCamera: false,
            showTorchButton: true,
            beepOnScan: true,
            torchOn: false,
            resultDisplayDuration: 0,
            openSettingsIfPermissionWasPreviouslyDenied: true // ios only ,

        }).then((result) => {
            const idItem = +result.text.substring(2);
                const item = this.items.find(x => x.ID === idItem);

                if (item) {
                setTimeout(() => {
                    this.inventorizeItem(item, true);
                }, 10);
            } else {
                setTimeout(() => {
                    feedbackMessage(FeedbackType.Error, 'Sken kódu', `Předmět nepatří do vašeho skladu.`);
                }, 20);
            }
        }, (errorMessage) => {
                console.log('Error when scanning ' + errorMessage);
            }
        );

        // if you want continously scanning, change code above with this

        // console.log();
        // this.barcodeScanner.scan({
        //     formats: "QR_CODE, EAN_13",
        //     preferFrontCamera: false,
        //     showTorchButton: true,
        //     message: "Naskenujte barcode nebo QR kód. Každou položku zaeviduje pouze jednou.",
        //     beepOnScan: true,
        //     torchOn: false,
        //     resultDisplayDuration: 0,
        //     openSettingsIfPermissionWasPreviouslyDenied: true, //ios only
        //     continuousScanCallback: (result) => {
        //         console.log(result)
        //         this.othersIsLoading = true;
        //         const idItem = +result.text.substring(2);
        //         console.log(idItem);
        //         const filtered = this.items.filter(item => item.ID === idItem);
        //         if (filtered.length === 1) {
        //             const item : WarehouseItemAllOutput = filtered[0];
        //             //console.log(item.toFullString());
        //             if (item.idLastInventory === this.currentInventory.ID) {
        //                 console.log("jiz bylo inventarizovano")
        //             } else {
        //                 console.log("jsu na to ")
        //                 this.inventorizeItem(item, true);
        //             }
        //         }
        //         this.othersIsLoading = false;
        //     },
        //     closeCallback: () => {
        //         console.log("zavreno");
        //     },

        // }).then(() => {

        //     }, (errorMessage) => {
        //         console.log("Error when scanning " + errorMessage);
        //     }
        // );
    }

    /**
     * shows modal view with help about inventorizing
     */
    showModalHelp() {
        this.othersIsLoading = true;
        const options: ModalDialogOptions = {
            viewContainerRef: this.viewContainerRef,
            context: {
                label: 'Inventarizace',
                messages: ['Inventarizaci je možné provádět offline, je pouze potřeba vybrat sklad, ve kterém bude inventura prováděna. Položky se načtou do lokální databáze, proto je možné aplikaci minimalizovat a znovu maximalizovat až ve skladu (i bez připojení k internetu). Pokud však aplikaci zavřete, nebudete se bez přístupu k internetu moct přihlásit a tudíž v inventarizaci pokračovat.',
                    'Při procházení skladu přidejte položky k inventarizování (naskenováním kódu nebo pomocí symbolu fajfky).',
                    'Jakmile budete připojeni k internetu, potvrďte inventarizaci. Tento postup je možné provést několikrát, není nutné inventarizovat najednou všechny položky.',
                    'Až budou všechny chtěné položky inventarizovány, je potřeba inventuru uzavřít (zrušit) přes webové rozhraní.'
                        ]
            },
            fullscreen: false
        };
        this.othersIsLoading = false;
        this.modalService.showModal(ModalHelpComponent, options);
    }

    get helpIcon() {
        return String.fromCharCode(0xf059);
    }

    get qrcodeIcon() {
        return String.fromCharCode(0xf029);
    }

    get toInventoryIcon() {
        return String.fromCharCode(0xf360);
    }

    get toConfirmedIcon() {
        return String.fromCharCode(0xf14a);
    }

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

    get rightIcon() {
        return String.fromCharCode(0xf105);
    }

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