module insite.orderapproval {
    "use strict";

    export class OrderApprovalDetailController {
        currentCart: CartModel;
        account: AccountModel;
        cart: CartModel;
        approveOrderErrorMessage: string;
        validationMessage: string;
        listPageUri: string;
        promotions: PromotionModel[];
        isExternal: boolean;
        cartPageUri: string;

        static $inject = ["orderApprovalService", "cartService", "accountService", "coreService", "queryString", "promotionService", "$localStorage"];

        constructor(
            protected orderApprovalService: orderapproval.IOrderApprovalService,
            protected cartService: cart.ICartService,
            protected accountService: account.IAccountService,
            protected coreService: core.ICoreService,
            protected queryString: common.IQueryStringService,
            protected promotionService: promotions.IPromotionService,
            protected $localStorage: common.WindowLocalStorage,
        ) {
        }

        $onInit(): void {
            const cartId = this.queryString.get("cartid");
            this.isExternal = this.queryString.get("external-approval")

            this.initEvents();

            this.accountService.getAccount().then(
                (account: AccountModel) => { this.getAccountCompleted(account); },
                (error: any) => { this.getAccountFailed(error); });

            this.orderApprovalService.getCart(cartId).then(
                (cart: CartModel) => { this.orderApprovalServiceGetCartCompleted(cart); },
                (error: any) => { this.orderApprovalServiceGetCartFailed(error); });
        }

        protected initEvents(): void {
            this.cartService.getCart().then(
                (cart: CartModel) => { this.cartServiceGetCartCompleted(cart); },
                (error: any) => { this.cartServiceGetCartFailed(error); });
        }

        protected getAccountCompleted(account: AccountModel): void {
            this.account = account;

            if (this.isExternal) {
                this.approveExternalOrder()
            }
        }

        protected getAccountFailed(error: any): void {
        }

        protected orderApprovalServiceGetCartCompleted(cart: CartModel): void {
            if (cart.status !== "AwaitingApproval") {
                this.coreService.redirectToPath(this.listPageUri);
                return;
            }

            this.promotionService.getCartPromotions(cart.id).then(
                (promotionCollection: PromotionCollectionModel) => {
                    this.getCartPromotionsCompleted(promotionCollection);
                },
                (error: any) => {
                    this.getCartPromotionsFailed(error);
                });

            this.cart = cart;
            this.canApproveOrders();

            if (this.isExternal) {
                this.approveExternalOrder()
            }
        }

        protected orderApprovalServiceGetCartFailed(error: any): void {
            this.validationMessage = error.message || error;
        }

        protected cartServiceGetCartCompleted(cart: CartModel): void {
            this.currentCart = cart;
            this.canApproveOrders();
        }

        protected cartServiceGetCartFailed(error: any): void {
        }

        protected canApproveOrders(): void {
            if (this.account && this.account.canApproveOrders && this.cart) {
                this.account.canApproveOrders = this.account.userName !== this.cart.initiatedByUserName;
            }
        }

        approvalDisabled(): boolean {
            return this.cart && this.cart.cartLines.every(o => o.isRestricted);
        }

        approveOrder(cartUri: string): void {
            const hasRestrictedProducts = this.cart.cartLines.some(o => o.isRestricted);
            this.$localStorage.set("hasRestrictedProducts", hasRestrictedProducts.toString());
            this.approveOrderErrorMessage = "";
            this.cart.status = "Cart";

            this.cartService.updateCart(this.cart).then(
                (cart: CartModel) => { this.updateCartCompleted(cartUri, cart); },
                (error: any) => { this.updateCartFailed(error); });
        }

        approveExternalOrder(): void {
            if (!this.isExternal || !this.account || !this.account.canApproveOrders || !this.cart || this.cart.status !== "AwaitingApproval") {
                return;
            }

            this.approveOrder(this.cartPageUri);
        }

        protected updateCartCompleted(cartUri: string, cart: CartModel): void {
            this.coreService.redirectToPath(cartUri);
        }

        protected updateCartFailed(error: any): void {
            this.approveOrderErrorMessage = error.message;
        }

        protected getCartPromotionsCompleted(promotionCollection: PromotionCollectionModel): void {
            this.promotions = promotionCollection.promotions;
        }

        protected getCartPromotionsFailed(error: any): void {
        }
    }

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