(function() {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.service('categories', ['$resource', 'urls', function($resource, metUrls) {
        
        var resource = $resource(metUrls('categoryApi').concat('/:categoryId'),
        {
            categoryId: '@categoryId'
        }, 
        {
            'update': {
                method: 'PUT'
            },
            'query': {
                method: 'GET',
                isArray: false
            }
        });

        return {
            getAll: function (options, success, error) {
                return resource.query(options, success, error);
            },
            getCategory: function(categoryId, success, error) {
                return resource.get({
                    categoryId: categoryId
                }, success, error);
            },
            update: function(category, success, error) {
                return resource.update(category, success, error);
            },
            create: function(category, success, error) {
                return resource.save(category, success, error);
            },
            remove: function(category, success, error) {
                return resource.remove({
                    categoryId: category.categoryId
                }, success, error);
            }
        };
    }]);
}());
(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');

    oneKeyApp.controller('categoriesController', ['$scope', '$filter', 'categories', 'focus', 'fadeOut', 'notify', 'localize', 'validate',
            function categoriesController($scope, $filter, metCategories, metFocus, metFadeOut, metNotify, metLocalize, metValidate) {
                $scope.adding = false;
                $scope.parentAddId = -1;
                $scope.categories = [];
                $scope.loading = true;
                $scope.new = null;
                $scope.original = null;
                $scope.selected = null;

                $scope.add = function () {
                    $scope.cancelAdd();
                    _.forEach($scope.categories, function (category) {
                        if (category.editing) {
                            $scope.cancelEdit(category);
                        }
                    });

                    $scope.new = {
                        categoryName: '',
                        valid: true,
                        duplicate: false
                    };

                    $scope.adding = true;
                    metFocus('focusAdd');
                };

                $scope.addingChild = function (parentId) {

                    return parentId === $scope.parentAddId;
                }

                $scope.addChild = function (parentId) {
                    $scope.cancelAdd();
                    _.forEach($scope.categories, function (category) {
                        if (category.editing) {
                            $scope.cancelEdit(category);
                        }

                        _.forEach(category.childCategories, function (childCategory) {
                            if (childCategory.editing) {
                                $scope.cancelEdit(childCategory);
                            }
                        });
                    });

                    $scope.new = {
                        categoryName: '',
                        parentCategoryId: parentId,
                        valid: true
                    };

                    $scope.parentAddId = parentId;
                    metFocus('focusAdd');
                };

                $scope.cancelAdd = function () {
                    $scope.new = null;
                    $scope.adding = false;
                    $scope.parentAddId = -1;
                };

                $scope.cancelEdit = function (category) {
                    angular.copy($scope.original, category);
                    $scope.original = null;
                    category.editing = false;
                };

                $scope.delete = function (category) {
                    var scope = this;
                    var parent = null;
                    if (category.parentCategoryId) {
                        parent = _.find($scope.categories, function (item) { return item.categoryId == category.parentCategoryId });
                    }

                    metCategories.remove(category, function () {
                        //success
                        metNotify.success(messages.categoryHasBeenDeleted.value);
                        metFadeOut(scope, function () {
                            _.remove($scope.categories, category);
                            if (parent) {
                                _.remove(parent.childCategories, category);
                            }
                        });
                    }, function (e) {
                        //error
                        console.log(e);
                    });
                };

                $scope.edit = function (item) {
                    _.forEach($scope.categories, function (category) {
                        if (category.editing) {
                            $scope.cancelEdit(category);
                        }

                        _.forEach(category.childCategories, function(childCategory) {
                            if (childCategory.editing) {
                                $scope.cancelEdit(childCategory);
                            }
                        });
                    }, function (error) {
                        // TODO: handle 
                    });
                    $scope.original = angular.copy(item);
                    item.editing = true;
                    item.valid = true;
                    metFocus('focusEdit');
                };

                $scope.isEmpty = function () {
                    return _.isEmpty($scope.categories);
                };

                $scope.orderBy = function () {
                    $scope.categories = $filter('orderBy')($scope.categories, 'categoryName');
                    _.forEach($scope.categories, function(category) {
                        category.childCategories = $filter('orderBy')(category.childCategories, 'categoryName');
                    });
                };

                $scope.clearError = function () {
                    $scope.new.duplicate = false;
                };

                $scope.save = function () {
                    metCategories.create($scope.new, function (response) {
                        if ($scope.new.parentCategoryId) {
                            _.forEach($scope.categories, function (category) {
                                if (category.categoryId === $scope.new.parentCategoryId) {
                                    category.childCategories.push(response);
                                }
                            });
                        } else {
                            $scope.categories.push(response);
                        }

                        $scope.cancelAdd();
                        $scope.orderBy();
                        metNotify.success(messages.categoryHasBeenAdded.value);
                    }, function (error) {
                        _.forEach($scope.categories, function (category) {
                            if (metValidate.compareStrings($scope.new.categoryName, category.categoryName, true, true)) {
                                $scope.new.duplicate = true;
                            }
                        });

                        $scope.new.valid = false;
                        $scope.new.error = error.data.message;
                    });
                };

                $scope.update = function (category) {
                    metCategories.update(category, function () {
                        $scope.original = null;
                        category.editing = false;
                        $scope.orderBy();
                        metNotify.success(messages.categoryHasBeenSaved.value);
                    }, function (error) {
                        category.valid = false;
                        category.error = error.data.message;
                    });
                };

                $scope.tabIndex = function (row, column) {
                    return ((row + 1) * 3) + column;
                }

                var messages = {
                    categoryHasBeenDeleted: metLocalize('messages', 'categoryHasBeenDeleted'),
                    categoryHasBeenSaved: metLocalize('messages', 'categoryHasBeenSaved'),
                    categoryHasBeenAdded: metLocalize('messages', 'categoryHasBeenAdded')
                }

                // INIT
                metCategories.getAll(null, function (data) {
                    $scope.categories = data.items;
                    $scope.orderBy();

                    if ($scope.selected) {
                        for (var i = 0; i < data.items.length; ++i) {
                            var item = data.items[i];
                            if (item.categoryId == $scope.selected) {
                                $scope.edit(item);
                                break;
                            }
                        }
                        $scope.selected = null;
                    }

                    $scope.loading = false;
                }, function (error) {
                    // TODO: handle  
                    $scope.loading = false;
                });
            }]);
}());

