'use strict';

/**
 *
 *
 * @author Zhong
 * @date 2019/5/15
 * @version
 */
//操作接口为eventListen
const importView = (() => {
    let xmlObj = null;  //导入xml转化后的对象
    let tbcObj = null;  //待确认对象
    //显示、隐藏提示上传文件窗口相关提示信息
    function showUploadAlert(success, msg) {
        if (!success) {
            $('#uploadAlert').removeClass('alert-success');
            $('#uploadAlert').addClass('alert-danger');
        } else {
            $('#uploadAlert').removeClass('alert-danger');
            $('#uploadAlert').addClass('alert-success');
        }
        $('#uploadAlert').text(msg);
        $('#uploadAlert').show();
    }
    /*
     * 获取单位工程数据（将所有单项工程里的单位工程放到一起，含有单项工程的一些信息）
     * @param {Object} xmlObj @return {Array}
     * */
    function getTenderDatas(xmlObj) {
        if (!xmlObj || !xmlObj.engs) {
            return [];
        }
        let rst = [];
        for (let eng of xmlObj.engs) {
            if (Array.isArray(eng.tenders)) {
                for (let tender of eng.tenders) {
                    tender.temp = {};  //暂时存放的信息（不是从导入文件中获取的，记录当前工程已阅、选择的费用标准、计算程序）
                    tender.engName = eng.name;
                }
                rst.push(...eng.tenders);
            }
        }
        return rst;
    }
    //确认界面提示信息隐藏
    function hideTBCInfo() {
        $('#tbc-engName-info').hide();
        $('#tbc-tenderName-info').hide();
        $('#tbc-engineering-info').hide();
        $('#tbc-calcProgram-info').hide();
    }
    //待确认界面相关
    class TBC {
        constructor(xmlObj, fileKind, valuation, taxType) {
            this.datas = getTenderDatas(xmlObj);
            this.fileKind = fileKind;   //文件类型
            this.valuationType = 'bill';    //计价方式 暂时默认为清单计价
            this.valuation = valuation;     //计价规则数据
            this.taxType = taxType; //计税方法
            this.engineeringList = valuation ? valuation.engineering_list : []; //工程专业库数据
            this.curIdx = 0;    //当前单位工程数据索引
            this.init();
        }
        //初始化
        init() {
            this.next(this.curIdx);
            $('#importInterface .modal-content:eq(1) p:eq(0)').text(`该文件共有${this.datas.length}个单位工程待导入`);  //信息统计信息
        }
        checkConfirmed() {
            //检查数据是否都确认过了
            let allConfirmed = this.datas.every(data => data.temp.confirmed);
            if (allConfirmed) {
                $('#import-confirm').prop('disabled', false);
            }
        }
        //检测当前待确认工程是否有效，有效才可确认
        checkValid() {
            let engName = $('#tbc-engName').val();
            if (!engName) {
                return $('#tbc-engName-info').show();
            } else {
                $('#tbc-engName-info').hide();
            }
            let tenderName = $('#tbc-tenderName').val();
            if (!tenderName) {
                return $('#tbc-tenderName-info').show();
            } else {
                $('#tbc-tenderName-info').hide();
            }
            let engineering = $('#tbc-engineering').val();
            if (!engineering) {
                return $('#tbc-engineering-info').show();
            } else {
                $('#tbc-engineering-info').hide();
            }
            let feeStandard = $('#tbc-feeStandard').val();
            if (!feeStandard) {
                return $('#tbc-feeStandard-info').show();
            } else {
                $('#tbc-feeStandard-info').hide();
            }
            let calcProgram = $('#tbc-calcProgram').val();
            if (!calcProgram) {
                return $('#tbc-calcProgram-info').show();
            } else {
                $('#tbc-calcProgram-info').hide();
            }
            return null;
        }
        //下一工程
        next(idx = null) {
            this.curIdx = idx !== null ? idx : this.curIdx + 1;
            if (this.curIdx && this.checkValid()) {
                this.curIdx--;
                return;
            }
            let curData = this.datas[this.curIdx];
            //显示这个工程的相关信息
            $('#tbc-engName').val(curData.engName || '');
            $('#tbc-tenderName').val(curData.name || '');
            $('#tbc-engineering').val(curData.engineering || '');
            curData.temp.confirmed = true;   //增加确认信息（已读）
            if (this.curIdx === this.datas.length - 1) { //到最后一个数据了，无法点击下一工程
                $('#tbc-next').prop('disabled', true);
            } else {
                $('#tbc-next').prop('disabled', false);
            }
            if (this.curIdx !== 0) {    //不为第一个数据，可以点击上一工程
                $('#tbc-prev').prop('disabled', false);
            } else {
                $('#tbc-prev').prop('disabled', true);
            }
            //更新x/x信息
            $('#tbc-info').text(`${this.curIdx + 1}/${this.datas.length} 已确认`);
            //更新选项信息
            this.initFeeOpts(curData);
            this.checkConfirmed();
        }
        //上一工程
        prev(idx = null) {
            this.curIdx = idx !== null ? idx : this.curIdx - 1;
            let curData = this.datas[this.curIdx];
            $('#tbc-engName').val(curData.engName || '');
            $('#tbc-tenderName').val(curData.name || '');
            $('#tbc-engineering').val(curData.engineering || '');
            if (this.curIdx === 0) {    //到第一个数据了，无法点击上一工程
                $('#tbc-prev').prop('disabled', true);
            } else {
                $('#tbc-prev').prop('disabled', false);
            }
            if (this.curIdx !== this.datas.length - 1) {    //不为最后一个数据了，可以点击下一工程
                $('#tbc-next').prop('disabled', false);
            } else {
                $('#tbc-next').prop('disabled', true);
            }
            //更新x/x信息
            $('#tbc-info').text(`${this.curIdx + 1}/${this.datas.length} 已确认`);
            //更新选项信息
            this.initFeeOpts(curData);
            this.checkConfirmed();
        }
        /*
         *  初始化工程的费用选项等相关信息(专业工程、费用标准、计算程序等)
         *  根据导入文件提取的专业工程等数据确定，需要我们软件有对应的工程专业数据，否则下拉选择为空
         *  @param {Object}tenderData(当前确认单位工程数据) {Array}engineeringList(当前计价规则下的工程专业数据)
         *  @return {void}
         * */
        initFeeOpts(tenderData) {
            $('#tbc-engineering').empty();  //清空工程专业选项
            $('#tbc-feeStandard').empty();  //清空费用标准选项
            $('#tbc-calcProgram').empty();  //清空计算程序选项
            let engineerings = [];
            if (tenderData.temp.engineering) {
                engineerings = this.engineeringList.filter(data => data.lib.name === tenderData.temp.engineering);
            } else {
                engineerings = this.engineeringList.filter(data => data.lib.name === tenderData.engineering);
                tenderData.temp.engineering = tenderData.engineering;
            }
            //文件里的工程专业跟软件里的对应不上，取第一个
            if (!engineerings.length) {
                let firstEngineering = this.engineeringList[0];
                engineerings = this.engineeringList.filter(data => data.lib.name === firstEngineering.lib.name);
                tenderData.temp.engineering = engineerings[0] ? engineerings[0].lib.name : tenderData.engineering;
            }
            if (!engineerings.length) {
                return;
            }
            //工程专业名称去重
            let engineeringNames = [...new Set(this.engineeringList.map(data => data.lib.name))];
            let engineeringHtml = engineeringNames.map(name =>
                `<option ${tenderData.temp.engineering === name ? 'selected' : ''} value="${name}">${name}</option>`);
            $('#tbc-engineering').html(engineeringHtml);
            //$('#tbc-engineering').html(`<option selected value="${tenderData.engineering}">${tenderData.engineering}</option>`);
            //费用标准，若当前工程有费用标准数据（该数据本身没有费用标准数据，选择过了，就会记录），则选中该费用标准
            let feeOptsHtml = engineerings.map(data =>
                `<option ${tenderData.temp.feeStandard === data.lib.feeName ? 'selected' : ''} value="${data.lib.feeName}">${data.lib.feeName}</option>`).join('');
            $('#tbc-feeStandard').html(feeOptsHtml);
            //记录选中的费用标准
            tenderData.temp.feeStandard = $('#tbc-feeStandard').val();
            //根据工程专业及费用标准确定的当前选中的工程专业库
            let curEngineering = engineerings.find(data => data.lib.feeName === tenderData.temp.feeStandard) || engineerings[0];
            //根据计税方法过滤出来的计税组合
            let taxDatas = curEngineering.lib.tax_group.filter(data => data.taxType == this.taxType);
            //计算程序，若当前工程有计算程序（该数据本身没有计算程序数据，选择过了，就会记录），则选中该计算程序
            let calcOptsHtml = taxDatas.map(data =>
                `<option ${tenderData.temp.calcProgram === data.program_lib.name ? 'selected' : ''} value="${data.program_lib.name}">${data.program_lib.name}</option>`);
            $('#tbc-calcProgram').html(calcOptsHtml);
            tenderData.temp.calcProgram = $('#tbc-calcProgram').val();
        }
    }
    /*
     * 根据条件获取计税组合数据
     * @param {Object}query ({engineeringName, feeName, taxType, calcProgram}) {Array}engineeringList(当前计价规则下的所有工程专业数据)
     * @return {Object}
     * */
    function getTaxData(query, engineeringList) {
        //工程专业名称 + 费用标准名称 确定一个工程专业数据
        let engineering = engineeringList.find(data => query.engineeringName === data.lib.name &&
            query.feeStandard === data.lib.feeName);
        if (!engineering || !Array.isArray(engineering.lib.tax_group)) {
            return null;
        }
        return engineering.lib.tax_group.find(data => query.taxType == data.taxType &&
            query.calcProgram === data.program_lib.name);
    }
    //获取单位工程项目属性的一些数据(新建单位工程需要，前端能获取到的一些数据，还有一些数据需要后端获取: rootProjectID, projectFeature..)
    /*
    * @param {Object}tbcObj(TBC实例) {Object}curData(单位工程数据)
    * @return {Object}
    * */
    function getProperty(tbcObj, curData) {
        if (!tbcObj) {
            throw '存在无效数据，无法生成项目。';
        }
        //计税数据
        let query = {
            engineeringName: curData.temp.engineering || curData.engineering,
            feeStandard: curData.temp.feeStandard,
            taxType: tbcObj.taxType,    //取导入时选择的计税方法，不读取文件中的计税方法
            calcProgram: curData.temp.calcProgram
        };
        let taxData = getTaxData(query, tbcObj.engineeringList);
        if (!taxData) {
            throw '无效计税数据，无法生成项目。';
        }
        //当前工程专业数据
        let curEngineering = tbcObj.engineeringList.find(data => query.engineeringName === data.lib.name &&
            query.feeStandard === data.lib.feeName);
        return {
            region: commonConstants.DEFAULT_REGION,   //地区
            valuationType: tbcObj.valuationType,    //计价方式
            valuation: tbcObj.valuation.id, //计价规则
            valuationName: tbcObj.valuation.name,
            engineering_id: curEngineering.engineering_id,  //工程专业
            engineeringName: curEngineering.lib.name,
            taxType: parseInt(tbcObj.taxType),    //计税方法
            isInstall: !!curEngineering.lib.isInstall,  //是安装工程?
            isItemIncrease: !!curEngineering.lib.isItemIncrease,  //是否子目增加费?
            isAreaIncrease: !!curEngineering.lib.isAreaIncrease,  //是否子目增加费?
            feeStandardName: curEngineering.lib.feeName,    //费用标准
            engineering: curEngineering.lib.engineering,    //定额取费专业
            projectEngineering: curEngineering.lib.projectEngineering,  //单位工程取费专业
            featureLibID: curEngineering.lib.feature_lib && curEngineering.lib.feature_lib[0] ? curEngineering.lib.feature_lib[0].id : '',    //工程特征
            indexName: curEngineering.lib.indexName,    // 指标名称
            engineerInfoLibID: curEngineering.lib.engineer_info_lib && curEngineering.lib.engineer_info_lib[0] ? curEngineering.lib.engineer_info_lib[0].id : '',   // 工程信息指标
            engineerFeatureLibID: curEngineering.lib.engineer_feature_lib && curEngineering.lib.engineer_feature_lib[0] ? curEngineering.lib.engineer_feature_lib[0].id : '',  //工程特征指标
            economicLibID: curEngineering.lib.economic_lib && curEngineering.lib.economic_lib[0] ? curEngineering.lib.economic_lib[0].id : '',    // 主要经济指标
            mainQuantityLibID: curEngineering.lib.main_quantity_lib && curEngineering.lib.main_quantity_lib[0] ? curEngineering.lib.main_quantity_lib[0].id : '',   // 主要工程量指标
            materialLibID: curEngineering.lib.material_lib && curEngineering.lib.material_lib[0] ? curEngineering.lib.material_lib[0].id : '', // 主要工料指标
            progressiveLibID: curEngineering.lib.progressive_lib && curEngineering.lib.progressive_lib[0] ? curEngineering.lib.progressive_lib[0].id: '', // 累进库
            calcProgram: { name: taxData.program_lib.name, id: taxData.program_lib.id },  //计算程序
            colLibID: taxData.col_lib.id,   //列设置
            templateLibID: taxData.template_lib.id, //清单模板
            unitPriceFile: { name: curData.name, id: '' },    //新建单价文件
            feeFile: { name: curData.name, id: `newFeeRate@@${taxData.fee_lib.id}` }  //新建费率文件
        };
    }
    function eventListen() {
        //选择文件
        $('#customFile').change(async function () {
            let file = $(this)[0].files[0];
            $('#import-confirm').prop('disabled', true);    //确认导入无效
            $('.custom-file-label').text(`${file ? file.name : ''}`);   //设置选择框文本
            $('#uploadAlert').hide();
            $('.selFile').hide();
            hideTBCInfo();
            if (file) {
                const reg = importXMLBase.getAcceptReg(importXML.accept);
                if (file.name && !reg.test(file.name)) {
                    $('.selFile').hide();
                    const acceptAlert = importXML.accept.join('、');
                    showUploadAlert(false, `请选择${acceptAlert}文件。`);
                    return;
                }
                $.bootstrapLoading.start();
                $('#loadingPage').css('z-index', '2000');
                try {
                    //转换数据
                    xmlObj = await importXML.extractData(file, false);
                    console.log(xmlObj);
                    $('.selFile input:eq(0)').val(xmlObj && xmlObj.name ? xmlObj.name : '');
                    $('.selFile input[name="fileKind-import"]:eq(0)').prop('checked', true);    //文件类型恢复成投标
                    $('#import-taxType').val('1');  //计税方法显示回默认的一般计税法
                    $('.selFile').show();   //显示建设项目、计价规则
                } catch (err) {
                    console.log(err);
                    showUploadAlert(false, err);
                    $(this).val('');
                }
                $.bootstrapLoading.end();
            }
        });
        //下一步
        $('#import-next').click(function () {
            debugger;
            let file = $('#customFile')[0].files[0];
            if (!file) {
                showUploadAlert(false, '请选择导入文件。');
                return;
            }
            if (!xmlObj) {
                showUploadAlert(false, '不存在有效数据。');
                return;
            }
            let projectName = $('.selFile input:eq(0)').val();
            if (!projectName) {
                showUploadAlert(false, '不存在有效建设项目。');
                return;
            }
            //文件类型
            let fileKind = $('.selFile input[name="fileKind-import"]:checked').val();
            if (!fileKind) {
                showUploadAlert(false, '不存在有效文件类型。');
            }
            //计价规则
            let valuation = $('#import-valuation').val();
            if (!valuation) {
                showUploadAlert(false, '不存在有效计价规则。');
                return;
            }
            //计税方法
            let taxType = $('#import-taxType').val();
            if (!taxType) {
                showUploadAlert(false, '不存在有效计税方法。');
                return;
            }
            if (!xmlObj.engs.length) {
                showUploadAlert(false, '不存在单项工程数据。');
                return;
            }
            if (!getTenderDatas(xmlObj).length) {
                showUploadAlert(false, '不存在单位工程数据。');
                return;
            }
            $('#importInterface .modal-content:eq(0)').hide();  //隐藏第一步内容
            $('#importInterface .modal-content:eq(1)').show();  //显示第二步内容
            //console.log(getTenderDatas(xmlObj));
            //console.log(xmlObj);
            let selValuation = billValuation.find(data => data.id === valuation);
            tbcObj = new TBC(xmlObj, fileKind, selValuation, taxType);
        });
        //上一步
        $('#import-prev').click(function () {
            $('#importInterface .modal-content:eq(0)').show();  //显示第一步内容
            $('#importInterface .modal-content:eq(1)').hide();  //隐藏第二步内容
            hideTBCInfo();
            $('#import-confirm').prop('disabled', true);    //确认导入无效
            //清空确认字段
            if (tbcObj) {
                for (let data of tbcObj.datas) {
                    delete data.temp.confirmed;
                }
            }
        });
        //变换专业工程
        $('#tbc-engineering').change(function () {
            let curData = tbcObj ? tbcObj.datas[tbcObj.curIdx] : null;
            if (!curData) {
                return;
            }
            curData.temp.engineering = $(this).val();
            tbcObj.initFeeOpts(curData);
        });
        //变换费用标准
        $('#tbc-feeStandard').change(function () {
            let curData = tbcObj ? tbcObj.datas[tbcObj.curIdx] : null;
            if (!curData) {
                return;
            }
            curData.temp.feeStandard = $(this).val();
            tbcObj.initFeeOpts(curData);
        });
        //变换计算程序
        $('#tbc-calcProgram').change(function () {
            let curData = tbcObj ? tbcObj.datas[tbcObj.curIdx] : null;
            if (!curData) {
                return;
            }
            curData.temp.calcProgram = $(this).val();
            tbcObj.initFeeOpts(curData);
        });
        //待确认-下一工程
        $('#tbc-next').click(function () {
            tbcObj.next();

        });
        //待确认-上一工程
        $('#tbc-prev').click(function () {
            tbcObj.prev();
            hideTBCInfo();
        });
        //确认导入
        $('#import-confirm').click(async function () {
            if (STATE.importing) {
                return;
            }
            STATE.importing = true;
            if (tbcObj && tbcObj.checkValid()) {
                return;
            }
            let pr = new SCComponent.InitProgressBar();
            try {
                //建设项目设置选择的文件类型和选择的计税方法
                xmlObj.property.fileKind = tbcObj.fileKind;
                xmlObj.property.taxType = tbcObj.taxType;
                //确定使用的计税组合
                tbcObj.datas.map(data => {
                    data.property = getProperty(tbcObj, data);
                    //默认定额库
                    let curEngineering = tbcObj.engineeringList.find(enData => data.temp.engineering === enData.lib.name &&
                        data.temp.feeStandard === enData.lib.feeName);
                    let defaultLib = curEngineering.lib.ration_lib.find(data => data.isDefault) || curEngineering.lib.ration_lib[0];
                    data.defaultRationLib = parseInt(defaultLib.id);
                    //此费用定额下可用的定额库id，人材机库id
                    data.rationLibIDs = curEngineering.lib.ration_lib.map(data => parseInt(data.id));
                    data.gljLibIDs = curEngineering.lib.glj_lib.map(data => parseInt(data.id));
                });
                //确定生成建设项目的父、前、后节点ID
                let { parentProjectID, preProjectID, nextProjectID } = projTreeObj.getRelProjectID(projTreeObj.tree.selected);
                xmlObj.ParentID = parentProjectID;
                xmlObj.preID = preProjectID;
                xmlObj.NextSiblingID = nextProjectID;
                //确定建设项目的名称（不允许重复）
                let sameDepthProjs = getProjs(projTreeObj.tree.selected);
                if (sameDepthProjs.find(node => node.data.name === xmlObj.name)) {
                    xmlObj.name += `(${moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')})`;
                }
                $('#importInterface').modal('hide');
                //pr.start('导入文件', '正在生成文件，请稍候……');
                $.bootstrapLoading.progressStart('导入文件', true);
                $("#progress_modal_body").text('正在导入接口文件，请稍候……');
                let importData = await importXML.transformData(xmlObj);
                console.log(importData);
                let blob = new Blob([JSON.stringify(importData)], { type: 'text/plain;charset=utf-8' });
                // 转换成File实例
                const key = `${uuid.v1()}.json`;
                const file = new File([blob], key);
                // 上传文件
                await projTreeObj.getUploadToken();
                await UPLOAD_CDN.uploadSync(file, key, projTreeObj.uptoken);
                // 下载并处理文件
                await ajaxPost('/pm/import/importInterface', { key });
                await importProcessChecking(key, null, (projectData) => handleProjectAfterChecking(projectData));
            } catch (err) {
                console.log(err);
                alert(err);
            } finally {
                projTreeObj.uptoken = null;
                setTimeout(function () {
                    STATE.importing = false;
                }, 500);
                //pr.end();
            }
        });
        // 导入窗口激活
        $('#importInterface').on('show.bs.modal', function () {
            // 设置上传文件输入框accept属性
            $('#customFile').attr('accept', importXML.accept.join(','));
            // 恢复计价规则下拉
            setValuationSels($('#import-valuation'), billValuation);
        });
        //导入窗口消失后
        $('#importInterface').on('hidden.bs.modal', function () {
            xmlObj = null;  //重置数据
            tbcObj = null;
            $('#importInterface .modal-content:eq(0)').show();  //显示第一步内容
            $('#importInterface .modal-content:eq(1)').hide();  //隐藏第二步内容
            $('#customFile').val('');    //清除选择
            $('.custom-file-label').text('');   //设置选择框文本
            $('#uploadAlert').hide();   //隐藏提示
            $('.selFile').hide();   //隐藏建设项目及计价规则
            $('#import-confirm').prop('disabled', true);    //确认导入无效
            $('.selFile input[name="fileKind-import"]:eq(0)').prop('checked', true);    //文件类型恢复成投标
            $('#import-taxType').val('1');  //显示回一般计税
            hideTBCInfo();
        });
    }
    //projectDatas在后端已经按照顺序排过了： project eng1 tender1-1 tender1-2 eng2 tender2-1 tender2-2
    function doAfterImport(projectDatas) {
        //插入节点
        let lastNode;
        for (let data of projectDatas) {
            data.feeStandardName = data.property && data.property.feeStandardName || ''; //工程专业列显示用
            let parent = projTreeObj.tree.items.find(node => node.data.ID === data.ParentID),
                next = projTreeObj.tree.items.find(node => node.data.ID === data.NextSiblingID);
            lastNode = projTreeObj.insert(data, parent, next);
        }
        if (lastNode) {
            projTreeObj.workBook.getSheet(0).showRow(lastNode.serialNo(), GC.Spread.Sheets.VerticalPosition.center);
        }
    }
    return { eventListen, doAfterImport };
})();