/**
 * Created by Tony on 2017/4/28.
 */
var rationGLJOprObj = {
    processDecimal: -6,
    sheet: null,
    currentRationItem: null,
    distTypeTree: null,
    activeCell: null,
    tempCacheArr: [],//被更新的工料机，若更新的工料机不存在，则恢复
    cache: {},
    setting: {
        header:[
            {headerName:"编码",headerWidth:80,dataCode:"code", dataType: "String", formatter: "@"},
            {headerName:"名称",headerWidth:160,dataCode:"name", dataType: "String"},
            {headerName:"规格型号",headerWidth:100,dataCode:"specs", dataType: "String"},
            {headerName:"单位",headerWidth:60,dataCode:"unit", dataType: "String", hAlign: "center", vAlign: "center"},
            {headerName:"定额价",headerWidth:80, dataCode:"basePrice", dataType: "Number", formatter:"0.00",  precision: 2},
            {headerName:"定额消耗",headerWidth:80, dataCode:"consumeAmt", dataType: "Number", formatter: "0.000", precision: 3},
            {headerName:"类型",headerWidth:70,dataCode:"gljType", dataType: "String", hAlign: "center", vAlign: "center"},
            {headerName:"配合比",headerWidth:70,dataCode:"proportion", dataType: "Number", formatter:"0.00",  precision: 2}
        ],
        view:{
            comboBox:[],
            lockColumns:[1,2,3,4,6]
        }
    },
    getDistTypeTree: function (gljDistType) {
        let distType;
        let distTypeTree = {
            prefix : 'gljDistType',
            distTypes: {},
            comboDatas: [],
            distTypesArr: []
        };
        gljDistType.forEach(function (typeData) {
            let typeObj = {
                data: typeData,
                children: [],
                parent: null
            }
            distTypeTree.distTypes[distTypeTree.prefix + typeData.ID] = typeObj;
            distTypeTree.distTypesArr.push(typeObj);
        });
        gljDistType.forEach(function (typeData) {
            distType = distTypeTree.distTypes[distTypeTree.prefix + typeData.ID];
            let parent = distTypeTree.distTypes[distTypeTree.prefix + typeData.ParentID];
            if(parent){
                distType.parent = parent;
                parent.children.push(distType);
            }
        });
        distTypeTree.distTypesArr.forEach(function (distTypeObj) {
            if(distTypeObj.children.length === 0 && distTypeObj.data.fullName !== '普通机械' &&distTypeObj.data.fullName !== '机械组成物'
                && distTypeObj.data.fullName !== '机上人工'){
                distTypeTree.comboDatas.push({text: distTypeObj.data.fullName, value: distTypeObj.data.ID});
            }
            if(distTypeObj.data.fullName === '机械'){
                distTypeTree.comboDatas.push({text: distTypeObj.data.fullName, value: distTypeObj.data.ID});
            }
        });
        return distTypeTree;
    },
    initGljDistType: function (gljDistTypeList) {
        this.distTypeTree = this.getDistTypeTree(gljDistTypeList);

    },
    buildSheet: function(sheet) {
        this.sheet = sheet;
        sheetCommonObj.initSheet(this.sheet, this.setting, 30);
        this.onContextmenuOpr();
        this.bindRationGljDelOpr();
        this.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasting, this.onClipboardPasting);
        this.sheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, this.onClipboardPasted);
        this.sheet.bind(GC.Spread.Sheets.Events.EditStarting, this.onEditStarting);
        this.sheet.bind(GC.Spread.Sheets.Events.EditEnded, this.onCellEditEnd);
    },
    bindRationGljDelOpr: function () {
        if (locked) {
            return;
        }
        const me = rationGLJOprObj;
        const spreadBook = me.sheet.getParent();
        spreadBook.commandManager().register('rationGljDelete', function () {
            const cacheSection = me.cache["_GLJ_" + me.currentRationItem.ID];
            const sels = me.sheet.getSelections();
            if (!cacheSection || !sels.length) {
                return;
            }
            let isUpdate = false;
            for (const sel of sels) {
                const deleteRow = sel.colCount === me.setting.header.length && sel.row < cacheSection.length;
                if (deleteRow) {
                    isUpdate = true;
                    cacheSection.splice(sel.row, sel.rowCount);
                }
            }
            if (isUpdate) {
                me.updateRationItem(function () {
                    me.sheet.getParent().focus(true);
                });
                sheetCommonObj.cleanData(me.sheet, me.setting, -1);
                me.showGljItems(me.currentRationItem.ID);
            }
        });
        spreadBook.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
        spreadBook.commandManager().setShortcutKey('rationGljDelete', GC.Spread.Commands.Key.del, false, false, false, false);
    },
    onClipboardPasting: function(sender, args) {
        const me = rationGLJOprObj;
        const rationCache = rationOprObj.getCache();
        const rationRow = rationOprObj.workBook.getSheet(0).getSelections()[0].row;
        me.currentRationItem = rationRow < rationCache.length ? rationCache[rationRow] : null;
        if(me.currentRationItem && typeof me.cache["_GLJ_" + me.currentRationItem.ID] === 'undefined'){
            me.cache["_GLJ_" + me.currentRationItem.ID] = [];
        }
        const field = me.setting.header[args.cellRange.col].dataCode;
        const canPasteFields = ['code', 'consumeAmt', 'proportion'];
        if (!me.currentRationItem || !(canPasteFields.includes(field) && args.cellRange.colCount === 1)) {
            args.cancel = true;
        }
    },
    onClipboardPasted: function(e, info) {
        const me = rationGLJOprObj;
        me.tempCacheArr = [];
        const gljCache = me.cache["_GLJ_" + me.currentRationItem.ID];
        const field = me.setting.header[info.cellRange.col].dataCode;
        if (field === 'code') {
            const pasteList = sheetCommonObj.analyzePasteData({header:[{dataCode: "code"}] }, info);
            const codes = [];
            for (let i = 0; i < pasteList.length; i++) {
                let rowIdx = info.cellRange.row + i;
                if(rowIdx < gljCache.length){//更新
                    me.tempCacheArr.push({org: gljCache[rowIdx], newCode: pasteList[i].code});
                    gljCache.splice(rowIdx--, 1);
                }
                codes.push(pasteList[i].code);
            }
            me.addGljItems(codes, pageOprObj.gljLibId, info.cellRange);
        } else if (gljCache && info.cellRange.row < gljCache.length) {
            const pasteList = sheetCommonObj.analyzePasteData(me.setting, info);
            const maxCount = info.cellRange.row + info.cellRange.rowCount -1 > gljCache.length -1 ?
                gljCache.length - info.cellRange.row : info.cellRange.rowCount;
            const precision = me.setting.header[info.cellRange.col].precision;
            for (let i = 0; i < maxCount; i++) {
                let roundCons = scMathUtil.roundTo(pasteList[i][field], -precision);
                gljCache[info.cellRange.row + i][field] = roundCons;
            }
            me.updateRationItem(function () {
                me.sheet.getParent().focus(true);
            });
            if (info.cellRange.row + info.cellRange.rowCount -1 >= gljCache.length -1) {
                me.sheet.suspendPaint();
                for(let rowIdx = gljCache.length; rowIdx <= info.cellRange.row + info.cellRange.rowCount -1; rowIdx++){
                    me.sheet.setValue(rowIdx, info.cellRange.col, '');
                }
                me.sheet.resumePaint();
            }
        } else if (info.cellRange.row >= gljCache.length) {
            me.sheet.suspendPaint();
            for(let rowIdx = info.cellRange.row; rowIdx <= info.cellRange.row + info.cellRange.rowCount -1; rowIdx ++){
                me.sheet.setValue(rowIdx, info.cellRange.col, '');
            }
            me.sheet.resumePaint();
        }
    },
    onEditStarting: function (sender, args) {
        const me = rationGLJOprObj;
        const rationSection = rationOprObj.getCache();
        const rationRow = rationOprObj.workBook.getSheet(0).getSelections()[0].row;
        me.currentRationItem = rationRow < rationSection.length ? rationSection[rationRow] : null;
        if(me.currentRationItem && typeof me.cache["_GLJ_" + me.currentRationItem.ID] === 'undefined'){
            me.cache["_GLJ_" + me.currentRationItem.ID] = [];
        }
        const isEmptyRation = !me.currentRationItem;
        if (isEmptyRation) {
            return args.cancel = true;
        }
        const canEditFields = ['code', 'consumeAmt', 'proportion'];
        const emptyGLJCanEditFields = ['code'];
        const isEmptyGLJ = args.row >= me.cache["_GLJ_" + me.currentRationItem.ID].length;
        const editingField = me.setting.header[args.col].dataCode;
        const isValidField =  isEmptyGLJ && emptyGLJCanEditFields.includes(editingField) || !isEmptyGLJ && canEditFields.includes(editingField);
        if (!isValidField) {
            return args.cancel = true;
        }
    },
    onCellEditEnd: function(sender, args) {
        const me = rationGLJOprObj;
        me.tempCacheArr = [];
        const cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
        const editingField = me.setting.header[args.col].dataCode;
        const trimText = args.editingText ? args.editingText.trim() : '';
        const curGLJ = cacheArr[args.row];
        const originText = curGLJ  && !commonUtil.isEmptyVal(curGLJ[editingField]) ? String(curGLJ[editingField]) : '';
        if (!trimText || trimText === originText) {
            args.sheet.setValue(args.row, args.col, originText);
            return;
        }
        if (editingField === 'code') {
            const matchGLJ = cacheArr.find((item, index) => item.code === trimText && index !== args.row);
            if (matchGLJ) {
                alert("该人材机已存在！");
                args.sheet.setValue(args.row, args.col, originText);
                return;
            }
            if (args.row < cacheArr.length) { // 替换人材机
                me.tempCacheArr.push({org: cacheArr[args.row], newCode: args.editingText.toString().trim()});
                cacheArr.splice(args.row, 1);
            }
            me.addGljItems([trimText], pageOprObj.gljLibId)
        } else {
            const fieldName = me.setting.header[args.col].headerName;
            if (isNaN(trimText)) {
                $('#alertText').text(`${fieldName}只能输入数值。`);
                $('#alertModal').modal('show');
                args.sheet.setValue(args.row, args.col, originText);
            } else {
                const precision = me.setting.header[args.col].precision;
                const roundText = scMathUtil.roundTo(trimText, -precision);
                curGLJ[editingField] = roundText;
                me.updateRationItem(function () {
                    me.sheet.getParent().focus(true);
                });
            }
        }
    },
    onContextmenuOpr: function () {//右键菜单
        let me = this;
        let raCoe = rationCoeOprObj;
        $.contextMenu({
            selector: '#rdSpread',
            build: function($triggerElement, e){
                //控制允许右键菜单在哪个位置出现
                let target = SheetDataHelper.safeRightClickSelection($triggerElement, e, me.sheet.getParent());
                let sheet = me.sheet;
                if(me.sheet.getParent().getActiveSheetIndex() === 0 && target.hitTestType === 3){//在表格内&& typeof target.row !== 'undefined' && typeof target.col !== 'undefined'
                    //rationGlj表
                    if(typeof target.row !== 'undefined'){
                        //控制按钮是否可用
                        sheet.setActiveCell(target.row, target.col);
                    }
                    return {
                        callback: function(){},
                        items: {
                            "add": {
                                name: "添加人材机",
                                disabled: function () {
                                    const inValidCell = !commonUtil.isDef(target.row) || !commonUtil.isDef(target.col);
                                    if (locked || inValidCell || !me.currentRationItem) {
                                        return true;
                                    }
                                    return false;
                                },
                                icon: "fa-plus",
                                callback: function (key, opt) {
                                    //默认radio所有工料机
                                    gljSelOprObj.initRadio();
                                    gljSelOprObj.gljCurTypeId = null;
                                    //默认点击树根节点
                                    if(gljSelOprObj.rootNode){
                                        gljSelOprObj.treeObj.selectNode(gljSelOprObj.rootNode);
                                        gljSelTreeOprObj.setting.callback.onClick(null, 'componentTree', gljSelOprObj.rootNode);
                                    }
                                    //弹出窗口
                                    $('#selGlj').modal('show');
                                }},
                            "delete": {
                                name: "删除人材机",
                                disabled: function () {
                                    const inValidCell = !commonUtil.isDef(target.row) || !commonUtil.isDef(target.col);
                                    const rationGlj =  me.cache['_GLJ_' + me.currentRationItem.ID];
                                    const inValidData = !rationGlj || target.row >= rationGlj.length;
                                    if (locked || inValidCell || !me.currentRationItem || inValidData) {
                                        return true;
                                    }
                                    return false;
                                },
                                icon: "fa-remove",
                                callback: function (key, opt) {
                                    const rationGlj =  me.cache['_GLJ_' + me.currentRationItem.ID];
                                    rationGlj.splice(target.row, 1);
                                    me.updateRationItem(function(){
                                        me.sheet.getParent().focus();
                                    });
                                    sheetCommonObj.cleanData(me.sheet, me.setting, -1);
                                    me.showGljItems(me.currentRationItem.ID);
                                }},
                        }
                    };
                }
                //rationCoe表
                else if(me.sheet.getParent().getActiveSheetIndex() === 2 && target.hitTestType === 3 && typeof target.row !== 'undefined' && typeof target.col !== 'undefined'){
                    let currentCache = raCoe.curRation && raCoe.isDef(raCoe.cache["_Coe_" + raCoe.curRation.ID])  ? raCoe.cache["_Coe_" + raCoe.curRation.ID] : [];
                    sheet.setActiveCell(target.row, target.col);
                    return {
                        callback: function(){},
                        items: {
                            "upMove": {
                                name: "上移",
                                disabled: function () {
                                    const inValidCell = !commonUtil.isDef(target.row) || !commonUtil.isDef(target.col);
                                    const inValidData = target.row >= currentCache.length || !raCoe.isDef(currentCache[target.row - 1]);
                                    return locked || inValidCell || inValidData
                                },
                                icon: "fa-arrow-up",
                                callback: function (key, opt) {
                                    raCoe.upMove(currentCache[target.row], currentCache[target.row - 1], {row: target.row - 1, col: target.col});
                                }
                            },
                            "downMove": {
                                name: "下移",
                                disabled: function () {
                                    const inValidCell = !commonUtil.isDef(target.row) || !commonUtil.isDef(target.col);
                                    const inValidData = target.row >= currentCache.length || !raCoe.isDef(currentCache[target.row + 1]);
                                    return locked || inValidCell || inValidData;
                                },
                                icon: "fa-arrow-down",
                                callback: function (key, opt) {
                                    raCoe.downMove(currentCache[target.row], currentCache[target.row + 1], {row: target.row + 1, col: target.col});
                                }
                            },
                            "ref": {
                                name: "添加到本节其他定额",
                                disabled: function () {
                                    const inValidCell = !commonUtil.isDef(target.row) || !commonUtil.isDef(target.col);
                                    const inValidData = target.row >= currentCache.length;
                                    return locked || inValidCell || inValidData;
                                },
                                icon: "fa-arrow-left",
                                callback: function (key, opt) {
                                    raCoe.updateSectionRation(rationOprObj.currentRations["_SEC_ID_" + rationOprObj.currentSectionId], currentCache[target.row], function (updateArr) {
                                        for(let i = 0, len = updateArr.length; i < len; i++){
                                            let ration = updateArr[i];
                                            let rationCoeList = updateArr[i].rationCoeList;
                                            let newNo = 1;
                                            for(let j = 0, jLen = rationCoeList.length; j < jLen; j++){
                                                if(rationCoeList[j].no >= newNo){
                                                    newNo = rationCoeList[j].no + 1;
                                                }
                                            }
                                            let theCache = raCoe.cache["_Coe_" + ration.ID];
                                            if(theCache !== undefined && theCache !== null){
                                                let newCoe = {};
                                                for(let attr in currentCache[target.row]){
                                                    newCoe[attr] = currentCache[target.row][attr];
                                                }
                                                newCoe.no = newNo;
                                                theCache.push(newCoe);
                                            }
                                        }
                                    });
                                }
                            }
                        }
                    };
                }
                else{
                    return false;
                }
            }
        });
    },
    getRecoveryArr: function (tempDelArr, newArr) {//获得更新的code不存在，恢复删除的被更新数据
        let rst = [];
        for(let i = 0, len = tempDelArr.length; i < len; i++){
            let isExist = false;
            for(let j = 0, jLen = newArr.length; j < jLen; j++){
                if(tempDelArr[i].newCode == newArr[j].code){
                    isExist = true;
                    break;
                }
            }
            if(!isExist){
                rst.push(tempDelArr[i].org);
            }
        }
        return rst;
    },
    addGljItems: function(codes, repId) {
        var me = this;
        $.ajax({
            type:"POST",
            url:"api/getGljItemsByCodes",
            data:{"gljCodes": JSON.stringify(codes), repId: repId},
            dataType:"json",
            cache:false,
            timeout:5000,
            success:function(result){
                if (result) {
                    if(result.data.length > 0){
                        if(priceProperties && priceProperties.length > 0){
                            let priceField = priceProperties[0].price.dataCode;
                            for(let glj of result.data){
                                glj.basePrice = glj.priceProperty && glj.priceProperty[priceField] ? glj.priceProperty[priceField] : 0;
                            }
                        }
                        sheetCommonObj.cleanData(me.sheet, me.setting, -1);
                        var rstArr = [], dummyR = {gljId: 0, consumeAmt:0},
                            newAddArr = [],
                            validGlj = [];
                        for (var i = 0; i < result.data.length; i++) {
                            dummyR.gljId = result.data[i].ID;
                            rstArr.push(me.createRationGljDisplayItem(dummyR, result.data[i]));
                        }
                        if (me.cache["_GLJ_" + me.currentRationItem.ID]) {
                            var cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
                            for (var i = 0; i < rstArr.length; i++) {
                                var hasDup = false;
                                for (var j = 0; j < cacheArr.length; j++) {
                                    if (cacheArr[j].gljId == rstArr[i].gljId) {
                                        hasDup = true;
                                        break;
                                    }
                                }
                                if (!hasDup) {
                                    newAddArr.push(rstArr[i]);
                                }
                            }
                            //新增的定额人材机，按照输入的编码排序
                            for (let code of codes) {
                                let fGlj = _.find(newAddArr, function (glj) {
                                    return glj.code === code;
                                });
                                if (fGlj) {
                                    validGlj.push(fGlj);
                                }
                            }
                            me.cache["_GLJ_" + me.currentRationItem.ID] = cacheArr.concat(validGlj);
                            let recoveryArr = me.getRecoveryArr(me.tempCacheArr, result.data);
                            if(recoveryArr.length > 0){
                                me.cache["_GLJ_" + me.currentRationItem.ID] = me.cache["_GLJ_" + me.currentRationItem.ID].concat(recoveryArr);
                            }
                        }
                        me.showGljItems(me.currentRationItem.ID);
                        if (validGlj.length > 0) {
                            me.updateRationItem(function () {
                                me.sheet.getParent().focus(true);
                            });
                        }
                    }
                    else{
                        let cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID]?  me.cache["_GLJ_" + me.currentRationItem.ID] : [];
                        let recoveryArr = me.getRecoveryArr(me.tempCacheArr, []);
                        if(recoveryArr.length > 0){
                            me.cache["_GLJ_" + me.currentRationItem.ID] = cacheArr.concat(recoveryArr);
                        }
                        //更新的工料机不存在
                        $('#alertModalBtn').click();
                        $('#alertText').text("人材机"+ codes + "不存在，请查找你所需要的人材机，或新增人材机");
                        $('#alertModalCls').click(function () {
                            me.showGljItems(me.currentRationItem.ID);
                        });
                        $('#alertModalCof').click(function () {
                            me.showGljItems(me.currentRationItem.ID);
                        })
                    }
                }
            },
            error:function(err){
                alert(err);
            }
        })
    },
    round(v, e){
        var t=1;
        for(;e>0;t*=10,e--);
        for(;e<0;t/=10,e++);
        return Math.round(v*t)/t;
    },
    rationCal: function () {
        let me = rationGLJOprObj;
        let rationBasePrc = 0;
        if(me.currentRationItem && me.cache['_GLJ_' + me.currentRationItem.ID]){
            let cacheArr = me.cache['_GLJ_' + me.currentRationItem.ID];
            cacheArr.forEach(function (gljData) {
                if(gljData.gljType && gljData.basePrice && gljData.consumeAmt){
                    rationBasePrc += gljData.basePrice * gljData.consumeAmt;
                }
            });
            rationBasePrc = scMathUtil.roundTo(rationBasePrc, 0);
        }
        return rationBasePrc;
    },
    updateRationItem: function(callback) {
        var me = this, updateArr = [];
        if (me.currentRationItem) {
            me.currentRationItem.rationGljList = me.buildRationItemGlj();
            //recalculate ration basePrice
            let price = me.rationCal();
            me.currentRationItem.basePrice = price;
            updateArr.push(me.currentRationItem);
            rationOprObj.mixUpdateRequest(updateArr, [], [], function () {
                if(callback) callback();
            });
        }
    },

    buildRationItemGlj: function(){
        var me = this, rst = [];
        if (me.currentRationItem && me.cache["_GLJ_" + me.currentRationItem.ID]) {
            var cacheArr = me.cache["_GLJ_" + me.currentRationItem.ID];
            for (var i = 0; i < cacheArr.length; i++) {
                rst.push({
                    gljId: cacheArr[i].gljId,
                    consumeAmt: cacheArr[i].consumeAmt,
                    proportion: cacheArr[i].proportion
                });
            }
        }
        return rst;
    },

    createRationGljDisplayItem: function(rItem, repGlj) {
        var rst = {};
        rst.gljId = rItem.gljId;
        rst.consumeAmt = rItem.consumeAmt;
        rst.proportion = rItem.proportion;
        rst.code = repGlj.code;
        rst.name = repGlj.name;
        rst.specs = repGlj.specs;
        rst.unit = repGlj.unit;
        rst.basePrice = repGlj.basePrice;
        rst.gljType = repGlj.gljType;
        return rst;
    },
    getGljItems: function(rationItem, callback) {
        var me = this, rationID = rationItem.ID, rationGljList = rationItem.rationGljList ? rationItem.rationGljList : [];
        me.currentRationItem = rationItem;
        if (me.cache["_GLJ_" + rationID]) {
            me.showGljItems(rationID);
        } else {
            var gljIds = [];
            for (var i = 0; i < rationGljList.length; i++) {
                gljIds.push(rationGljList[i].gljId);
            }
                $.ajax({
                    type:"POST",
                    url:"api/getGljItemsByIds",
                    data:{"gljIds": JSON.stringify(gljIds)},
                    dataType:"json",
                    cache:false,
                    timeout:5000,
                    success:function(result){
                        sheetCommonObj.cleanSheet(me.sheet, me.setting, -1);
                        if (result) {
                            if(priceProperties && priceProperties.length > 0){
                                let priceField = priceProperties[0].price.dataCode;
                                for(let glj of result.data){
                                    glj.basePrice = glj.priceProperty && glj.priceProperty[priceField] ? glj.priceProperty[priceField] : 0;
                                }
                            }
                            var cacheArr = [];
                            for (var j = 0; j < rationGljList.length; j++) {
                                for (var i = 0; i < result.data.length; i++) {
                                    if (rationGljList[j].gljId == result.data[i].ID) {
                                        cacheArr.push(me.createRationGljDisplayItem(rationGljList[j], result.data[i]));
                                        break;
                                    }
                                }
                            }
                            me.cache["_GLJ_" + rationID] = cacheArr;
                            me.showGljItems(rationID);
                        }
                        if(callback) callback();
                    },
                    error:function(err){
                        alert(err);
                    }
                })
        }
    },
    showGljItems: function(rationID) {
        var me = this;
        if (me.cache["_GLJ_" + rationID]) {
            sheetCommonObj.cleanData(me.sheet, me.setting, -1);
            sheetsOprObj.showData(me.sheet, me.setting, me.cache["_GLJ_" + rationID], me.distTypeTree);
        }
    }
}