define([ 'plugins/router', 'durandal/app', 'durandal/system', 'knockout', 'services/datacontext', 'services/logger', 'services/breeze.knockout.select2'], function (router, app, system, ko, datacontext, logger) {
    var isDeleting = ko.observable(false),
        isSaving = ko.observable(false),
        isDeleted = ko.observable(false),
        oil = ko.observable(),
        tags = ko.observableArray([]),

        editing = ko.observable(false),
        isNew = ko.observable(0),

        activate = function (id) {
            initLookups();
            return id == 0 ? oil(datacontext.createOil()) : datacontext.getOilById(id, oil);
        },
        initLookups = function () {
            // todo: Lookup tags
            tags(datacontext.lookups.tags);
        },
        cancel = function () {
            datacontext.cancelChanges();
        },
        goBack = function () {
            router.navigateBack();
        },
        hasChanges = ko.computed(function () {
            return datacontext.hasChanges();
        }),
        canSave = ko.computed(function () {
            return hasChanges() && !isSaving();
        }),
        save = function () {
            isSaving(true);
            return datacontext.saveChanges().fin(complete);
            function complete() {
                isSaving(false);
                router.navigate('#/oil/' + oil().id());
            }
        },
        saveClose = function () {
            save().then(success).fail(failed);

            function success() {
                router.navigate('#/oils');
            }

            function failed(error) {
                var errorMsg = 'Error: ' + error.message;
                logger.logError(errorMsg, error, system.getModuleId(vm), true);
            }
        },
        deleteOil = function () {
            isDeleting(true); // prevent leaving during delete workflow
            var msg = 'Delete oil "' + oil().name() + '" ?';
            return app.showMessage(msg, 'Confirm Delete', ['Yes', 'No'])
                .then(confirmDelete);

            function confirmDelete(selectedOption) {
                if (selectedOption === 'Yes') {
                    // mark for deletion, then save
                    oil().entityAspect.setDeleted();
                    save().then(success).fail(failed);
                } else {
                    isDeleting(false);
                }

                function success() {
                    isDeleted(true); // to navigate away now
                    isDeleting(false); // to navigate away now
                    router.navigate('#/oils');
                }

                function failed(error) {
                    isDeleting(false);
                    cancel();
                    var errorMsg = 'Error: ' + error.message;
                    logger.logError(errorMsg, error, system.getModuleId(vm), true);
                }
            }
        },
        canDeactivate = function () {
            if (isDeleting()) {
                return false;
            } // Prevent leaving

            if (isDeleted()) {
                return true;
            } // Prevent leaving

//            if (hasChanges()) {
//                var name = 'Do you want to leave "' + oil().name() + '" ?';
//                var msg = 'Navigate away and cancel your changes?';
//                return app.showMessage(name, msg, ['Yes', 'No'])
//                    .then(confirm);
//            }

            return true;

            function confirm(selectedOption) {
                if (selectedOption === 'Yes') {
                    cancel();
                }
                return selectedOption;
            }
        },

        allTags = function (query) {
            var all = [];
            var filtered;

            filtered = ko.utils.arrayFilter(tags(), function (item) {
                return item.name().toLowerCase().indexOf(query.term) !== -1;
            });

            ko.utils.arrayForEach(filtered || [], function (tag) {
                all.push({id: tag.id(), text: tag.name(), locked: false});
            });

            query.callback({results: all});
        }
        ;


    var vm = {
        activate: activate,
        oil: oil,
        cancel: cancel,
        canSave: canSave,
        canDeactivate: canDeactivate,
        deleteOil: deleteOil,
        goBack: goBack,
        hasChanges: hasChanges,
        save: save,
        saveClose: saveClose,
        title: 'Edit a Oil',
        editing: editing,
        isNew: isNew,
        allTags: allTags
    };

    return vm;
});

