/**
 * Created by jimiz on 2017/4/16.
 */
var billsData = require('./bills');
var rationData = require('./ration');
var ration_glj_data = require('../../ration_glj/facade/ration_glj_facade');
var ration_coe_data = require('../../ration_glj/facade/ration_coe_facade');
var ration_ass_data = require('../../ration_glj/facade/ration_ass_facade');
let ration_installation = require('../facade/ration_installation_facade');
let ration_template = require('../facade/ration_template_facade');
var quantity_detail_data = require('../facade/quantity_detail_facade');
var fee_rate_data = require('../../fee_rates/facade/fee_rates_facade');
let projCounter = require('./proj_counter_model');
let projSetting = require('./proj_setting_model');
// let volumePriceData = require('../../volume_price/models/volume_price_model');
var labour_coe_facade = require('../facade/labour_coe_facade');
var calc_program_facade = require('../facade/calc_program_facade');
const GLJController = require("../../glj/controllers/glj_controller");
let installation_facade = require('../facade/installation_facade');
let evaluate_facade = require('../facade/evaluate_facade');
let bid_facade = require('../facade/bid_facade');
let contractor_facade = require('../facade/contractor_facade');
let pmController = require('../../pm/controllers/pm_controller');


const commonFacade = require('../../main/facade/common_facade');
const GLJListModel = require("../../glj/models/glj_list_model");

var consts = require('./project_consts');
var projectConsts = consts.projectConst;
var asyncTool = require("async");

var moduleMap = {};

moduleMap[projectConsts.BILLS] = billsData;
moduleMap[projectConsts.RATION] = rationData;
moduleMap[projectConsts.RATION_GLJ] = ration_glj_data;
moduleMap[projectConsts.RATION_COE] = ration_coe_data;
moduleMap[projectConsts.RATION_ASS] = ration_ass_data;
moduleMap[projectConsts.RATION_INSTALLATION] = ration_installation;
moduleMap[projectConsts.QUANTITY_DETAIL] = quantity_detail_data;
moduleMap[projCounter.collectionName] = projCounter;
moduleMap[projSetting.collectionName] = projSetting;
moduleMap[projectConsts.FEERATE] = fee_rate_data;
moduleMap[projectConsts.LABOUR_COE] = labour_coe_facade;
moduleMap[projectConsts.CALC_PROGRAM] = calc_program_facade;
moduleMap[projectConsts.PROJECTGLJ] = new GLJController();
moduleMap[projectConsts.INSTALLATION_FEE] = installation_facade;
moduleMap[projectConsts.RATION_TEMPLATE] = ration_template;
moduleMap[projectConsts.PROJECT_INFO] = pmController;
moduleMap[projectConsts.EVALUATE_LIST] = evaluate_facade;
moduleMap[projectConsts.BID_EVALUATION_LIST] = bid_facade;
moduleMap[projectConsts.CONTRACTOR_LIST] = contractor_facade;

var Project = function (){};

Project.prototype.datas = [];

Project.prototype.prepare = function(data, callback){
    var me = this;
    data.update_data.forEach(function(item){
        item.user_id = data.user_id;
        me.datas.push(item);
        /*
        to do
        moduleMap[item.moduleName].prepare(item.data, jobCallback);
        */
    });
};

Project.prototype.save = function(datas, callback){
    var job, savePoint;
    var functions = [];
    var item;
    var me = this;

    me.prepare(datas, function(job, savePoint){});

    function saveModule(data) {
        return function (cb) {
            if(data.moduleName!=undefined){
                moduleMap[data.moduleName].save(data.user_id, data.data, cb);
            }
           // console.log(moduleMap[data.moduleName])

        }
    }

    for (var i = 0; i < me.datas.length; i++){
        item = me.datas[i];
        functions.push(saveModule(item));
    }

    asyncTool.parallel(functions, function(err, results) {
        if (!err){
            callback(null, '', results)
        } else{
            console.log(err);
            callback(1, 'save project failed', null)
        }
    });
    me.datas = [];
};

Project.prototype.getData = function(projectID, callback, isReport, userID){
    var functions = [];
    var itemName;
    let firstTime = +new Date();
    for (itemName in moduleMap){
        functions.push((function(itemName){
            return function (cb) {
                let startTime = +new Date();
                moduleMap[itemName].getData(projectID, function(err, moduleName, data){
                    let endTime = +new Date();
                    console.log(moduleName+'---------------'+(endTime - startTime));
                    cb(err, {moduleName: moduleName, data: data})
                }, isReport, userID)
            }
        })(itemName))
    }

    asyncTool.parallel(functions, function(err, results) {
        if (!err){
            let lastTime = +new Date();
            console.log('最后加载时间---------------'+(lastTime - firstTime));
            callback(0, '', results)
        }
        else{
            console.log(err);
            callback(1, 'load project failed', null)
        }
    });
};

Project.prototype.getDataSync = function(projectID){
    return new Promise((resolve, reject) => {
        const functions = [];
        const firstTime = +new Date();
        for (const itemName in moduleMap){
            functions.push((function(itemName){
                return function (cb) {
                    const startTime = +new Date();
                    moduleMap[itemName].getData(projectID, function(err, moduleName, data){
                        const endTime = +new Date();
                        console.log(moduleName+'---------------'+(endTime - startTime));
                        cb(err, {moduleName: moduleName, data: data})
                    }, true); // true 返回调价后的数据
                }
            })(itemName))
        }
    
        asyncTool.parallel(functions, function(err, results) {
            if (!err) {
                const lastTime = +new Date();
                console.log('最后加载时间---------------'+(lastTime - firstTime));
                resolve(results);
            } else {
                reject(err);
            }
        });
    });
};

Project.prototype.getFilterData = function (projectID, filter, callback) {
    let functions = [];
    let getModuleData = function (moduleName) {
        return async function (cb) {
            if (moduleMap[moduleName]) {
                moduleMap[moduleName].getData(projectID, function (err, name, data) {
                    cb(err, {'moduleName': name, 'data': data})
                }, true);     // 所有报表只显示调价后的数据，这里传入一个标记true，子方法会将调价后的值赋给调价前的字段，这样报表可以不用动。
            } else if (moduleName === projectConsts.PROJECTGLJ) {
                try {
                    if (isNaN(projectID) || projectID <= 0) {
                        throw '标段id有误';
                    }
                    // 获取标段对应的单价文件id
                    let unitPriceFileId = await commonFacade.getUnitPriceFileId(projectID);
                    if (unitPriceFileId <= 0) {
                        throw '没有对应的单价文件';
                    }
                    // 先获取对应标段的项目工料机数据
                    let gljListModel = new GLJListModel();
                    let [gljList, mixRatioConnectData] = await gljListModel.getListByProjectId(projectID, unitPriceFileId);

                    cb(null, {'moduleName': moduleName, 'data': gljList});
                } catch (error) {
                    cb(error, null);
                }
            } else {
                throw '要查询的项目模块不存在';
            }
        }
    };
    for (let itemName of filter) {
        functions.push(getModuleData(itemName));
    }
    asyncTool.parallel(functions, function (err, results) {
        //console.log(results);
        if (err) {
            throw '获取项目数据出错';
        } else {
            callback(results);
        }
    });
};

module.exports = new Project();
