'use strict';

/**
 *
 *
 * @author Mai
 * @date
 * @version
 */
const payConst = require('../const/deal_pay.js');
const writableFields = ['name', 'minus', 'sprice', 'sexpr', 'rprice', 'rexpr', 'is_yf', 'dl_type', 'dl_count', 'dl_tp_type', 'dl_tp'];

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

        /**
         * 初始化 合同支付数据
         * @param transaction
         * @returns {Promise<boolean>}
         */
        async addDefaultPayData(tid, transaction) {
            const existPays = this.getAllDataByCondition({tid: tid});
            const pays = JSON.parse(JSON.stringify(payConst.payTemplate));
            if (existPays.length >= pays.length) { return false; }

            for (const p of pays) {
                p.tid = tid;
                p.csid = 0;
                p.cstimes = 0;
                p.csorder = 0;
                p.csaorder = 0;
            }
            let result;
            if (transaction) {
                result = await transaction.insert(this.tableName, pays);
            } else {
                result = await this.db.insert(this.tableName, pays);
            }
            return result.affectedRows === pays.length;
        }

        async _getMaxOrder(tenderId) {
            const sql = 'SELECT Max(??) As value FROM ?? Where tid = ' + tenderId;
            const sqlParam = ['order', this.tableName];
            const queryResult = await this.db.queryOne(sql, sqlParam);
            return queryResult.value;
        }

        /**
         * 新增合同支付项
         * @returns {Promise<*>}
         */
        async add() {
            if (!this.ctx.tender || !this.ctx.stage) {
                throw '数据错误';
            }
            const order = await this._getMaxOrder(this.ctx.tender.id);
            const pay = {
                tid: this.ctx.tender.id,
                csid: this.ctx.stage.id,
                cstimes: this.ctx.stage.times,
                csorder: this.ctx.stage.order,
                csaorder: this.ctx.stage.curOrder,
                uid: this.ctx.session.sessionUser.accountId,
                minus: false,
                ptype: payConst.payType.normal,
                order: order + 1,
            };

            const transaction = await this.db.beginTransaction();
            try {
                const result = await transaction.insert(this.tableName, pay);
                if (result.affectedRows !== 1) {
                    throw '新增合同支付项失败'
                }
                pay.id = result.insertId;

                const stagePay = await this.ctx.service.stagePay.syncAdd(pay, transaction);
                await transaction.commit();
                return this._.assign(pay, stagePay);
            } catch(err) {
                await transaction.rollback();
                throw err;
            }
        }

        /**
         * 删除合同支付项
         * @param id
         * @returns {Promise<void>}
         */
        async del(id) {
            if (!this.ctx.tender || !this.ctx.stage) {
                throw '数据错误';
            }
            // 检查是否可以删除
            const pay = await this.getDataByCondition({id: id});
            if (!pay) {
                throw '合同支付项不存在';
            } else if (pay.ptype !== payConst.payType.normal) {
                throw '该合同支付项不可删除';
            }
            // 删除合同支付
            const transaction = await this.db.beginTransaction();
            try {
                // 假删除
                //const result = await transaction.delete(this.tableName, {id: id});
                const result = await transaction.update(this.tableName, {
                    id: id,
                    valid: false,
                });
                if (result.affectedRows !== 1) {
                    throw '删除合同支付项失败'
                }
                await transaction.commit();
                return true;
            } catch(err) {
                await transaction.rollback();
                throw err;
            }
        }

        /**
         * 交换两个合同支付项的顺序
         * @param {Number} id1 - 合同支付项1的id
         * @param {Number} id2 - 合同支付项1的id
         * @returns {Promise<void>}
         */
        async changeOrder(id1, id2) {
            if (!this.ctx.tender || !this.ctx.stage) {
                throw '数据错误';
            }
            const pay1 = await this.getDataByCondition({tid: this.ctx.tender.id, id: id1});
            const pay2 = await this.getDataByCondition({tid: this.ctx.tender.id, id: id2});
            if (!pay1 || !pay2) {
                throw '数据错误';
            }

            const transaction = await this.db.beginTransaction();
            try {
                const order = pay1.order;
                pay1.order = pay2.order;
                pay2.order = order;
                await transaction.update(this.tableName, {id: pay1.id, order: pay1.order});
                await transaction.update(this.tableName, {id: pay2.id, order: pay2.order});
                await transaction.commit();
                return true;
            } catch (err) {
                await transaction.rollback();
                throw err;
            }
        }

        async _save(data, transaction) {
            const pay = await this.getDataByCondition({tid: this.ctx.tender.id, id: data.id});
            if(!pay) {
                throw '数据错误';
            }
            const updateData = this.ctx.helper.filterValidFields(data, writableFields);
            updateData.id = data.id;
            if (transaction) {
                const result = await transaction.update(this.tableName, updateData);
                if (result.affectedRows !== 1) {
                    throw '更新数据失败';
                }
            } else {
                const result = await this.db.update(this.tableName, updateData);
                if (result.affectedRows !== 1) {
                    throw '更新数据失败';
                }
            }
            return updateData;
        }

        /**
         * 保存合同支付项数据
         * @param data
         * @returns {Promise<boolean>}
         */
        async save(data) {
            if (!this.ctx.tender || !this.ctx.stage) { return false; }

            if (data instanceof Array) {
                const transaction = await this.db.beginTransaction();
                const result = [];
                try {
                    for (const d of data) {
                        const updateData = await this._save(d, transaction);
                        result.push(updateData);
                    }
                    await transaction.commit();
                } catch(err) {
                    await transaction.rollback();
                    throw err;
                }
                return result;
            } else {
                const pay = await this.getDataByCondition({tid: this.ctx.tender.id, id: data.id});
                if(!pay) {
                    throw '数据错误';
                }
                const updateData = this.ctx.helper.filterValidFields(data, writableFields);
                updateData.id = data.id;
                const result = await this.db.update(this.tableName, updateData);
                if (result.affectedRows !== 1) {
                    throw '更新数据失败';
                }
                return updateData;
            }
        }
    }

    return Pay;
};