'use strict';

/**
 *
 *
 * @author Mai
 * @date 2018/9/26
 * @version
 */

const settingConst = require('../const/setting.js');

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

        /**
         * 新增分类
         *
         * @param {Number} pid - 项目id
         * @param {String} name - 分类名称
         * @param {Number} type - 分类类型
         * @returns {Promise<{pid: *, name: *, type: *}>}
         */
        async addCategory(pid, name, type) {
            const count = await this.count({pid: pid, name: name});
            if (count > 0) {
                throw '存在同名类别';
            }

            const category = {
                pid: pid,
                name: name,
                type: type,
            };
            const result = await this.db.insert(this.tableName, category);
            if (result.affectedRows !== 1) {
                throw '提交数据失败';
            } else {
                category.id = result.insertId;
            }

            category.value = category.value && category.value !== '' ? JSON.parse(category.value) : [];
            return category;
        }

        /**
         * 大于level的分类level - 1
         *
         * @param {Number} pid - 项目id
         * @param {Number} level - level
         * @returns {Promise<*>}
         * @private
         */
        async _upLevelCategory(pid, level) {
            this.initSqlBuilder();
            this.sqlBuilder.setAndWhere('pid', {
                value: pid,
                operate: '='
            });
            this.sqlBuilder.setAndWhere('level', {
                value: level,
                operate: '>',
            });
            this.sqlBuilder.setUpdateData('level', {
                value: 1,
                selfOperate: '-',
            });
            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
            const data = await this.transaction.query(sql, sqlParam);

            return data;
        }
        /**
         * 删除分类
         * @param {Number} pid - 项目id
         * @param {Number} cid - 分类id
         * @returns {Promise<void>}
         */
        async deleteCategory(pid, cid) {
            const category = await this.getDataById(cid);
            if (category.pid !== pid) {
                throw '提交数据错误'
            }
            this.transaction = await this.db.beginTransaction();
            try {
                // 调整已用分类排序
                if (category.level >= 1) {
                    await this._upLevelCategory(pid, category.level);
                }
                // 删除标段分类数据
                const tenders = await this.ctx.service.tender.getList();
                for (const t of tenders) {
                    if (t.category && t.category.length > 0) {
                        this._.remove(t.category, function (c) {
                            return c.cid === cid;
                        });
                    }
                    await this.transaction.update(this.ctx.service.tender.tableName, {
                        id: t.id,
                        category: JSON.stringify(t.category),
                    });
                }
                // 删除分类数据
                await this.transaction.delete(this.tableName, {id: cid});
                // 删除分类值
                await this.transaction.delete(this.ctx.service.categoryValue.tableName, {cid: cid});
                await this.transaction.commit();
            } catch(err) {
                await this.transaction.rollback();
                throw err;
            }
        }

        /**
         * 获取分类数据
         *
         * @param {Number} id - 分类id
         * @returns {Promise<*>}
         */
        async getCategory(id) {
            const data = await this.getDataByCondition({id: id});
            data.value = await this.ctx.service.categoryValue.getAllDataByCondition({ where: {cid: id} });
            return data;
        }
        /**
         * 获取项目下全部分类数据
         *
         * @param {Number} pid - 标段id
         * @returns {Promise<*>}
         */
        async getAllCategory(pid) {
            const data = await this.getAllDataByCondition({where: {pid: pid}});
            const values = await this.ctx.service.categoryValue.getAllDataByCondition({ where: {pid: pid} });
            for (const d of data) {
                d.value = values.filter(function (v) {
                    return v.cid === d.id;
                });
            }
            return data;
        }

        /**
         * 重置分类已用排序
         *
         * @param {Array} data - 分类已用排序数据（TODO未做验证）
         * @returns {Promise<void>}
         */
        async resetCategoryLevel(data) {
            this.transaction = await this.db.beginTransaction();
            try {
                for (const d of data) {
                    this.transaction.update(this.tableName, {id: d.id, level: d.level});
                }
                this.transaction.commit();
            } catch (err) {
                await this.transaction.rollback();
                throw err;
            }
        }

    }

    return Category;
};