/* global Bdf,History,$$ */

History.Fiche = {};

History.Fiche.CURRENT_COMPONENTARRAY = new Array();
History.Fiche.revisionCacheMap = new Map();

History.Fiche.init = function (historyId, args, callback) {
    Bdf.Ajax.loadUi(args.subsetName, function (ui) {
        $$(historyId, "diff").html(Bdf.render("history:fiche-diff", {
            historyId: historyId
        }));
        History.Fiche.CURRENT_COMPONENTARRAY = ui.componentArray;
        callback();
    });
};

History.Fiche.getRevisionRow = function (revisionName, args, callback) {
    History.Fiche.loadRevisions([revisionName], args, function (result) {
        let ficheRevision = result[0];
        let fieldKeyMap = new History.Fiche.FieldKeyMap();
        fieldKeyMap.scanRevision(ficheRevision);
        callback(Bdf.render("history:fiche-revision", {
            revisionName: revisionName,
            fieldArray: fieldKeyMap.toArray()
        }));
    });
};

History.Fiche.showDiff = function (historyId, args) {
    var history = $$.one(historyId); 
    var beforeRadio = $$.first(history, {_element: "input", _name: "before", _checked: true});
    var afterRadio = $$.first(history, {_element: "input", _name: "after", _checked: true});
    if ((!beforeRadio) || (!afterRadio)) {
        return;
    }
    var beforeName = beforeRadio.dataset.revisionName;
    var afterName = afterRadio.dataset.revisionName;
    var beforeIndex = beforeRadio.dataset.index;
    var afterIndex = afterRadio.dataset.index;
    if ((beforeName) && (afterName)) {
        History.Fiche.loadRevisions([beforeName, afterName], args, function(revisionArray) {
            _update(revisionArray[0], revisionArray[1]);
        });
    }
    
    function _update(beforeFiche, afterFiche) {
        History.hide($$(historyId, "diff_content"), false);
        _updateDiffTitle("before-title", beforeIndex);
        _updateDiffTitle("after-title", afterIndex);
        var fieldKeyMap = new History.Fiche.FieldKeyMap();
        fieldKeyMap.scanDiff(beforeFiche, afterFiche);
        var diffArray = fieldKeyMap.toArray();
        $$(historyId, "diff_fieldlist").html(Bdf.render("history:fiche-diff-field", diffArray));
        var width = $$(historyId, "diff_fieldlist").width();
        for(let diff of diffArray) {
            let $diff = $$(diff.genId);
            $diff.mergely({
                width: width,
                height: diff.height,
                cmsettings: {
                    readOnly: true,
                    lineWrapping: true
                },
                license: 'gpl-separate-notice',
                sidebar: false
            });
            $diff.mergely('lhs', diff.beforeValue);
            $diff.mergely('rhs', diff.afterValue);
        }
    }
    
    function _updateDiffTitle(role, index) {
        var $tr = $$(history, {_element: "tr", index: index});
        var $diffTitle = $$(history, {role: role});

        __copy("revisionname");
        __copy("revisionuser");
        __copy("revisionday");
        __copy("revisiontime");

        function __copy(cellName) {
             $$($diffTitle, {cellcopy: cellName}).text($$($tr, {cell: cellName}).text());
        }
    }

};

History.Fiche.loadRevisions = function (nameArray, args, revisionCallback) {
    let result = new Array();
    let toLoadArray = new Array();
    for(let i = 0, len = nameArray.length; i < len; i++) {
        let name = nameArray[i];
        if (History.Fiche.revisionCacheMap.has(name)) {
            result.push(History.Fiche.revisionCacheMap.get(name));
        } else {
            result.push({});
            toLoadArray.push({name: name, index: i});
        }
    }
    if (toLoadArray.length === 0) {
        revisionCallback(result);
    } else {
        let param = "";
        for(let obj of toLoadArray) {
            if (param.length > 0) {
                param += ",";
            }
            param += obj.name;
        }
        Bdf.Ajax.loadFicheRevisions(args.subsetName, args.id, param, function (ficheRevisions) {
            for(let obj of toLoadArray) {
                let revision = ficheRevisions[obj.name];
                if (!revision) {
                    revision = {};
                }
                result[obj.index] = revision;
                History.Fiche.revisionCacheMap.set(obj.name, revision);
            }
            revisionCallback(result);
        });
    }
};


History.Fiche.getFieldKeyMap = function (fiche1, fiche2) {
    var fieldKeyMap = {};
    _scan(fiche1);
    if (fiche1) {
        _scan(fiche2);
    }
    return fieldKeyMap;
    
    function _scan(fiche) {
        for(let prop in fiche) {
            if (!fieldKeyMap.hasOwnProperty(prop)) {
                fieldKeyMap[prop] = {};
            }
        }
    }
    
};

History.Fiche.FieldKeyMap = function () {
    this.map = {};
};

History.Fiche.FieldKeyMap.prototype.scanRevision = function (ficheRevision) {
    for(let prop in ficheRevision) {
        this.map[prop] = {
            key: prop,
            value: ficheRevision[prop]
        };
    }
};

History.Fiche.FieldKeyMap.prototype.scanDiff = function (beforeFiche, afterFiche) {
    var tmpMap = {};
    _scan(beforeFiche);
    _scan(afterFiche);
    for(let key in tmpMap) {
        let beforeValue = _getValue(beforeFiche, key);
        let afterValue = _getValue(afterFiche, key);
        if (beforeValue !== afterValue) {
            this.map[key] = {
                genId: Bdf.generateId(),
                beforeValue: beforeValue,
                afterValue: afterValue,
                height: _getHeight(key)
            };
        }
    }
    
    
    function _scan(fiche) {
        for(let prop in fiche) {
            if (!tmpMap.hasOwnProperty(prop)) {
                tmpMap[prop] = {};
            }
        }
    }
    
    function _getValue(fiche, key) {
        if (fiche.hasOwnProperty(key)) {
            return fiche[key];
        } else {
            return " ";
        }
    }
    
    function _getHeight(key) {
        if (key.indexOf("section_") === 0) {
            return 500;
        } else {
            return 50;
        }
    }
};

History.Fiche.FieldKeyMap.prototype.toArray = function () {
    var array = new Array();
    var doneSet = {};
    for(let uiComponent of History.Fiche.CURRENT_COMPONENTARRAY) {
        let key = uiComponent.key;
        if (this.map.hasOwnProperty(key)) {
            let obj = this.map[key];
            obj.title = uiComponent.title;
            array.push(obj);
            doneSet[key] = true;
        }
    }
    for(let key in this.map) {
        if (!doneSet.hasOwnProperty(key)) {
            let obj = this.map[key];
            obj.title = key;
            array.push(obj);
        }
    }
    return array;
};