define([
    // Dojo
    "dojo", "dojo/_base/declare", "dojo/on", "dojo/when", "dijit/registry",
    
    // dijit
    "dijit/layout/_LayoutWidget", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin", "dijit/form/CheckBox",
    
    //epi
    "epi/_Module", "epi/dependency",
    
    // epi shell
    "epi/shell/form/Field", "epi/shell/form/formFieldRegistry", "epi/shell/widget/dialog/Dialog", "epi/shell/DialogService",
    
    // epi cms
    "epi-cms/_ContentContextMixin", "epi-cms/contentediting/ContentViewModel"
], function (
    // Dojo
    dojo, declare, on, when, dijitRegistry,
    
    // dijit
    _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, CheckBox,
            
    // epi
    _Module, dependency,
    
    // epi shell
    Field, formFieldRegistry, Dialog, dialogService,
    
    // epi cms
    _ContentContextMixin, ContentViewModel
) {
        var factory = formFieldRegistry.get(formFieldRegistry.type.field, "");
             
        function updateProperties(propertyName, value, commonDrafts) {
            return new Promise((resolve) => {
                var countUpdatedContent = 0;
                commonDrafts.forEach((commonDraft) => {
                    var model = new ContentViewModel({
                        contentLink: commonDraft.contentLink,
                        enableAutoSave: false,
                        isInQuickEditMode: true
                    });
                    model.onContentLinkChange = function () { };
                    model.reload(true).then(function () {
                        model.setProperty(propertyName, value);
                        model.save().then(function () {
                            countUpdatedContent++;
                            if (commonDrafts.length === countUpdatedContent) {
                                resolve();
                            }
                        });
                    });
                });
            });
        }
        
        var DialogContent = declare([_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
            templateString: "<div></div>",

            addSelection: function (language) {
                var labelElement = document.createElement("label");
                labelElement.classList.add("dijitVisible");
                this.domNode.appendChild(labelElement);
                var checkboxElement = document.createElement("span");
                labelElement.appendChild(checkboxElement);
                var textElement = document.createElement("span");
                labelElement.appendChild(textElement);
                textElement.innerHTML = language;

                var self = this;
                var checkbox = new CheckBox({
                    name: "checkBox-selection-" + language,
                    value: language,
                    checked: false,
                    onChange: (checked) => {
                        self.onSelectionChanged(language, checked);
                    }
                }, checkboxElement);
                this.own(checkbox);                
            },
            
            onSelectionChanged: function() {}
        });
        
        function selectVersions(widget, commonDrafts) {
            var customWidget = new DialogContent();
            
            var selectedLanguages = {};
            
            function getSelectedLanguages() {
                return Object.keys(selectedLanguages).filter(x => selectedLanguages[x]);
            }
            
            return new Promise((resolve, reject) => {
                var resolved = false;
                var dialog = new Dialog({
                    title: "Copy to language branches",
                    dialogClass: "epi-dialog-landscape",
                    content: customWidget,
                    onExecute: function () {
                        resolve(getSelectedLanguages());
                    },
                    onHide: function () {
                        if (!resolved) {
                            reject();
                        }
                    }
                });

                widget.own(dialog);
                dialog.own(customWidget);

                commonDrafts.forEach((commonDraft) => {
                    customWidget.addSelection(commonDraft.language);
                });
                dialog.own(on(customWidget, "selectionChanged", (language, checked) => {
                    selectedLanguages[language] = checked;
                    dialog.definitionConsumer.setItemProperty(dialog._okButtonName, "disabled", getSelectedLanguages().length === 0);
                    
                }));

                dialog.startup();
                dialog.show();
                dialog.definitionConsumer.setItemProperty(dialog._okButtonName, "disabled", true);
            });
        }
        
        function copyPropertyValue(widget, parent, getCurrentContent) {
            when(getCurrentContent(), function (context) {
                var contentVersionStore = dependency.resolve("epi.storeregistry").get("epi.cms.contentversion");
                contentVersionStore.query({ contentLink: context.contentLink }).then(function(versions) {
                    var commonDrafts = versions.filter(x => x.isCommonDraft && x.language !== context.currentLanguageBranch.languageId);
                    selectVersions(widget, commonDrafts).then((selectedLanguages) => {
                        commonDrafts = commonDrafts.filter(x => selectedLanguages.indexOf(x.language) !== -1);
                        updateProperties(widget.name, widget.get("value"), commonDrafts).then(() => {
                            dialogService.alert({
                                title: "Info",
                                description: "Language versions has been updated"
                            });
                        });
                    });
                });
            });
        }
        
        function getPropertyWidgetWrapper(widget, parent, getCurrentContent, getCurrentContext) {
            var wrapper = factory(widget, parent);
            if (!widget.params.isLanguageSpecific) {
                return wrapper;
            }

            var languageNode = document.createElement("span");
            languageNode.classList.add("dijitInline", "dijitReset", "dijitIcon", "epi-iconCopy", "epi-cursor--pointer");
            languageNode.title = "Copy to other language versions";
            wrapper.labelNode.appendChild(languageNode);
            when(getCurrentContext()).then(function (currentContext) {
                if (currentContext && currentContext.currentMode === "create" || currentContext.currentMode === "translate") {
                    languageNode.classList.add("dijitHidden");
                }
            });
            
            wrapper.own(on(languageNode, "click", function() { copyPropertyValue(widget, parent, getCurrentContent); }));
            return wrapper;
        }
        
        return declare([_Module, _ContentContextMixin], {
            initialize: function () {
                this.inherited(arguments);

                var self = this;
                var customFactory = {
                    type: formFieldRegistry.type.field,
                    hint: "",
                    factory: function (widget, parent) {
                        return getPropertyWidgetWrapper(widget, parent, self.getCurrentContent.bind(self), self.getCurrentContext.bind(self));
                    }
                };
                
                formFieldRegistry.add(customFactory);
            }
        });
    });