(function () {
    'use strict';

    var oneKeyApp = angular.module('oneKeyApp');
    oneKeyApp.controller('categoriesAssignController', [
        '$scope', '$timeout', '$modalInstance', '$log',
        'localize', 'focus', 'inventory', 'categories',
        'userItemIds', 'knownCategories', 'allItems', 'groupIds', 'groupType', 'searchFilters',
        function ($scope, $timeout, $modalInstance, $log,
            metLocalize, metFocus, metInventory, metCategories,
            userItemIds, knownCategories, allItems, groupIds, groupType, searchFilters) {

            $scope.userItemIds = userItemIds;
            $scope.categories = knownCategories;
            $scope.parentCategories = [];
            $scope.allItems = allItems;
            $scope.addMode = false;
            $scope.category = {};
            $scope.saving = false;
            $scope.editValid = true;
            $scope.addValid = true;

            $scope.messages = {
                editCategory: metLocalize('titles', 'editCategory'),
                cancel: metLocalize('commands', 'cancel'),
                save: metLocalize('commands', 'save'),
                category: metLocalize('fieldNames', 'categoryId'),
                categoryTitle: metLocalize('fieldNames', 'categoryName'),
                pleaseSelectCategory: metLocalize('messages', 'pleaseSelectCategory'),
                parentCategoryTitle: metLocalize('fieldNames', 'parentCategoryName'),
                select: metLocalize('fieldNames', 'select'),
                addNew: metLocalize('titles', 'addNew')
            };

            metCategories.getAll(
            {
                includeUncategorized: false
            },
            function (data) {
                _.forEach(data.items, function (category) {
                    $scope.parentCategories.push(category);
                });
            });

            $scope.edit = function() {
                if (!$scope.selectedCategory) {
                    onEditError($scope.messages.pleaseSelectCategory.value);
                    return;
                }

                // send no item id's if allItems is set to true (to make a smaller/faster request)
                var userItemIds = allItems ? [] : $scope.userItemIds;
                
                $scope.saving = true;
                metInventory.bulkUpdate({
                    userItemIds: $scope.userItemIds,
                    userCategoryId: $scope.selectedCategory.categoryId,
                    updateAllUserItems: allItems,
                    groupIds: groupIds,
                    groupType: groupType,
                    filters: searchFilters,

                }, function (result) {
                    if (!result.isValid) {
                        onEditError(result.message);
                    } else {
                        $modalInstance.close();
                    }
                }, function(error) {
                    onEditError(error.data.message);
                });
            };

            var onEditError = function(message) {
                $scope.saving = false;
                $scope.editValid = false;
                $scope.editError = message;
            };

            $scope.add = function () {
                $scope.saving = true;
                if ($scope.category.parentCategory) {
                    $scope.category.parentCategoryId = $scope.category.parentCategory.categoryId;
                }

                metCategories.create($scope.category, function (newCategory) {
                    metInventory.bulkUpdate({
                        userItemIds: $scope.userItemIds,
                        userCategoryId: newCategory.categoryId,
                        updateAllUserItems: allItems,
                        groupIds: groupIds,
                        groupType: groupType,
                        filters: searchFilters,
                    }, function(result) {
                        if (!result.isValid) {
                            onAddError(result.message);
                        } else {
                            $modalInstance.close();
                        }
                    }, function(error) {
                        onAddError(error.data.message);
                    });
                }, function (error) {
                    onAddError(error.data.message);
                });
            };

            var onAddError = function(message) {
                $scope.saving = false;
                $scope.addValid = false;
                $scope.addError = message;
            };

            $scope.cancel = function() {
                $modalInstance.dismiss('cancel');
            };

            $scope.toggleMode = function () {
                $scope.addMode = true;
            };
        }
    ]);
}());

