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

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

        activate = function (id) {
            initLookups();
            return id == 0 ? health(datacontext.createHealth()) : datacontext.getHealthById(id, health);
        },
        initLookups = function () {
            // todo: Lookup tags
            tags(datacontext.lookups.tags);

            var _oils = ko.observableArray([]);
            _oils.subscribe(function(items){
                oils([]);
                ko.utils.arrayForEach(items, function(oil){
                    oils.push({id: oil.id(), text: oil.name()});
                });
            });

            datacontext.getOilPartials(_oils);

        },
        cancel = function () {
//            debugger;
//            editingDisease().entityAspect.rejectChanges();
            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('#/health/' + health().id());
            }
        },
        saveClose = function () {
            save().then(success).fail(failed);

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

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

            function confirmDelete(selectedOption) {
                if (selectedOption === 'Yes') {
                    // mark for deletion, then save
                    health().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('#/healths');
                }

                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 "' + health().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;
            }
        },

        editDisease = function (data) {
            editing(true);
            editingDisease(data);

        },
        addDisease = function () {
            var data = datacontext.createDisease(health());

            editingDisease(data);
            isNew(1);
        },
        addDirection = function (data) {
            datacontext.createDirection(data);
        },
        saveDisease = function () {
            isNew(0);
            editing(false);
            editingDisease(null);
            save();
        },
        cancelDisease = function () {
//            debugger;
            if(editingDisease()){
                editingDisease().entityAspect.rejectChanges();
                editingDisease(null);
            }
        },
        removeDisease = function (data) {
            app.showMessage('Are you sure you want to delete = ' + data.name() + '?', 'Delete Confirmation', ['Yes', 'No']).then(function (dialogResult) {
                if (dialogResult === "Yes") {
                    editingDisease.entityAspect.setDeleted();
                    editingDisease(null);
                }
            });

        },
        removeDirection = function (data) {
            app.showMessage('Are you sure you want to delete?', 'Delete Confirmation', ['Yes', 'No']).then(function (dialogResult) {
                if (dialogResult === "Yes") {
                    data.entityAspect.setDeleted();
                }
            });

        },
        editingDisease = ko.observable(null),
        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,
        health: health,
        cancel: cancel,
        canSave: canSave,
        canDeactivate: canDeactivate,
        deleteHealth: deleteHealth,
        goBack: goBack,
        hasChanges: hasChanges,
        save: save,
        saveClose: saveClose,
        editing: editing,
        isNew: isNew,
        editDisease: editDisease,
        addDisease: addDisease,
        addDirection: addDirection,
        saveDisease: saveDisease,
        cancelDisease: cancelDisease,
        removeDisease: removeDisease,
        removeDirection: removeDirection,
        editingDisease: editingDisease,
        allTags: allTags,
        oils: oils
    };

    return vm;


    var ctor = {
        editing: ko.observable(false),
        isNew: ko.observable(0),
        health: ko.observable(null),
        activate: function (id) {
            dataservice.findHealth(id).then(querySuccess).fail(queryFail);
        },
        save: function () {
            dataservice.saveChanges().then(goToEditView).fail(failed);
        },
        saveClose: function () {
            dataservice.saveChanges().then(goToListView).fail(failed);
        },
        cancel: function () {
            router.navigate('#/healths');
        },
        editDisease: function (data) {
            ctor.editing(true);
            ctor.editingDisease(data);

        },
        addDisease: function () {
            var data = dataservice.createDisease({name: '', description: '', health: ctor.health(), tags: []});

            ctor.editingDisease(data);
            ctor.isNew(1);
        },
        saveDisease: function () {
            ctor.isNew(0);
            ctor.editing(false);
            ctor.editingDisease(null);
            ctor.save();
        },
        cancelDisease: function () {
            if (ctor.isNew()) {
                $.each(ctor.editingDisease().tags(), function (index, tag_map) {
                    dataservice.remove(tag_map);
                });

                dataservice.removeDisease(ctor.editingDisease());

                ctor.isNew(0);
            }
            ctor.editingDisease(null);
        },
        removeDisease: function (data) {
            app.showMessage('Are you sure you want to delete: ' + data.name() + '?', 'Delete Confirmation', ['Yes', 'No']).then(function (dialogResult) {
                if (dialogResult === "Yes") {
                    dataservice.removeDisease(data);
                    ctor.editingDisease(null);
                    ctor.save();
                }
            });

        },
        editingDisease: ko.observable(null),
        allTags: function (query) {
            console.log(query)
            dataservice.getTags(query.term).then(function (data) {
                var tags = [];
                ko.utils.arrayForEach(data.results, function (tag) {
                    tags.push({id: tag.id(), text: tag.name(), locked: false});
                });
                query.callback({results: tags});
            });

        }

    };


    function goToListView(result) {
        logger.log('Save success.', result, 'health', true);
        router.navigate('#/healths');
    }

    function goToEditView(result) {
        logger.log('Save success.', result, 'health', true);
        router.navigate('#/health/' + ctor.health().id());
    }

    function failed(error) {
        logger.logError('Health save fail.', error, 'health', true);
    }

    function querySuccess(data) {
        var health = data.results[0];

        if (!health) {
            health = dataservice.createHealth({name: '', description: '', diseases: []});
        }
        ctor.health(health);

        logger.log('Load success.', data, 'health', true);
    }

    function queryFail(error) {
        logger.logError('Load fail.', error, 'health', true);
    }

    return ctor;
});