'use strict';

/**
 * 中间计量--计量清单 数据模型
 *
 * @author Mai
 * @date 2018/6/27
 * @version
 */

module.exports = app => {

    class MeasureBills extends app.BaseService {

        /**
         * 构造函数
         *
         * @param {Object} ctx - egg全局变量
         * @return {void}
         */
        constructor(ctx) {
            super(ctx);
            this.tableName = 'measure_bills';
        }

        /**
         * 查询中间计量下清单信息
         *
         * @param {Number} tenderId - 标段id
         * @param {uuid} mid - 中间计量id
         * @returns {Promise<*>}
         */
        async getBillsDetail(tenderId, mid) {
            const sql = 'SELECT MB.`tender_id`, MB.`mid`, MB.`bid`, L.`code`, L.`name`, L.`full_path` ' +
                'FROM ?? AS L, ?? AS MB ' +
                'WHERE L.`tender_id` = ? and MB.`tender_id` = ? and MB.`mid` = ? ' +
                '    and MB.`bid` = L.`ledger_id`';
            const sqlParam = [this.ctx.service.ledger.tableName, this.tableName, tenderId, tenderId, mid];
            return await this.db.query(sql, sqlParam);
        }

        /**
         *
         * @param tenderId
         * @param mid
         * @param ids
         * @returns {Promise<*>}
         * @private
         */
        async _getUnionBillsData(tenderId, mid, ids) {
            const sql = 'SELECT L.*, MB.`deal_quantity`, MB.`deal_totalprice`, MB.`qc_quantity`, MB.`qc_totalprice` ' +
                'FROM ?? AS L, ?? AS MB ' +
                'WHERE L.`tender_id` = ? and L.`ledger_id` IN (' + ids.join(',') + ') and MB.`tender_id` = ? and MB.`mid` = ?' +
                '    and MB.`bid` = L.`ledger_id` ' +
                'UNION ' +
                'SELECT L.*, Null, Null, Null, Null ' +
                'FROM ?? AS L ' +
                'WHERE L.`tender_id` = ? and L.`ledger_id` IN (' + ids.join(',') + ') and L.`is_leaf` = false';
            const sqlParam = [this.ctx.service.ledger.tableName, this.tableName, tenderId, tenderId, mid,
                this.ctx.service.ledger.tableName, tenderId];
            return await this.db.query(sql, sqlParam);
        };

        /**
         * 查询中间计量下清单(含父项)
         * @param {Number} tenderId - 标段id
         * @param {uuid} mid - 中间计量id
         * @returns {Promise<Array>}
         */
        async getBillsDetailWithParent(tenderId, mid) {
            const bills = await this.getBillsDetail(tenderId, mid);
            if (bills.length > 0) {
                let ids = [];
                for (const b of bills) {
                    ids = ids.concat(b.full_path.split('.'));
                }
                return await this._getUnionBillsData(tenderId, mid, ids);
                //return await this.ctx.service.ledger.getDataByNodeIds(tenderId, ids);
            } else {
                return [];
            }
        }

        /**
         * 查询中间计量下，某一条清单信息
         * @param {Number} tenderId - 标段id
         * @param {uuid} mid - 计量id
         * @param {Number} bid - 清单id
         * @returns {Promise<*>}
         */
        async getBillsData(tenderId, mid, bid) {
            const sql = 'SELECT MB.`tender_id`, MB.`mid`, MB.`bid`, L.`code`, L.`name`, L.`full_path` ' +
                'FROM ?? AS L, ?? AS MB ' +
                'WHERE L.`tender_id` = ? and MB.`tender_id` = ? and MB.`mid` = ?  and MB.bid = ?' +
                '    and MB.`bid` = L.`ledger_id`';
            const sqlParam = [this.ctx.service.ledger.tableName, this.tableName, tenderId, tenderId, mid, bid];
            return await this.db.queryOne(sql, sqlParam);
        }

        /**
         * 查询中间计量下，某一条清单信息(含父项)
         * @param {Number} tenderId - 标段id
         * @param {uuid} mid - 计量id
         * @param {Number} bid - 清单id
         * @returns {Promise<*>}
         */
        async getBillsDataWithParent(tenderId, mid, bid) {
            const bills = await this.getBillsData(tenderId, mid, bid);
            const ids = bills.full_path.split('.');
            return await this._getUnionBillsData(tenderId, mid, ids);
            //return await this.ctx.service.ledger.getDataByNodeIds(tenderId, bills.full_path.split('.'));
        }

        /**
         * 新增计量清单
         * @param {Number} tenderId - 标段id
         * @param {uuid} mid - 计量id
         * @param {Number} bid - 清单id
         * @returns {Promise<void>}
         */
        async addBills(tenderId, mid, bid) {
            const result = await this.db.insert(this.tableName, {
                tender_id: tenderId,
                mid: mid,
                bid: bid,
                in_time: new Date(),
                in_user: this.ctx.session.sessionUser.accountId,
            });
        }

        /**
         * 移除计量清单
         * @param {Number} tenderId - 标段id
         * @param {uuid} mid - 计量id
         * @param {Number} bid - 清单id
         * @returns {Promise<void>}
         */
        async removeBills(tenderId, mid, bid) {
            await this.db.delete(this.tableName, {
                tender_id: tenderId,
                mid: mid,
                bid: bid,
            });
        }

        /**
         * 更新计量清单并计算
         * @param {Number} tenderId - 标段id
         * @param {uuid} mid - 计量id
         * @param {Number} bid - 清单id
         * @param {Object} data - 更新数据
         * @returns {Promise<*>}
         */
        async updateBills(tenderId, mid, bid, data) {
            const bills = await this.ctx.service.ledger.getDataByNodeId(tenderId, bid);
            if (data.deal_quantity) {
                data.deal_totalprice = data.deal_quantity * bills.unit_price;
            } else if (data.qc_quantity) {
                data.qc_totalprice = data.qc_quantity * bills.unit_price;
            } else {
                throw '计量清单数据有误';
            }
            const result = await this.update(data, {
                tender_id: tenderId,
                mid: mid,
                bid: bid,
            });
            if (result) {
                data.ledger_id = bid;
                return data;
            } else {
                throw '更新数据失败';
            }
        }
    }

    return MeasureBills;
};