/**
 * 单价业务模型
 *
 * @author CaiAoLin
 * @date 2017/6/30
 * @version
 */
import BaseModel from "../../common/base/base_model"
import CounterModel from "./counter_model"
import GLJListModel from "./glj_list_model";
import {default as UnitPriceSchema, collectionName as collectionName} from "./schemas/unit_price";

class UnitPriceModel extends BaseModel {

    /**
     * 自动赋值的工料机类型集
     * (主材、设备)
     *
     * @var {Array}
     */
    static autoChangeGLJType = [10, 11];

    /**
     * 触发计算混凝土、砂浆、配合比、机械的市场单价
     * (人工、材料(普通材料))
     *
     * @var {Array}
     */
    static triggerCalculateGLJType = [2, 5];

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

    /**
     * 根据单价文件id获取单价数据
     *
     * @param {Number} fileId
     * @return {Promise}
     */
    async getDataByFileId(fileId) {
        fileId = parseInt(fileId);
        if (isNaN(fileId) || fileId <= 0) {
            return null;
        }

        let unitPriceList = await this.db.model.find({unit_price_file_id: fileId});
        if (unitPriceList.length <= 0) {
            return null;
        }

        // 整理数据
        let result = {};
        for(let tmp of unitPriceList) {
            result[tmp.code + tmp.name] = tmp;
        }

        return result;
    }

    /**
     * 设置场景
     *
     * @param {string} scene
     * @return {void}
     */
    setScene(scene = '') {
        switch (scene) {
            // 新增数据的验证规则
            case 'add':
                this.model.schema.path('base_price').required(true);
                this.model.schema.path('market_price').required(true);
                this.model.schema.path('name').required(true);
                this.model.schema.path('code').required(true);
                this.model.schema.path('unit').required(true);
                this.model.schema.path('type').required(true);
                this.model.schema.path('unit_price_file_id').required(true);
        }
    }

    /**
     * 新增单价数据
     *
     * @param {Object} data
     * @param {Number} unitPriceFileId
     * @param {Number} gljCount
     * @return {Promise} 返回数据以及是否新增
     */
    async addUnitPrice(data, unitPriceFileId, gljCount = 0) {
        if (data.code === undefined || data.project_id === undefined || data.name === undefined
            || data.market_price === undefined) {
            return [null, false];
        }

        // 先查找是否有同code的单价记录 @todo 后续可能会加入单位这个字段进一步确定唯一性
        let unitPriceData = await this.findDataByCondition({code: data.code, unit_price_file_id: unitPriceFileId}, null, false);

        // 如果有记录，判断是否存在一样的市场单价，有则直接返回数据
        let unitPriceIndex = this.isPriceIncluded(unitPriceData, data.market_price);
        if (unitPriceData && unitPriceIndex >= 0) {
            return [unitPriceData[unitPriceIndex], false];
        }

        // 如果不存在基价单价，则在数据源中获取
        if (data.base_price === undefined) {
            let firstUnitPrice = unitPriceData[0] !== undefined ? unitPriceData[0] : [];
            data.base_price = firstUnitPrice.base_price !== undefined ? firstUnitPrice.base_price : 0;
            data.type = firstUnitPrice.type !== undefined ? firstUnitPrice.type : 0;
            data.unit = firstUnitPrice.unit !== undefined ? firstUnitPrice.unit : 0;
        }

        // 更改名称
        if (gljCount > 0) {
            let regular = /\(\d\)/;
            let changeString = '(' + gljCount + ')';
            data.name = regular.test(data.name) ? data.name.replace(regular, changeString) :
                data.name + changeString;
        }

        let insertData = {
            code: data.code,
            base_price: data.base_price,
            market_price: data.market_price,
            unit_price_file_id: unitPriceFileId,
            name: data.name,
            type: data.type,
            unit: data.unit
        };

        let addPriceResult = await this.add(insertData);
        return [addPriceResult, true];
    }

    /**
     * 新增记录
     *
     * @param {object} data
     * @return {Promise}
     */
    async add(data) {
        let counterModel = new CounterModel();
        let unitPriceId = await counterModel.getId(collectionName);
        data.id = unitPriceId;

        this.setScene('add');
        return this.db.model.create(data);
    }

    /**
     * 判断数据中是否包含某个市场价格的记录
     *
     * @param {Array} data
     * @param {Number} price
     * @return {Number}
     */
    isPriceIncluded(data, price) {
        let index = -1;
        if (data.length <= 0) {
            return index;
        }
        for(let tmp in data) {
            if (data[tmp].market_price === price) {
                index = tmp;
                break;
            }
        }

        return index;
    }

    /**
     * 更新市场单价
     *
     * @param {Number} id
     * @param {Object} updateData
     * @return {Promise}
     */
    async updatePriceById(id, updateData) {
        id = parseInt(id);
        if (isNaN(id) || id <= 0 || Object.keys(updateData).length <= 0) {
            return false;
        }
        // 首先查找相应的数据判断工料机类型
        let unitPriceData = this.findDataByCondition({id: id});
        if (!unitPriceData) {
            throw '找不到对应的单价数据';
        }

        // 如果是主材、设备自动赋值基价单价=市场单价、调整基价=市场单价
        if (UnitPriceModel.autoChangeGLJType.indexOf(unitPriceData.type) >= 0) {
            updateData.base_price = updateData.market_price;
        }

        let result = await this.updateById(id, updateData);
        return result;
    }

}

export default UnitPriceModel;