/**
 * 编办管理业务逻辑模型
 *
 * @author CaiAoLin
 * @date 2017/7/28
 * @version
 */
import mongoose from "mongoose";
import BaseModel from "../../common/base/base_model";
import  uuidV1  from 'uuid/v1';

class CompilationModel extends BaseModel {

    /**
     * 允许的块
     *
     * @var {Array}
     */
    sectionList = ['bill', 'ration'];

    /**
     * 构造函数
     *
     * @return {void}
     */
    constructor() {
        let parent = super();
        parent.model = mongoose.model('compilation');
        parent.init();
    }

    /**
     * 获取编办列表
     *
     * @return {Promise}
     */
    async getCompilationList(fields = null) {
        // 筛选字段
        let field = fields == null ?{_id: 1, name: 1, is_release: 1, categoryID: 1, description: 1,overWriteUrl: 1,example: 1, "ration_valuation.id": 1, "ration_valuation.name": 1, "ration_valuation.enable": 1,
            "bill_valuation.id": 1, "bill_valuation.name": 1, "bill_valuation.enable": 1}:fields;
        let compilationData = await this.findDataByCondition({name: {$ne: ''}}, field, false);

        return compilationData === null ? [] : compilationData;
    }

    /**
     * 设置场景
     *
     * @param {string} scene
     * @return {void}
     */
    setScene(scene = '') {
        switch (scene) {
            // 新增
            case 'add':
                this.model.schema.path('name').required(true);
                this.model.schema.path('creator').required(true);
                this.model.schema.path('create_time').required(true);
                break;
        }
    }

    /**
     * 新增编办
     *
     * @param {Object} data
     * @return {Promise}
     */
    async add(data) {
        let result = false;
        if (Object.keys(data).length <= 0) {
            return result;
        }

        this.setScene('add');
        data.create_time = new Date().getTime();
        result = this.db.create(data);
        return result;
    }

    /*
    * 设置版本描述
    *
    * @param {String} compilationId
    * @param {String} description
    * @return {Promise}
    * */
    async setDescription(compilationId, description){
        return await this.updateById(compilationId, {description: description});
    }
    /*
        设置代码覆盖路径
     */
    async setOverWriteUrl(compilationId, overWriteUrl, priceProp, consumeAmtProp){
        return await this.updateById(compilationId, {overWriteUrl: overWriteUrl, priceProperties: priceProp, consumeAmtProperties: consumeAmtProp});
    }

    /*
    * 设置例题
    * @param {String} compilationId
    * @param {Array} example
    * @return {Promise}
    * */
    async setExample(compilationId, example) {
        let data = [];
        if (example) {
            for (let projId of example) {
                data.push(parseInt(projId));
            }
        }
        return await this.updateById(compilationId, {example: data});
    }

    /**
     * 新增计价规则
     *
     * @param {String} id
     * @param {String} section
     * @param {Object} data
     * @return {Promise}
     */
    async addValuation(id, section, data) {
        let condition = {_id: id};
        let compilationData = await this.findDataByCondition(condition);
        if (compilationData === null || compilationData.name === undefined) {
            throw '没有找到对应的数据';
        }

        if (data.name === undefined || data.name === '') {
            throw '计价规则名称为空';
        }
        if (this.sectionList.indexOf(section) < 0) {
            console.log('2');
            throw '数据有误';
        }

        let insertData = {};
        data.id = uuidV1();
        insertData[section + '_valuation'] = data;
        let result = await this.db.addToSet(condition, insertData);
        return result.ok === undefined ? false : data.id;
    }

    /**
     * 保存计价数据
     *
     * @param {String} valuationId
     * @param {Object} data
     * @return {Promise}
     */
    async saveValuation(valuationId, data) {
        data = this._filterValuationData(data);
        let sectionString = data.section + "_valuation";
        let condition = {};
        condition[sectionString + ".id"] = valuationId;

        let updateData = {};
        updateData[sectionString + ".$.name"] = data.valuationName;

        let result = await this.db.update(condition, updateData);

        return result !== null && result.ok === 1;
    };

    /**
     * 更改启用/禁用
     *
     * @param {String} valuationId
     * @param {String} section
     * @param {String} enable
     * @return {Promise}
     */
    async switchEnable(valuationId, section, enable) {
        let sectionString = section + "_valuation";
        let condition = {};
        condition[sectionString + ".id"] = valuationId;

        let updateData = {};
        updateData[sectionString + ".$.enable"] = enable === "true";

        let result = await this.db.update(condition, updateData);

        return result !== null && result.ok === 1;
    }

