module insite.catalog {
    "use strict";
    import VmiBinModel = Insite.Catalog.WebApi.V1.ApiModels.VmiBinModel;
    import VmiCountModel = Insite.Catalog.WebApi.V1.ApiModels.VmiCountModel;
    import CartModel = Insite.Cart.WebApi.V1.ApiModels.CartModel;

    export class VmiBinsController extends BaseVmiBinsController {
        paginationStorageKey = "DefaultPaginationVmiBinList";
        vmiBinsPageUrl: string;
        isVmiAdmin: boolean;

        static $inject = ["$rootScope", "vmiBinService", "vmiLocationsService", "coreService", "paginationService", "queryString", "spinnerService", "deleteVmiBinsModalService", "vmiBinModalService", "vmiCountService", "cartService", "importVmiBinsModalService", "importVmiCountsModalService", "vmiCartPopupService", "$filter", "$scope", "$timeout", "$location", "sessionService"];

        constructor(
            protected $rootScope: ng.IRootScopeService,
            protected vmiBinService: vmiBin.IVmiBinService,
            protected vmiLocationsService: catalog.IVmiLocationsService,
            protected coreService: core.ICoreService,
            protected paginationService: core.IPaginationService,
            protected queryString: common.IQueryStringService,
            protected spinnerService: core.ISpinnerService,
            protected deleteVmiBinsModalService: vmiBin.IDeleteVmiBinsModalService,
            protected vmiBinModalService: vmiBin.IVmiBinModalService,
            protected vmiCountService: vmiCount.IVmiCountService,
            protected cartService: insite.cart.ICartService,
            protected importVmiBinsModalService: vmiBin.IImportVmiBinsModalService,
            protected importVmiCountsModalService: vmiCount.IImportVmiCountsModalService,
            protected vmiCartPopupService: insite.layout.IVmiCartPopupService,
            protected $filter: ng.IFilterService,
            protected $scope: ng.IScope,
            protected $timeout: ng.ITimeoutService,
            protected $location: ng.ILocationService,
            protected sessionService: account.ISessionService
        ) {
            super(vmiBinService, vmiLocationsService, coreService, paginationService, queryString, spinnerService, importVmiBinsModalService, importVmiCountsModalService, cartService, vmiCartPopupService, $filter, $scope, $timeout, $location);
        }

        $onInit(): void {
            this.initParams();

            this.getSession();

            this.$scope.$on("$locationChangeSuccess", (event, newUrl: string, oldUrl: string) => {
                const newUrlLowerCase = newUrl.toLowerCase();
                const vmiBinsPageUrlLowerCase = this.vmiBinsPageUrl.toLowerCase();
                if ((newUrlLowerCase.endsWith(vmiBinsPageUrlLowerCase, newUrlLowerCase.length) || newUrlLowerCase.indexOf(`${vmiBinsPageUrlLowerCase}?`) !== -1) && newUrl !== oldUrl) {
                    this.locationId = this.queryString.get("locationId");
                    if (this.selectedLocation && !this.locationId) {
                        this.selectedLocation = null;
                    }

                    this.getVmiBins();
                }
            });

            super.$onInit();
        }

        getSession(): void {
            this.sessionService.getSession().then(
                (session: SessionModel) => { this.getSessionCompleted(session); },
                (error: any) => { this.getSessionFailed(error); });
        }

        protected getSessionCompleted(session: SessionModel): void {
            this.isVmiAdmin = session.userRoles && session.userRoles.toLowerCase().indexOf("vmi_admin") !== -1;
        }

        protected getSessionFailed(error: any): void {
        }

