'use strict';

/**
 *
 *
 * @author Zhong
 * @date 2018/6/11
 * @version
 */

//清单指引/精灵获取完清单数据后的回调函数
let doAfterLoadGuidance = null;

const billsGuidance = (function () {
    const libSel = $('#stdBillsGuidanceLibSelect');
    //工作内容
    let stdBillsJobData = [];
    //项目特征
    let stdBillsFeatureData = [];
    const bills = {
        dom: $('#billsGuidance_bills'),
        workBook: null,
        cache: [],
        tree: null,
        controller: null,
        treeSetting: {
            emptyRowHeader: true,
            rowHeaderWidth: 15,
            treeCol: 0,
            emptyRows: 0,
            headRows: 1,
            headRowHeight: [40],
            defaultRowHeight: 21,
            cols: [{
                width: 140,
                readOnly: true,
                showHint: true,
                head: {
                    titleNames: ["项目编码"],
                    spanCols: [1],
                    spanRows: [1],
                    vAlign: [1],
                    hAlign: [1],
                    font: ["Arial"]
                },
                data: {
                    field: "code",
                    vAlign: 1,
                    hAlign: 0,
                    font: "Arial"
                }
            }, {
                width: 190,
                readOnly: true,
                head: {
                    titleNames: ["项目名称"],
                    spanCols: [1],
                    spanRows: [1],
                    vAlign: [1],
                    hAlign: [1],
                    font: ["Arial"]
                },
                data: {
                    field: "name",
                    vAlign: 1,
                    hAlign: 0,
                    font: "Arial"
                }
            },
               {
                width: 45,
                readOnly: true,
                 head: {
                     titleNames: ["计量单位"],
                     spanCols: [1],
                     spanRows: [1],
                     vAlign: [1],
                     hAlign: [1],
                     font: ["Arial"]
                 },
                 data: {
                     field: "unit",
                     vAlign: 1,
                     hAlign: 1,
                     font: "Arial"
                 }
            }
            ]
        },
        headers: [
            {name: '项目编码', dataCode: 'code', width: 140, vAlign: 'center', hAlign: 'left', formatter: '@'},
            {name: '项目名称', dataCode: 'name', width: 190, vAlign: 'center', hAlign: 'left', formatter: '@'},
            {name: '单位', dataCode: 'unit', width: 45, vAlign: 'center', hAlign: 'center', formatter: '@'},
        ],
        rowHeaderWidth:1,
        events: {
            CellDoubleClick: function (sender, args) {
                if(!bills.tree){
                    return;
                }
                let node = bills.tree.items[args.row];
                if(!node){
                    return;
                }
                if(node.children.length > 0){
                    node.setExpanded(!node.expanded);
                    //设置展开收起状态
                    sessionStorage.setItem('stdBillsGuidanceExpState', bills.tree.getExpState(bills.tree.items));
                    renderSheetFunc(args.sheet, function () {
                        let iCount = node.posterityCount(), i, child;
                        for (i = 0; i < iCount; i++) {
                            child = bills.tree.items[args.row + i + 1];
                            args.sheet.setRowVisible(args.row + i + 1, child.visible, args.sheetArea);
                        }
                        args.sheet.invalidateLayout();
                    });
                    args.sheet.repaint();
                } else if(!projectReadOnly) {
                    billsLibObj.insertBills(stdBillsJobData, stdBillsFeatureData, node);
                }
            }
        }
    };
    const options = {
        workBook: {
            tabStripVisible:  false,
            allowContextMenu: false,
            allowCopyPasteExcelStyle : false,
            allowExtendPasteRange: false,
            allowUserDragDrop : false,
            allowUserDragFill: false,
            scrollbarMaxAlign : true
        },
        sheet: {
            protectionOptions: {allowResizeRows: true, allowResizeColumns: true},
            clipBoardOptions: GC.Spread.Sheets.ClipboardPasteOptions.values
        }
    };
    //渲染时方法，停止渲染
    //@param {Object}sheet {Function}func @return {void}
    function renderSheetFunc(sheet, func){
        sheet.suspendEvent();
        sheet.suspendPaint();
        if(func){
            func();
        }
        sheet.resumeEvent();
        sheet.resumePaint();
    }
    //设置表选项
    //@param {Object}workBook {Object}opts @return {void}
    function setOptions (workBook, opts) {
        for(let opt in opts.workBook){
            workBook.options[opt] = opts.workBook[opt];
        }
        for(let opt in opts.sheet){
            workBook.getActiveSheet().options[opt] = opts.sheet[opt];
        }
    }
    //建表头
    //@param {Object}sheet {Array}headers @return {void}
    function buildHeader(sheet, headers) {
        let fuc = function () {
            sheet.setColumnCount(headers.length);
            sheet.setRowHeight(0, 30, GC.Spread.Sheets.SheetArea.colHeader);
            for(let i = 0, len = headers.length; i < len; i++){
                sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
                sheet.setColumnWidth(i, headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
                if(headers[i].formatter){
                    sheet.setFormatter(-1, i, headers[i].formatter);
                }
                sheet.getRange(-1, i, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[i]['hAlign']]);
                sheet.getRange(-1, i, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[i]['vAlign']]);
            }
        };
        renderSheetFunc(sheet, fuc);
    }
    //表监听事件
    //@param {Object}workBook @return {void}
    function bindEvent(workBook, events) {
        if(Object.keys(events).length === 0){
            return;
        }
        const Events = GC.Spread.Sheets.Events;
        for(let event in events){
            workBook.bind(Events[event], events[event]);
        }
    }
    //建表
    //@param {Object}module @return {void}
    function buildSheet(module) {
        if(!module.workBook){
            module.workBook = new GC.Spread.Sheets.Workbook(module.dom[0], {sheetCount: 1});
            sheetCommonObj.spreadDefaultStyle(module.workBook);
            let sheet = module.workBook.getActiveSheet();
            if(module === bills){
                //默认初始可控制焦点在清单表中
                sheet.options.rowHeaderVisible = false;
                module.workBook.focus();
                sheet.options.isProtected = true;
                sheet.name('stdBillsGuidance_bills');
                //设置悬浮提示
                TREE_SHEET_HELPER.initSetting(bills.dom[0], bills.treeSetting);
            }
            if(module.rowHeaderWidth) {
                sheet.setColumnWidth(0, module.rowHeaderWidth, GC.Spread.Sheets.SheetArea.rowHeader);
            }
            setOptions(module.workBook, options);
            buildHeader(module.workBook.getActiveSheet(), module.headers);
            bindEvent(module.workBook, module.events);
        }
    }
    //初始化各工作表
    //@param {Array}modules @return {void}
    function initWorkBooks(modules){
        for(let module of modules){
            buildSheet(module);
        }
    }
    //点击清单名称后面的问号，弹出补注窗口并设置当前节点（或xxx父节点）的补注
    //@param {Number}row(当前焦点行) @return {void}
    function initRechargeModal(row) {
        let node = bills.tree.items[row];
        while (node && !node.data.recharge){
            node = node.parent;
        }
        let recharge = node && node.data.recharge ? node.data.recharge : '无内容';
        node = bills.tree.items[row];
        while (node && !node.data.ruleText){
            node = node.parent;
        }
        let ruleText = node && node.data.ruleText ? node.data.ruleText : '无内容';

        $('#questionTab1').text('补注');
        $('#questionTab2').text('工程量计算规则');
        $('#questionContent1').html(recharge);
        $('#questionContent2').html(ruleText);
        $('#questionModal').modal('show');
    }
    //节点链上含有补注或工程量计算规则数据
    //@param {Number}row(行当前行) @return {Boolean}
    function hasRechargeRuleText(row) {
        let node = bills.tree.items[row];
        if (!node) {
            return false;
        }
        while (node) {
            if (node.data.recharge || node.data.ruleText) {
                return true;
            }
            node = node.parent;
        }
        return false;
    }
    //初始化并输出树
    //@param {Object}module {Object}sheet {Object}treeSetting {Array}datas
    function initTree(module, sheet, treeSetting, datas){
        module.tree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1, autoUpdate: true});
        module.controller = TREE_SHEET_CONTROLLER.createNew(module.tree, sheet, treeSetting, false);
        module.tree.loadDatas(datas);
        if(module === bills){
            initExpandStat();
        }
        module.controller.showTreeData();
        if(module === bills){
            module.workBook.getSheet(0).options.rowHeaderVisible = true;
            setBillsHint(bills.tree.items, stdBillsJobData, stdBillsFeatureData);
            renderSheetFunc(sheet, function () {
                for(let i = 0; i < bills.tree.items.length; i++){
                    sheet.setCellType(i, 1, TREE_SHEET_HELPER.getQuestionCellType(initRechargeModal, hasRechargeRuleText));
        }
            });
        }
    }
    //初始化清单的工作内容和项目特征
    //@param {Number}billsLibId {Function}callback @return {void}
    function initJobAndCharacter(billsLibId, callback){
        CommonAjax.post('/stdBillsEditor/getJobContent', {userId: userID, billsLibId: billsLibId}, function (datas) {
            stdBillsJobData = datas;
            CommonAjax.post('/stdBillsEditor/getItemCharacter', {userId: userID, billsLibId: billsLibId}, function (datas) {
                stdBillsFeatureData = datas;
                if(callback){
                    callback();
                }
            });
        });
    }
    //初始化清单展开收起状态
    //@return {void}
    function initExpandStat(){
        //读取展开收起状态
        let currentExpState = sessionStorage.getItem('stdBillsGuidanceExpState');
        if(currentExpState){
            bills.tree.setExpandedByState(bills.tree.items, currentExpState);
        }
        //非叶子节点默认收起
        else{
            bills.tree.setRootExpanded(bills.tree.roots, false);
        }
    }
    //设置tag以悬浮提示
    function setTagForHint(nodes){
        let sheet = bills.workBook.getActiveSheet();
        renderSheetFunc(sheet, function () {
            for(let node of nodes){
                sheet.setTag(node.serialNo(), 2, node.data.ruleText ? node.data.ruleText : '');
            }
        });
    }
    //根据编码定位至清单精灵库中
    //@param {String}code @return {void}
    function locateAtBills(code) {
        let nineCode = code.substring(0, 9);
        let items = bills.tree.items;
        let locateBills = _.find(items, function(item){
            return item.data.code === nineCode;
        });
        if(locateBills){
            expandSearchNodes([locateBills]);
            sessionStorage.setItem('stdBillsGuidanceExpState', bills.tree.getExpState(bills.tree.items));
        }
        let sheet = bills.workBook.getActiveSheet();
        let locateRow = locateBills ? locateBills.serialNo() : 0;
        sheet.setActiveCell(locateRow, 0);
        sheet.showRow(locateRow, GC.Spread.Sheets.VerticalPosition.center);
    }
    //清单设置悬浮提示信息
    //@param {Array}billsNodes(清单节点) {Array}jobs(总的工作内容数据) {Array}items(总的项目特征数据)
    function setBillsHint(billsNodes, jobs, items) {
        let jobsMapping = {},
            itemsMapping = {};
        for(let job of jobs){
            jobsMapping[job.id] = job;
        }
        for(let item of items){
            itemsMapping[item.id] = item;
        }
        let tagInfo = [];
        for(let billsNode of billsNodes){
            let hintArr = [];
            let billsItems = billsNode.data.items;
            if(billsItems.length > 0){
                //项目特征
                hintArr.push('项目特征:');
            }
            let itemCount = 1,
                jobCount = 1;
            for(let billsItem of billsItems){
                let itemData = itemsMapping[billsItem.id];
                if(itemData){
                    //特征值
                    let eigens = [];
                    for(let eigen of itemData.itemValue){
                        eigens.push(eigen.value);
                    }
                    eigens = eigens.join(';');
                    hintArr.push(`${itemCount}.${itemData.content}${eigens === '' ? '' : ': ' + eigens}`);
                    itemCount ++;
                }
            }
            //工作内容
            let billsJobs = billsNode.data.jobs;
            if(billsJobs.length > 0){
                hintArr.push('工作内容:');
            }
            for(let billsJob of billsJobs){
                let jobData = jobsMapping[billsJob.id];
                if(jobData){
                    hintArr.push(`${jobCount}.${jobData.content}`);
                    jobCount ++;
                }
            }
            if(hintArr.length > 0){
                tagInfo.push({row: billsNode.serialNo(), value: hintArr.join('\n')});
            }
        }
        let sheet = bills.workBook.getActiveSheet();
        renderSheetFunc(sheet, function () {
            for(let tagI of tagInfo){
                sheet.setTag(tagI.row, 0, tagI.value);
            }
        });
    }
    //初始选择清单指引库
    //@param {Number}libID @return {void}
    function libInitSel(libID,rcallback){
        //获取清单
        $.bootstrapLoading.start();
        CommonAjax.post('/billsGuidance/api/getLibWithBills', {libID: libID, isGuidanceLib: false}, function(rstData){
            initViews();
            let callback = function () {
                initTree(bills, bills.workBook.getActiveSheet(), bills.treeSetting, rstData.bills);
                if(doAfterLoadGuidance){
                    doAfterLoadGuidance();
                }
                if(rcallback)rcallback();
                $.bootstrapLoading.end();
            };
            //获取清单库中的工作内容和项目特征
            initJobAndCharacter(+libID, callback);
        }, function () {
            $.bootstrapLoading.end();
        });
    }
    //初始化清单指引库
    //@param {Array}libDats @return {void}
    function initLibs(libDatas,callback){
        libSel.empty();
        if(!libDatas){
            return;
        }
        let selectedLib = sessionStorage.getItem('stdBillsGuidance');
        for(let libData of libDatas){
            let opt = $('<option>').val(libData.id).text(libData.name);
            if(selectedLib && libData.id == selectedLib){
                opt.attr('selected', 'selected');
            }
            libSel.append(opt);
        }
        //初始默认选择
        libInitSel(libSel.select().val(),callback);
    }
    //初始化视图
    //@param {void} @return {void}
    function initViews(){
        //赋初始高度
        if($('#billsGuidance_bills').height() === 0 || $('#billsGuidance_items').height() === 0){
            let height = $(window).height()-$(".header").height()-$(".toolsbar").height()-$(".tools-bar-height-z").height();
            $('#billsGuidance_bills').height(height / 2);
            $('#billsGuidance_items').height(height / 2);
        }
        let modules = [bills];
        initWorkBooks(modules);

    }
    //展开至搜索出来点的节点
    //@param {Array}nodes @return {void}
    function expandSearchNodes(nodes){
        let billsSheet = bills.workBook.getActiveSheet();
        renderSheetFunc(billsSheet, function () {
            function expParentNode(node){
                if(node.parent){
                    if (!node.parent.expanded) {
                        node.parent.setExpanded(true);
                    }
                    expParentNode(node.parent);
                }
            }
            for(let node of nodes){
                expParentNode(node);
            }
            TREE_SHEET_HELPER.refreshTreeNodeData(bills.treeSetting, billsSheet, bills.tree.roots, true);
            TREE_SHEET_HELPER.refreshNodesVisible(bills.tree.roots, billsSheet, true);
        });
    }

    function initBillsLibs(callback){
        if(libSel.children().length === 0 && !$(this).hasClass('disabled')){
            initLibs(projectObj.project.projectInfo.engineeringInfo.bill_lib,callback);
        }else{
            callback();
        }
    }
    
    //各按钮监听事件
    //@return {void}
    function bindBtn(){
        //打开清单指引库
        $('#stdBillsGuidanceTab').click(function () {
            if(libSel.children().length === 0 && !$(this).hasClass('disabled')){
                initLibs(projectObj.project.projectInfo.engineeringInfo.bill_lib);
            }
        });
        //更改清单指引库
        $('#stdBillsGuidanceLibSelect').change(function () {
            //关闭搜索窗口
            $('#billsGuidanceSearchResult').hide();
            billsLibObj.clearHighLight(bills.workBook);
            libInitSel($(this).select().val());
            //记住选项
            sessionStorage.setItem('stdBillsGuidance', $(this).select().val());
            //清除展开收起状态sessionStorage
            sessionStorage.removeItem('stdBillsGuidanceExpState');
        });
        //搜索
        $('#stdBillsGuidanceSearch>div>button').click(function () {
            if(!bills.tree){
                return;
            }
            let billsSheet = bills.workBook.getActiveSheet();
            billsLibObj.clearHighLight(bills.workBook);
            let keyword = $('#stdBillsGuidanceSearch>input').val();
            if (!keyword || keyword === '') {
                $('#billsGuidanceSearchResult').hide();
                return;
            }

            let result = bills.tree.items.filter(function (item) {
                let codeIs = item.data.code ? item.data.code.indexOf(keyword) !== -1 : false;
                let nameIs = item.data.name ? item.data.name.indexOf(keyword) !== -1 : false;
                return codeIs || nameIs;
            });
            result.sort(function (x, y) {
                return x.serialNo() - y.serialNo();
            });
            if (result.length !== 0) {
                //展开搜索出来的节点
                expandSearchNodes(result);
                //设置记住展开
                sessionStorage.setItem('stdBillsGuidanceExpState', bills.tree.getExpState(bills.tree.items));

                let sel = billsSheet.getSelections();
                renderSheetFunc(billsSheet, function () {
                    bills.controller.setTreeSelected(result[0]);
                    billsSheet.setSelection(result[0].serialNo(), sel[0].col, 1, 1);
                    for (let node of result) {
                        billsSheet.getRange(node.serialNo(), -1, 1, -1).backColor('lemonChiffon');
                    }
                });
                //搜索初始定位
                billsSheet.showRow(result[0].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
                //查找下一条
                $('#nextBillsGuidance').show();
                $('#nextBillsGuidance').unbind('click');
                $('#nextBillsGuidance').bind('click', function () {
                    let cur = bills.tree.selected, resultIndex = result.indexOf(cur), sel = billsSheet.getSelections();
                    if (resultIndex === result.length - 1) {
                        bills.controller.setTreeSelected(result[0]);
                        billsSheet.setSelection(result[0].serialNo(), sel[0].col, 1, 1);
                        billsSheet.showRow(result[0].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
                    } else {
                        bills.controller.setTreeSelected(result[resultIndex + 1]);
                        billsSheet.setSelection(result[resultIndex + 1].serialNo(), sel[0].col, 1, 1);
                        billsSheet.showRow(result[resultIndex + 1].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
                    }
                });
                //查找上一条
                $('#preBillsGuidance').show();
                $('#preBillsGuidance').unbind('click');
                $('#preBillsGuidance').bind('click', function () {
                    let cur = bills.tree.selected, resultIndex = result.indexOf(cur), sel = billsSheet.getSelections();
                    if (resultIndex === 0) {
                        bills.controller.setTreeSelected(result[result.length - 1]);
                        billsSheet.setSelection(result[result.length - 1].serialNo(), sel[0].col, 1, 1);
                        billsSheet.showRow(result[result.length - 1].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
                    } else {
                        bills.controller.setTreeSelected(result[resultIndex - 1]);
                        billsSheet.setSelection(result[resultIndex - 1].serialNo(), sel[0].col, 1, 1);
                        billsSheet.showRow(result[resultIndex - 1].serialNo(), GC.Spread.Sheets.VerticalPosition.center);
                    }
                });
            } else {
                billsLibObj.clearHighLight(bills.workBook);
                $('#nextBillsGuidance').hide();
                $('#preBillsGuidance').hide();
            }
            $('#billsGuidanceSearchResultCount').text('搜索结果：' + result.length);
            $('#billsGuidanceSearchResult').show();
            autoFlashHeight();
            refreshWorkBook();
        });
        //搜索框回车
        $('#stdBillsGuidanceSearch>input').bind('keypress', function (event) {
            if(event.keyCode === 13){
                $(this).blur();
                $('#stdBillsGuidanceSearch>div>button').click();
            }
        });
        // 关闭搜索结果
        $('#closeSearchBillsGuidance').click(function () {
            $('#billsGuidanceSearchResult').hide();
            billsLibObj.clearHighLight(bills.workBook);
            autoFlashHeight();
            refreshWorkBook();
        });
    }
    //刷新表
    //@return {void}
    function refreshWorkBook(){
        if(bills.workBook){
            bills.workBook.refresh();
        }
    }

    return {
        initViews,
        bindBtn,
        refreshWorkBook,
        locateAtBills,
        initBillsLibs,
        bills
    };
})();

$(document).ready(function(){
    billsGuidance.bindBtn();
});