    /**
     * 过滤计价数据
     *
     * @param {Object} data
     * @return {Object}
     */
    _filterValuationData(data) {
        if (Object.keys(data).length <= 0) {
            console.log('3');
            throw '数据有误';
        }

        if (data.section === undefined || data.section === '' || this.sectionList.indexOf(data.section) < 0) {
            throw '类型错误';
        }

        // 判断名称
        if (data.valuationName === undefined || data.valuationName === '') {
            throw '名称不能为空';
        }

        return data;
    }

    /**
     * 获取计价规则数据
     *
     * @param {String} compilationId
     * @param {String} id
     * @param {String} section
     * @return {Promise|Array}
     */
    async getValuation(compilationId, id, section) {
        if (this.sectionList.indexOf(section) < 0) {
            throw '数据有误';
        }
        let compilationData = await this.findDataByCondition({_id: compilationId});
        if (Object.keys(compilationData).length <= 0) {
            throw '编办数据有误';
        }
        let result = {};
        let sectionString = section + '_valuation';

        for(let valuation of compilationData[sectionString]) {
            if (valuation.id.toString() === id) {
                result = valuation;
                break;
            }
        }

        return [result, compilationData[sectionString]];
        /* 数据库获取编办
        let condition = {_id: versionId};
        let childCondition = {};
        childCondition[sectionString] = {$elemMatch: {_id: id}};

        let result = await this.db.findOne(condition, childCondition);

        return result !== null && result.bill_valuation.length > 0 ? result.bill_valuation[0] : {};
        */
    }

    /**
     * 删除计价规则
     *
     * @param {String} compilationId
     * @param {String} valuationId
     * @param {String} section
     * @return {Promise}
     */
    async deleteValuation(compilationId, valuationId, section) {
        let condition = {_id: compilationId};
        let sectionString = section + '_valuation';
        let deleteData = {};
        deleteData[sectionString] = {id: valuationId};

        // 利用pull删除嵌套数据
        let result = await this.db.deleteSet(condition, deleteData);

        return result !== null && result.ok === 1;
    }

    /**
     * 发布编办
     *
     * @param {String} id
     * @param {Number} status
     * @return {Promise}
     */
    async release(id, status) {
        // 如果是发布编办则需要判断配置的内容是否满足发布条件
        if (status) {
            let compilationData = await this.findDataByCondition({_id: id});
            // 最少需要有一个计价规则存在
            if (compilationData.bill_valuation.length <= 0 && compilationData.ration_valuation.length <= 0) {
                throw '至少需要一个计价规则';
            }

            // 判断是否全部禁止
            let hasEnable = false;
            let valuationList = compilationData.bill_valuation.concat(compilationData.ration_valuation);
            for (let valuation of valuationList) {
                if (valuation.enable) {
                    hasEnable = true;
                    break;
                }
            }

            if (!hasEnable) {
                throw '至少需要一个可用的计价规则';
            }
        }

        let updateData = {
            is_release: status === 1,
            release_time: new Date().getTime()
        };
        return this.updateById(id, updateData);
    }

    /**
     * 根据专业工程获取对应专业工程标准库id
     *
     * @param {String} valuationId
     * @param {String} section
     * @param {Number} engineering
     * @return {Promise}
     */
    async getEngineeringLib(valuationId, section, engineering) {
        let sectionString = section + "_valuation";
        let condition = {};
        condition[sectionString + ".id"] = valuationId;

        let compilationData = await this.findDataByCondition(condition);
        if (compilationData === null) {
            throw '不存在对应编办';
        }
        let valuationData = null;
        for(let valuation of compilationData[sectionString]) {
            if(valuation.id === valuationId) {
                valuationData = valuation;
            }
        }

        if (valuationData === null) {
            throw '不存在对应计价规则';
        }

        // 判断是否已有对应数据
        let engineeringList = valuationData.engineering_list;
        let engineeringLib = null;
        for(let tmpEngineering of engineeringList) {
            if (tmpEngineering.engineering === engineering) {
                engineeringLib = tmpEngineering;
                break;
            }
        }

        return engineeringLib;
    }

    /**
     * 新增专业工程标准库
     *
     * @param {String} valuationId
     * @param {String} section
     * @param {Object} data
     * @return {Promise}
     */
    async addEngineeringLib(valuationId, section, data) {
        let sectionString = section + "_valuation";
        let condition = {};
        condition[sectionString + ".id"] = valuationId;

        let insertData = {};
        insertData[sectionString + ".$.engineering_list"] = data;
        let result = await this.db.addToSet(condition, insertData);

        return result.ok === 1;
    }

    /*
     * 设置CLD办事处信息
     *
     * @param {String} compilationId
     * @param {int} category
     * @return {Promise}
     * */
    async updateCategory(compilationId, category) {
        return await this.updateById(compilationId, {categoryID: category});
    }

}

export default CompilationModel;