        initParams(): void {
            this.locationId = this.queryString.get("locationId");

            this.$scope.$on("vmi-bins-were-deleted", () => {
                if (this.pagination) {
                    this.pagination.page = 1;
                }
                this.getVmiBins();
            });

            this.$scope.$on("vmi-bin-was-created", () => {
                this.getVmiBins();
            });

            this.$scope.$on("vmi-bins-were-imported", () => {
                this.getVmiBins();
                this.getAllVmiBins();
            });

            this.$scope.$on("vmi-counts-were-imported", () => {
                this.getVmiBins();
            });

            this.$scope.$on("get-all-vmi-bins-import-product", () => {
                this.getAllVmiBins(CallBackOption.OpenImportProductModal);
            });
        }

        openAddProductModal(): void {
            this.vmiBinModalService.display({
                vmiBin: { vmiLocationId: this.locationId },
                broadcastCreateStr: "vmi-bin-was-created",
                showImport: true
            });
        }

        deleteVmiBins(): void {
            this.deleteVmiBinsModalService.display({
                vmiBins: this.vmiBins.filter(o => this.isSelected[o.id.toString()]),
                broadcastStr: "vmi-bins-were-deleted"
            });
        }
        
        openImportCountModal(): void {
            this.spinnerService.show();
            this.getAllVmiBins(CallBackOption.OpenImportCountModal);
        }

        updateCurrentQty(vmiBin: VmiBinModel, oldLastCountQty: number): void {
            if (vmiBin.lastCountQty || vmiBin.lastCountQty === 0) {
                this.isUpdateInProgress = true;
                this.$rootScope.$broadcast("cartRequestInProcess", true);
                this.spinnerService.show();
                this.vmiCountService.addVmiCount(vmiBin.vmiLocationId, vmiBin.id, vmiBin.productId, vmiBin.lastCountQty).then(
                    (result: VmiCountModel) => { this.updateVmiCountCompleted(result); },
                    (error: any) => { this.updateVmiCountFailed(error, vmiBin); });
            } else {
                vmiBin.lastCountQty = oldLastCountQty;
            }
        }

        protected updateVmiCountCompleted(result: VmiCountModel): void {
            this.getVmiBins();
            this.spinnerService.hide();
            this.isUpdateInProgress = false;
            this.$rootScope.$broadcast("cartRequestInProcess", false);
        }

        protected updateVmiCountFailed(error: any, vmiBin: any): void {
            this.spinnerService.hide();
            this.isUpdateInProgress = false;
            this.$rootScope.$broadcast("cartRequestInProcess", false);
            if (error && error.message) {
                vmiBin.updateVmiCountFailed = error.message;
            }
        }

        reorderSelected(): void {
            var vmiBinsSelected = this.vmiBins.filter(o => this.isSelected[o.id.toString()]);
            vmiBinsSelected.forEach((vmiBin) => {
                vmiBin.product.qtyOrdered = vmiBin.maximumQty > vmiBin.lastCountQty ? vmiBin.maximumQty - vmiBin.lastCountQty : 1;
            });
            this.updateCart(vmiBinsSelected);
        }

        reorder(vmiBin: VmiBinModel): void {
            vmiBin.product.qtyOrdered = vmiBin.maximumQty > vmiBin.lastCountQty ? vmiBin.maximumQty - vmiBin.lastCountQty: 1;
            this.updateCart([vmiBin]);
        }

        protected updateCart(vmiBins: VmiBinModel[]): void {

            this.isUpdateInProgress = true;
            this.spinnerService.show("mainLayout", true);
            this.$rootScope.$broadcast("cartRequestInProcess", true);
            this.cartService.getCart().then(
                (cart: CartModel) => {
                    if (cart.status == "AlternateCart") {
                        this.addVmiBinsToCart(vmiBins);
                    } else {
                        this.cartService.addCart(this.locationId).then(
                            (result: CartModel) => {
                                this.cartService.getCart().then(
                                    (cart: CartModel) => {
                                        this.addVmiBinsToCart(vmiBins);
                                    },
                                    (error: any) => { this.getCartFailed(error); });
                            },
                            (error: any) => { this.addCartFailed(error); });
                    }
                },
                (error: any) => { this.getCartFailed(error); });
        }

