/**
 * Created by Mai on 2017/7/5.
 */

const rationContent = 0, rationPrice = 1, rationPriceConverse = 2, billsPrice = 3;

const sumTotalFeeFlag = 0, totalFeeFlag = 1;
const rationContentUnitFeeFlag = 0, averageQtyUnitFeeFlag = 1, billsPriceUnitFeeFlag = 2;

let rationContentCalcFields = [
    {'type': 'common', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': totalFeeFlag},
    {'type': 'labour', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
    {'type': 'material', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
    {'type': 'machine', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
];
let rationPriceCalcFields = [
    {'type': 'common', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': totalFeeFlag},
    {'type': 'labour', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
    {'type': 'material', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
    {'type': 'machine', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
];
let rationPriceConverseCalcFields = [
    {'type': 'common', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
    {'type': 'labour', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
    {'type': 'material', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
    {'type': 'machine', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
];
let billsPriceCalcFields = [
    {'type': 'common', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': totalFeeFlag},
    {'type': 'labour', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
    {'type': 'material', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
    {'type': 'machine', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
];

let nodeCalcObj = {
    node: null,
    digit: 2,
    field: null,
    getFee: calcFees.getFee,
    sumTotalFee: function() {
        let result = 0, child;
        for (child of this.node.children) {
            result += this.getFee(child.data, this.field.totalFee);
        }
        return result;
    },
    averageQty: function() {
        let result = 0, child, qty;
        result = this.sumTotalFee(this.field);
        qty = this.getFee(this.node.data, 'quantity');
        if (qty !== 0) {
            result = result / qty;
        }
        return result;
    },
    totalFee: function () {
        return this.getFee(this.node.data, this.field.unitFee) * this.getFee(this.node.data, 'quantity');
    },
    rationContentUnitFee: function () {
        let result = 0, child, qty = this.getFee(this.node.data, 'quantity');
        if (qty === 0) {
            qty = 1;
        }
        for (child of this.node.children) {
            result += (this.getFee(child.data, this.field.unitFee) * this.getFee(child.data, 'quantity') / qty).toDecimal(this.digit);
        }
        return result;
    }
};

let baseCalcField = [
    {
        ID: 1,
        // 序号
        serialNo: '一',
        // 费用代号
        code: "A",
        // 名称
        name: "定额直接费",
        // 计算基数
        dispExpr: "A1+A2+A3",
        // 基数说明
        statement: "人工费+材料费+机械费",
        // 费率
        feeRate: null,
        // 费用类别
        type: 'RationDirect',
        // 备注
        memo: ''
    }, {
        ID: 2,
        // 序号
        serialNo: '1',
        // 费用代号
        code: "A1",
        // 名称
        name: "人工费",
        // 计算基数
        dispExpr: "H_J",
        // 基数说明
        statement: "合计",
        // 费率
        feeRate: 0,
        // 费用类别
        type: 'labour',
        // 备注
        memo: ''
    }, {
        ID: 3,
        // 序号
        serialNo: '2',
        // 费用代号
        code: "A2",
        // 名称
        name: "材料费",
        // 计算基数
        dispExpr: "H_J",
        // 基数说明
        statement: "合计",
        // 费率
        feeRate: 100,
        // 费用类别
        type: 'material',
        // 备注
        memo: ''
    }, {
        ID: 4,
        // 序号
        serialNo: '3',
        // 费用代号
        code: "A3",
        // 名称
        name: "机械费",
        // 计算基数
        dispExpr: "H_J",
        // 基数说明
        statement: "合计",
        // 费率
        feeRate: 0,
        // 费用类别
        type: 'machine',
        // 备注
        memo: ''
    }, {
        ID: 5,
        // 序号
        serialNo: '二',
        // 费用代号
        code: "A4",
        // 名称
        name: "管理费",
        // 计算基数
        dispExpr: "A",
        // 基数说明
        statement: "定额直接费",
        // 费率
        feeRate: 0,
        // 费用类别
        type: 'management',
        // 备注
        memo: ''
    }, {
        ID: 6,
        // 序号
        serialNo: '三',
        // 费用代号
        code: "B",
        // 名称
        name: "利润",
        // 计算基数
        dispExpr: "A",
        // 基数说明
        statement: "定额直接费",
        // 费率
        feeRate: 0,
        // 费用类别
        type: 'profit',
        // 备注
        memo: ''
    }, {
        ID: 7,
        // 序号
        serialNo: '四',
        // 费用代号
        code: "C",
        // 名称
        name: "风险费用",
        // 计算基数
        dispExpr: "",
        // 基数说明
        statement: "",
        // 费率
        feeRate: null,
        // 费用类别
        type: 'risk',
        // 备注
        memo: ''
    }, {
        ID: 8,
        // 序号
        serialNo: '',
        // 费用代号
        code: "",
        // 名称
        name: "综合单价",
        // 计算基数
        dispExpr: "A+B",
        // 基数说明
        statement: "定额直接费+利润",
        // 费率
        feeRate: NaN,
        // 费用类别
        type: 'common',
        // 备注
        memo: ''
    }
];

class BillsCalcHelper {
    constructor (project, CalcFlag) {
        this.project = project;
        this.CalcFlag = CalcFlag;
        switch (this.CalcFlag) {
            case rationContent:
                this.calcField = rationContentCalcFields;
                break;
            case rationPrice:
                this.calcField = rationPriceCalcFields;
                break;
            case rationPriceConverse:
                this.calcField = rationPriceConverseCalcFields;
                break;
            case billsPrice:
                this.calcField = billsPriceCalcFields;
                break;
            default:
                this.calcField = [];
        }
        this.InitFields(this.calcField);
    };

    getBillsGLjs (node) {
        let rations = this.project.Ration.getBillsSortRation(node.source.getID());
        let gljs = this.project.ration_glj.getGatherGljArrByRations(rations);
        for (let glj of gljs) {
            glj.quantity = (glj.quantity / calcFees.getFee(node.data, 'quantity')).toDecimal(4);
        }
        return gljs;
    };
    calcRationLeaf (node, fields) {
        nodeCalcObj.node = node;
        nodeCalcObj.digit = this.project.Decimal.unitFee;
        calcFees.checkFields(node.data, fields);
        let nodeCalc = nodeCalcObj, virData= null;

        // 清单单价：套用定额计算程序
        if (this.CalcFlag === billsPrice) {
            rationCalcObj.calcGljs = this.getBillsGLjs(node);
            console.log(rationCalcObj.calcGljs);
            rationCalcObj.calcFields = rationCalcFields;
            virData = rationCalcObj.calculate();
        }

        for (let field of fields) {
            nodeCalcObj.field = field;
            switch (field.unitFeeFlag) {
                case rationContentUnitFeeFlag:
                    node.data.feesIndex[field.type].unitFee = nodeCalcObj.rationContentUnitFee().toDecimal(this.project.Decimal.common.unitFee);
                    break;
                case averageQtyUnitFeeFlag:
                    node.data.feesIndex[field.type].unitFee = nodeCalcObj.averageQty().toDecimal(this.project.Decimal.common.unitFee);
                    break;
                 case billsPriceUnitFeeFlag:
                     node.data.feesIndex[field.type].unitFee = virData[field.type];
                     break;
                default:
                    node.data.feesIndex[field.type].unitFee = 0;
            }
            switch (field.totalFeeFlag) {
                case sumTotalFeeFlag:
                    node.data.feesIndex[field.type].totalFee = nodeCalcObj.sumTotalFee().toDecimal(this.project.Decimal.common.totalFee);
                    break;
                case totalFeeFlag:
                    node.data.feesIndex[field.type].totalFee = nodeCalcObj.totalFee().toDecimal(this.project.Decimal.common.totalFee);
                    break;
                default:
                    node.data.feesIndex[field.type].totalFee = 0;
            }
        }
    };
    calcVolumePriceLeaf (node, fields) {

    };
    calcParent (node, fields) {
        nodeCalcObj.node = node;
        calcFees.checkFields(node.data, fields);
        for (let field of fields) {
            nodeCalcObj.field = field;
            node.data.feesIndex[field.type].totalFee = nodeCalcObj.sumTotalFee().toDecimal(this.project.Decimal.common.totalFee);
        }
    };
    calcNodes (nodes) {
        for (let node of nodes) {
            if (node.sourceType !== this.project.Bills.getSourceType()) {
                return;
            }

            if (node.source.children.length > 0) {
                this.calcNodes(node.children);
                this.calcParent(node, this.calcField);
            } else {
                if (node.children.length > 0) {
                    if (node.firstChild().sourceType === this.project.Ration.getSourceType()) {
                        this.calcRationLeaf(node, this.calcField);
                    } else {
                        this.calcVolumePriceLeaf(node, this.calcField);
                    }
                } else {

                }
            }
        }
    };
    calcAll () {
        this.calcNodes(this.project.mainTree.roots);
    };
    InitFields (fields) {
        for (let field of fields) {
            if (field.unitFee) return;
            field.unitFee = 'feesIndex.' + field.type + '.unitFee';
            field.unitFeeSplit = field.unitFee.split('.');
            field.totalFee = 'feesIndex.' + field.type + '.totalFee';
            field.totalFeeSplit = field.totalFee.split('.');
            field.tenderUnitFee = 'feesIndex.'+ field.type + '.tenderUnitFee';
            field.tenderUnitFeeSplit = field.tenderUnitFee.split('.');
            field.tenderTotalFee = 'feesIndex.' + field.type + '.tenderTotalFee';
            field.tenderTotalFeeSplit = field.tenderTotalFee.split('.');
        }
    }
}
