/**
 * Created by Zhong on 2018/1/9.
 */
const mongoose = require('mongoose');
const compleRationModel = mongoose.model('complementary_ration_items');
const complementaryGljModel = mongoose.model('complementary_glj_lib');
const stdGljModel = mongoose.model('std_glj_lib_gljList');
const compleRationSectionTreeModel = mongoose.model('complementary_ration_section_tree');
let stdSectionTreeModel = require ('../../ration_repository/models/ration_section_tree').Model;
let stdRationModel = require ('../../ration_repository/models/ration_item').Model;

const compleRationLib = 'compleRationLib';

class SearchDao{
    async getRationItem(userId, compilationId, rationRepIds, code, ID, callback){
        let ration = null;
        try{
            if(rationRepIds.includes(compleRationLib)) {
                rationRepIds.splice(rationRepIds.indexOf(compleRationLib), 1);
            }
            let stdQuery = {rationRepId: {$in: rationRepIds}, code: code, $or: [{isDeleted: null}, {isDeleted: false}]};
            if(ID){
                stdQuery = {ID: ID, $or: [{isDeleted: null}, {isDeleted: false}]};
            }
            let stdRation = await stdRationModel.findOne(stdQuery);
            if(isDef(stdRation)){
                ration = stdRation._doc;
                ration.type = 'std';
            } else{
                let compleQuery = {userId: userId, compilationId: compilationId, code: code, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]};
                if(ID){
                    compleQuery.ID = ID;
                }
                let compleRation = await compleRationModel.findOne(compleQuery);
                if(isDef(compleRation)){
                    ration = compleRation._doc;
                    ration.type = 'complementary';
                }
            }
            if(isDef(ration)){
                if (ration.type === 'std') {
                    let stdChapter = await stdSectionTreeModel.findOne({rationRepId: ration.rationRepId, ID: ration.sectionId, $or: [{isDeleted: null}, {isDeleted: false}]});
                    if(isDef(stdChapter)){
                        ration.chapter = stdChapter._doc;
                    }
                } else {
                    let compleChapter = await compleRationSectionTreeModel.findOne({ID: ration.sectionId, $or: [{isDeleted: null}, {isDeleted: false}]});
                    if(isDef(compleChapter)){
                        ration.chapter = compleChapter._doc;
                    }
                }
            }
            if(callback){
                callback(0, ration);
            }
        }
        catch(err){
            if(callback){
                callback(err, null);
            }
        }
        return ration;
    }

    //@param {Object}skip({std: Number, comple: Number})
    async findRation(userId, compilationId, rationRepId, keyword, skip, callback){
        //每次限制结果数
        const limit = 50;
        //结果数
        let resultCount = 0,
            rst = {data: [], count: null};
        try{
            //是否需要查找补充定额
            let findCompleRtion = rationRepId.length > 0 && rationRepId.includes(compleRationLib) ? true : false;
            //剔除补充定额库id
            if (rationRepId.includes(compleRationLib)) {
                rationRepId.splice(rationRepId.indexOf(compleRationLib), 1);
            }
            let filter = {
                'rationRepId': {$in: rationRepId},
                '$and': [{
                    '$or': [{'code': {'$regex': keyword, $options: '$i'}}, {'name': {'$regex': keyword, $options: '$i'}}]
                }, {
                    '$or': [{'isDeleted': {"$exists":false}}, {'isDeleted': null}, {'isDeleted': false}, {deleteInfo: null}]
                }]
            };
            let compleFilter = {
                userId: userId,
                compilationId: compilationId,
                '$and': [{
                    '$or': [{'code': {'$regex': keyword, $options: '$i'}}, {'name': {'$regex': keyword, $options: '$i'}}]
                }, {
                    '$or': [{deleteInfo: null}, {'deleteInfo.deleted': false}]
                }]
            };
            //结果数
            if (skip && skip.std === 0 && skip.comple === 0) {
                resultCount += rationRepId.length === 0 ? 0 : await stdRationModel.find(filter).count();
                resultCount += findCompleRtion ? await compleRationModel.find(compleFilter).count() : 0;
                rst.count = resultCount;
            }
            //搜索定额
            let stdGljIds = [],
                comGljIds = [];
            let stdRations = rationRepId.length === 0 ? [] : await stdRationModel.find(filter).sort({code: 1}).skip(skip.std).limit(limit);
            for(let i = 0, len = stdRations.length; i < len; i++){
                stdRations[i]._doc.type = 'std';
                for(let glj of stdRations[i].rationGljList){
                    stdGljIds.push(glj.gljId);
                }
            }
            let compleRations = [];
            let residueLimit = limit - stdRations.length;
            if (residueLimit > 0) {
                compleRations = findCompleRtion ? await compleRationModel.find(compleFilter).sort({code: 1}).skip(skip.comple).limit(residueLimit) : [];
                for(let i = 0, len = compleRations.length; i <len; i++){
                    compleRations[i]._doc.type = 'complementary';
                    for(let glj of compleRations[i].rationGljList){
                        if(glj.type === 'std'){
                            stdGljIds.push(glj.gljId);
                        }
                        else {
                            comGljIds.push(glj.gljId);
                        }
                    }
                }
            }

            //设置悬浮信息
            stdGljIds = Array.from(new Set(stdGljIds));
            comGljIds = Array.from(new Set(comGljIds));
            let gljIDMapping = {};
            if(stdGljIds.length > 0){
                let stdGljs = await stdGljModel.find({ID: {$in: stdGljIds}}, '-_id ID code name specs unit gljType');
                for(let stdGlj of stdGljs){
                    gljIDMapping[stdGlj.ID] = stdGlj;
                }
            }
            if(comGljIds.length > 0){
                let comGljs = await complementaryGljModel.find({ID: {$in: stdGljIds}});
                for(let comGlj of comGljs){
                    gljIDMapping[comGlj.ID] = comGlj;
                }
            }
            for(let ration of stdRations){
                let hintsArr = [];
                //对人材机进行排序
                ration.rationGljList.sort(function (a, b) {
                    let gljA = gljIDMapping[a.gljId],
                        gljB = gljIDMapping[b.gljId];
                    if(gljA && gljB){
                        let aV = gljA.gljType + gljA.code,
                            bV = gljB.gljType + gljB.code;
                        if(aV > bV) {
                            return 1;
                        } else if(aV < bV) {
                            return -1;
                        }
                    }
                    return 0;
                });
                for(let rationGlj of ration.rationGljList){
                    let glj = gljIDMapping[rationGlj.gljId];
                    if(glj){
                        hintsArr.push(` ${glj.code} ${glj.name}${glj.specs ? ' ' + glj.specs : ''} ${glj.unit} ${rationGlj.consumeAmt}`);
                    }
                }
                hintsArr.push(`基价 元 ${ration.basePrice}`);
                if(ration.jobContent && ration.jobContent.toString().trim() !== ''){
                    hintsArr.push(`工作内容:`);
                    hintsArr = hintsArr.concat(ration.jobContent.split('\n'));
                }
                if(ration.annotation && ration.annotation.toString().trim() !== ''){
                    hintsArr.push(`附注:`);
                    hintsArr = hintsArr.concat(ration.annotation.split('\n'));
                }
                ration._doc.hint = hintsArr.join('<br>');
            }
            for(let ration of compleRations){
                let hintsArr = [];
                for(let rationGlj of ration.rationGljList){
                    let glj = gljIDMapping[rationGlj.gljId];
                    if(glj){
                        hintsArr.push(` ${glj.code} ${glj.name}${glj.specs ? ' ' + glj.specs : ''} ${glj.unit} ${rationGlj.consumeAmt}`);
                    }
                }
                hintsArr.push(`基价 元 ${ration.basePrice}`);
                if(ration.jobContent && ration.jobContent.toString().trim() !== ''){
                    hintsArr.push(`工作内容:`);
                    hintsArr = hintsArr.concat(ration.jobContent.split('\n'));
                }
                if(ration.annotation && ration.annotation.toString().trim() !== ''){
                    hintsArr.push(`附注:`);
                    hintsArr = hintsArr.concat(ration.annotation.split('\n'));
                }
                ration._doc.hint = hintsArr.join('<br>');
            }
            rst.data = stdRations.concat(compleRations);
            callback(0, rst);
        }
        catch(err){
            console.log(err);
            callback(err, null);
        }
    }
}

function isDef(v){
    return v !== undefined && v !== null;
}

export default SearchDao;