        protected addVmiBinsToCart(vmiBins: VmiBinModel[]): void {
            this.cartService.addLineCollectionFromVmiBins(vmiBins, false, true).then(
                (cartLineCollection: CartLineCollectionModel) => { this.addProductsToCartCompleted(cartLineCollection); },
                (error: any) => { this.addProductsToCartFailed(error); });
        }

        protected addProductsToCartCompleted(data: any): void {
            this.isUpdateInProgress = false;
            this.spinnerService.hide("mainLayout");
            this.$rootScope.$broadcast("cartRequestInProcess", false);
        }

        protected addProductsToCartFailed(error: any): void {
            this.isUpdateInProgress = false;
            this.spinnerService.hide("mainLayout");
            this.$rootScope.$broadcast("cartRequestInProcess", false);
        }

        protected getLocationsCompleted(locationCollection: VmiLocationCollectionModel): void {
            this.vmiLocations = locationCollection.vmiLocations;
            this.selectedLocation = this.vmiLocations?.find(location => location.id.toLowerCase() === this.locationId?.toLowerCase());
            if (this.selectedLocation) {
                this.getVmiBins();
                this.cartService.getCart().then(
                    (cart: CartModel) => {
                        if (cart.status !== "AlternateCart") {
                            // Create new cart
                            this.createCart(this.selectedLocation.id);
                            return;
                        }

                        if (cart.vmiLocationId !== this.selectedLocation.id) {
                            this.$timeout(() => {
                                // Remove and Addnew cart
                                this.removeAndCreateCart(cart, this.selectedLocation.id);
                            }, 3);
                        }
                    },
                    (error: any) => { this.getCartFailed(error); });
            }
        }

        switchLocation(): void {

            if (!this.selectedLocation) {
                this.updateQueryString(null);
                return;
            }

            this.cartService.getCart().then(
                (cart: CartModel) => {
                    if (cart.status !== "AlternateCart") {
                        // Create new cart
                        this.createCart(this.selectedLocation.id);
                        this.updateQueryString(this.selectedLocation.id.toString());
                        return;
                    }

                    if (cart.vmiLocationId === this.selectedLocation.id) {
                        this.updateQueryString(this.selectedLocation.id.toString());
                        return;
                    }

                    if (cart.lineCount > 0) {
                        var cartLocation = this.vmiLocations?.find(location => location.id.toLowerCase() === cart?.vmiLocationId?.toString().toLowerCase());
                        // Show message
                        this.vmiCartPopupService.display({
                            cart: cart,
                            cartLocationName: cartLocation?.name,
                            selectedLocationId: this.selectedLocation.id,
                            onClose: () => {
                                this.selectedLocation = this.vmiLocations?.find(location => location.id.toLowerCase() === this.locationId?.toLowerCase());
                                this.$scope.$apply();
                                this.cartService.getCart();
                            }
                        });
                    }
                    else {
                        // Remove and Addnew cart
                        this.removeAndCreateCart(cart, this.selectedLocation.id);
                        this.updateQueryString(this.selectedLocation.id.toString());
                    }
                },
                (error: any) => { this.getCartFailed(error); });
        }

        protected createCart(locationId: System.Guid): void {
            this.cartService.addCart(locationId).then(
                () => {
                    this.cartService.getCart();
                },
                (error: any) => { this.addCartFailed(error); });
        }

        protected removeAndCreateCart(cart: CartModel, locationId: System.Guid): void {
            this.cartService.removeCart(cart).then(
                () => {
                    // Create new cart
                    this.createCart(locationId);
                },
                (error: any) => { this.deleteSavedOrderFailed(error); });
        }

        protected updateQueryString(locationId: string): void {
            this.$timeout(() => {
                this.$location.search("locationId", locationId);
            }, 0);
        }
    }

    angular
        .module("insite")
        .controller("VmiBinsController", VmiBinsController);
}