'use strict';

/**
 * 期计量 中间计量 详细数据
 *
 * @author Mai
 * @date 2019/2/13
 * @version
 */

module.exports = app => {
    class StageDetail extends app.BaseService {
        /**
         * 构造函数
         *
         * @param {Object} ctx - egg全局变量
         * @return {void}
         */
        constructor(ctx) {
            super(ctx);
            this.tableName = 'stage_detail';
        }

        /**
         * 查询最后审核人数据
         * @param {Number} tid - 标段id
         * @param {Number} sid - 期id
         * @param {Number|Array} lid - 台账节点id（可以为空）
         * @returns {Promise<*>}
         */
        async getLastestStageData(tid, sid, lid) {
            const lidSql = lid ? ' And Bills.lid in (?)' : '';
            const sql = 'SELECT * FROM ' + this.tableName + ' As Bills ' +
                '  INNER JOIN ( ' +
                '    SELECT MAX(`times`) As `times`, MAX(`order`) As `order`, `lid`, `uuid` From ' + this.tableName +
                '      GROUP BY `lid`, `uuid`' +
                '  ) As MaxFilter ' +
                '  ON Bills.times = MaxFilter.times And Bills.order = MaxFilter.order And Bills.lid = MaxFilter.lid And Bills.uuid = MaxFilter.uuid' +
                '  WHERE Bills.tid = ? And Bills.sid = ?' + lidSql;
            const sqlParam = [tid, sid];
            if (!lid) {
                return await this.db.query(sql, sqlParam);
            } else if (lid instanceof Array) {
                sqlParam.push(lid.join(', '));
                return await this.db.query(sql, sqlParam);
            } else {
                sqlParam.push(lid);
                return await this.db.queryOne(sql, sqlParam);
            }
        }

        /**
         * 获取 中间计量 用户最新输入数据
         * @param {Number} tid - 标段id
         * @param {Number} sid - 期id
         * @param {Number} lid - 关联的台账节点id
         * @param {String} uuid - 中间计量单 唯一id
         * @returns {Promise<*>}
         */
        async getLastestImStageData(tid, sid, lid, uuid) {
            const sql = 'SELECT * FROM ' + this.tableName + ' As Bills ' +
                '  INNER JOIN ( ' +
                '    SELECT MAX(`times`) As `times`, MAX(`order`) As `order`, `lid`, `uuid` From ' + this.tableName +
                '      WHERE lid = ? And uuid = ?' +
                '      GROUP BY `lid`, `uuid`' +
                '  ) As MaxFilter ' +
                '  ON Bills.times = MaxFilter.times And Bills.order = MaxFilter.order And Bills.lid = MaxFilter.lid And Bills.uuid = MaxFilter.uuid' +
                '  WHERE Bills.tid = ? And Bills.sid = ?';
            const sqlParam = [lid, uuid, tid, sid];
            return await this.db.queryOne(sql, sqlParam);
        }

        /**
         *
         * @param data
         * @returns {Promise<void>}
         */
        async saveDetailData(data) {
            if (data.uuid) {
                const org = await this.getLastestImStageData(this.ctx.tender.id, this.ctx.stage.id, data.lid, data.uuid);
                const order = this.ctx.stage.curAuditor ? this.ctx.stage.curAuditor.order : 0;
                if (org.times === this.ctx.stage.times && org.order === order) {
                    const newData = this._.assign(org, data);
                    await this.db.update(this.tableName, newData);
                } else {
                    data.uuid = org.uuid;
                    data.tid = this.ctx.tender.id;
                    data.sid = this.ctx.stage.id;
                    data.times = this.ctx.stage.times;
                    data.order = order;
                    await this.db.insert(this.tableName, data);
                }
            } else {
                data.uuid = this.uuid.v4();
                data.tid = this.ctx.tender.id;
                data.sid = this.ctx.stage.id;
                data.times = this.ctx.stage.times;
                data.order = this.ctx.stage.curAuditor ? this.ctx.stage.curAuditor.order : 0;
                await this.db.insert(this.tableName, data);
            }
        }
    }

    return StageDetail;
};