'use strict';

angular.module('pos')
    .controller('DashboardCtrl', function ($scope, $routeParams, $http, $timeout, $interval) {
        var webservice = 'api/?a=pos';

        $scope.postParams = {
            'project_id': "5",
            'pos_id': 0,
            'cashier': window.localStorage.getItem("cashier"),
            'token': window.localStorage.getItem("token"),
            'active': 1,
            'disabled': 0
        };
        var postParams = $scope.postParams;

        $scope.posList = _.range(0, 9);
        
        $scope.filterInvoices = function (pos) {
            if (pos == 0) return $scope.invoices;
            return _.filter($scope.invoices, function (e) { return e.pos_id == pos; });
        };        
        
        $scope.lineTemplate = function () {
            if ($scope.currentInvoice.last_line_number === undefined) {
                $scope.currentInvoice.last_line_number = parseInt($scope.currentInvoice.details[0].line_number, 10);
            }
            $scope.currentInvoice.last_line_number += 1;
            return {
                'line_number': $scope.currentInvoice.last_line_number,
                'item': "",
                'seller_id': "",
                'item_id': "",
                'price': 0
            };
        };

        $scope.invoiceTemplate = function () {
            return {
                    'invoice_number': "",
                    'project_id': $scope.postParams.project_id,
                    'pos_id': $scope.postParams.pos_id,
                    'invoice_date': moment(),
                    'cashier': $scope.postParams.cashier,
                    'last_line_number': 1,
                    'line_count': 0,
                    'valid': false,
                    'total': 0.0,
                    'paid': 0.0,
                    'details': [
                        {
                            'line_number': 1,
                            'item': "",
                            'seller_id': "",
                            'item_id': "",
                            'price': 0.0
                        }
                    ]
                };
        };

        var successSound = new Audio("sounds/success.wav");
        var errorSound = new Audio("sounds/error.wav");

		$scope.warning = 0;
		$scope.warningInfo = [
			"",
			"Dieses Etikett wurde bereits gescannt",
			"Etiketten-Nummer ungültig",
			"Preis ungültig"
		];
		
        $scope.currentLine = 0;
        $scope.currentLineType = '.item';
        $scope.currentInvoice = $scope.invoiceTemplate();
        $scope.showCurrentInvoice = false;

        $scope.offlineInvoices = JSON.parse(window.localStorage.getItem("offlineInvoices"));
        $scope.invoices = [];
        $scope.soldItems = [];

		$scope.total = function (pos) {
            return _.reduce($scope.filterInvoices(pos), function (sum, i) { return sum + parseFloat(i.total); }, 0);
        };

        $scope.invoiceLineCount = function () {
            return $scope.currentInvoice.details.length;
        };

        $scope.invoiceTotal = function () {
            return _.reduce($scope.currentInvoice.details, function (sum, d) { return sum + parseFloat(d.price); }, 0);
        };

        $scope.addItem = function () {
            $scope.currentInvoice.details.unshift($scope.lineTemplate());
        };

        $scope.removeItem = function (item) {
            $scope.currentInvoice.details = _.without($scope.currentInvoice.details, item);
        };

        $scope.currentChange = function () {
            if ($scope.currentInvoice.paid === 0.0
                || $scope.currentInvoice.paid == ""
                || $scope.currentInvoice.paid == Number.NaN) {
                return 0.0;
            }

            $scope.currentInvoice.total = $scope.invoiceTotal();
            return $scope.currentInvoice.paid - $scope.currentInvoice.total;
        };

        $scope.getInvoiceByNumber = function (invoiceNumber) {
            return _.find($scope.invoices, function (e) { return e.invoice_number === invoiceNumber; });
        };

        $scope.editInvoice = function (invoiceNumber) {
			
            $scope.currentInvoice = $scope.getInvoiceByNumber(invoiceNumber);
            $scope.selectItem(0);
        };

        $scope.jumpEvent = function (event) {
            var key = String.fromCharCode(event.which);

            switch (key) {
                case '*':
                    $scope.selectPrice($scope.currentLine+1);
                    return false;
                case '/':
                    $('#paid').select();
                    $scope.validate();
                    return false;
                case '+':
                    $scope.selectItem(0);
                    return false;
            }
            return true;
        };
        $("body").on('keypress', $scope.jumpEvent);


        $scope.lineNumberComparator = function (v1, v2) {
            return (parseInt(v1, 10) < parseInt(v2, 10)) ? -1 : 1;
        };

        $scope.keyPressModal = function (e) {
            if (e.which === 13) {
                e.preventDefault();
                $(".modal").modal("hide");
                $scope.selectItem();
            }
            return true;
        };

        $scope.showWarning = function (num) {
            $scope.warning = num;
            $('#warningModal').modal('show');
            errorSound.play();
        };

        $scope.selectItem = function (index, itemType) {
            if (index !== undefined) {
                $scope.currentLine = index;
            }
            if (itemType !== undefined) {
                $scope.currentLineType = itemType;
            } else {
                $scope.currentLineType = '.item';
            }

            $timeout(function () {
                $($scope.currentLineType)[$scope.currentLine].select();
            }, 300, true);
        };

        $scope.selectPrice = function (index) {
            $scope.selectItem(index, '.price');
        };

        $scope.currentSoldItems = function (index) {
            var list = _.pluck($scope.currentInvoice.details, 'item');
            var needle = list[index];
            list[index] = "";
            for (var i = 0; i < list.length; i++) {
                if (list[i] === needle) {
                    return i;
                }
            }
            return index;
        };

        $scope.keyPressItem = function (e, i) {
            if (e.which === 13) {
                e.preventDefault();

                var currentItem = $scope.currentInvoice.details[i];
                if ($scope.currentLine !== i && currentItem.item === "") {
                    return true;
                }

                if (!currentItem.item.match(/^\d{3}-\d{3}$/gi)) {
                    $scope.showWarning(2);
				} else if ($scope.currentInvoice.invoice_number == 0 && _.contains($scope.soldItems, currentItem.item)) {
                    $scope.showWarning(1);
                } else if ($scope.currentSoldItems(i) !== i) {
                    errorSound.play();
                    $scope.selectPrice($scope.currentSoldItems(i));
                    currentItem.item = "";
                    return false;
                } else {
                    successSound.play();
                    $scope.selectPrice(i);
					return true;
                }

				$scope.selectItem(i);
                return false;
            }
            var key = String.fromCharCode(e.which);
            if (key == '/') {
                e.preventDefault();
            }

            return true;
        };

        $scope.keyPressPrice = function (e, i) {
            if (e.which === 13) {
                var currentPrice = $scope.currentInvoice.details[i].price;

                if (!currentPrice.toString().match(/^\d+(\.\d\d?)?$/gi) || currentPrice <= 0) {
                    errorSound.play();
                    e.preventDefault();
                    $scope.selectPrice(i);
                    return false;
                }

                if ($scope.currentInvoice.details[0].item !== "") {
                    $scope.addItem();
                }

                successSound.play();
                $scope.selectItem(0);
                return false;
            }
            var key = String.fromCharCode(e.which);
            if (key == '/') {
                e.preventDefault();
            }
            return true;
        };

        $scope.keyPressPaid = function (e) {
            $scope.validate();

            if (e.which === 13) {
                $scope.checkOut();
            }
        };


        $scope.validate = function () {
            var i = 0, item;
            for (i = $scope.currentInvoice.details.length - 1; i >= 0; i--) {
                if ($scope.currentInvoice.details[i].price == 0 && $scope.currentInvoice.details[i].item === "") {
                    $scope.removeItem($scope.currentInvoice.details[i]);
                    break;
                }

                item = $scope.currentInvoice.details[i];
                if (!item.price.toString().match(/^\d+(\.\d\d?)?$/gi) || item.price <= 0) {
                    $scope.selectPrice(i);
                    errorSound.play();
                    $scope.currentInvoice.valid = false;
                    return false;
                }
                if (item.item === "" || !item.item.match(/^\d{3}-\d{3}$/gi)
                    || ($scope.currentInvoice.invoice_number == 0 && _.contains($scope.soldItems, item.item))) {
                    $scope.selectItem(i);
                    errorSound.play();
                    $scope.currentInvoice.valid = false;
                    return false;
                }

                item.seller_id = item.item.substring(0, 3);
                item.item_id = item.item.substring(4, 7);
            }
            if ($scope.currentInvoice.details.length === 0) {
                $scope.addItem();
                $scope.selectItem(0);
                errorSound.play();
                $scope.currentInvoice.valid = false;
                return false;
            }

            $scope.currentInvoice.cashier = $scope.postParams.cashier;
            $scope.currentInvoice.line_count = $scope.currentInvoice.details.length;
            $scope.currentInvoice.invoice_date = moment();
            $scope.currentInvoice.valid = true;
            return true;
        };

        $scope.checkOut = function () {
            if (isNaN($scope.currentInvoice.paid) || $scope.currentInvoice.paid == '' || $scope.currentInvoice.paid == 0) {
                $scope.currentInvoice.paid = $scope.currentInvoice.total;
            }

            $scope.saveInvoice($scope.currentInvoice);
            window.localStorage.setItem("cashier", $scope.postParams.cashier);
            $scope.currentInvoice = $scope.invoiceTemplate();
            $scope.selectItem(0);
        };

        if ($scope.offlineInvoices === null) {
            $scope.offlineInvoices = [];
        }

        if ($scope.postParams.token === null) {
            $scope.postParams.token = 0;
        }

        $scope.setActive = function () {
            $scope.postParams.active = 1;
            $scope.refreshStatus();
        };

        $scope.setInactive = function () {
            $scope.postParams.active = 0;
            $scope.refreshStatus();
        };

        $scope.closePos = function () {
            $scope.postParams.disabled = 1;
            $scope.refreshStatus();
        };

        $scope.refreshStatus = function () {
            $http.post(webservice + '_token', postParams).then(function (response) {
                $scope.postParams.token = response.data.token;
                window.localStorage.setItem("token", $scope.postParams.token);
                $scope.postParams.active = response.data.active;
                $scope.postParams.disabled = response.data.disabled;
            });
        };

		$scope.saveInvoice = function (invoice) {
            $http.post(webservice + '_invoices', { 'params': $scope.postParams, 'invoice': invoice })
				.then(function (response) {
                    if (response.data.invoice_number !== undefined) {
                        $scope.offlineInvoices = _.without($scope.offlineInvoices, invoice);
                        $scope.invoices[$scope.invoices.length] = response.data;
                    } else if (!_.contains($scope.offlineInvoices, invoice)) {
                        $scope.offlineInvoices.push(invoice);
                    }
                    window.localStorage.setItem("offlineInvoices", JSON.stringify($scope.offlineInvoices));
				});			
		};
		
		$scope.loadInvoice = function (invoiceNumber) {
            $http.post(webservice + '_invoices', { 'params': $scope.postParams, 'invoice_number': invoiceNumber })
				.then(function (response) {
                    if (response.data.invoice_number !== undefined) {
                        $scope.currentInvoice = response.data;
                        $scope.showCurrentInvoice = true;
                        $scope.selectItem(0);
                    } 
				});			
		};

        $scope.printInvoice = function (invoiceNumber) {
            $http.post(webservice + '_print', { 'params': $scope.postParams, 'invoice_number': invoiceNumber })
                .then(function (response) {
                    if (response.data.invoice_number !== undefined) {
                        var invoice = $scope.getInvoiceByNumber(invoiceNumber);
                        invoice.printed = 1;
                    }
                });
        };

		$scope.refresh = function () {
            for (var i = 0; i < $scope.offlineInvoices.length; i++) {
                $timeout($scope.saveInvoice($scope.offlineInvoices[i]), 3000 * i);
            }

            $http.post(webservice + '_infos', $scope.postParams)
				.then(function (response) {
					//$scope.soldItems = response.data.items;
                    $scope.invoices = response.data.invoices;
				});
		};

        $interval($scope.refresh, 60 * 1000);
        $scope.refreshStatus();
        $scope.refresh();
    });