'use strict';

async function getdep (ctx) {
    try {
        const { fs: { api: { userInfo } } } = ctx
        const models = ctx.fs.dc.models;

        let depLevel0 = await models.Department.findAll({
            order: [['id', 'asc']],
            where: {
                // id: userInfo.departmentId
                dependence: null,
                delete: false
            },
        })

        let depRslt = []
        const getDep = async (d) => {
            let subordinate = []
            let depRes = await models.Department.findAll({
                order: [['id', 'asc']],
                where: {
                    dependence: d.id,
                    delete: false
                },
            })
            if (depRes.length)
                for (let d of depRes) {
                    let dep = d.dataValues
                    dep.subordinate = await getDep(d.dataValues)
                    subordinate.push(dep)
                }
            return subordinate
        }
        for (let d of depLevel0) {
            let dep0 = d.dataValues
            dep0.subordinate = await getDep(d.dataValues)
            depRslt.push(dep0)
        }

        ctx.status = 200;
        ctx.body = depRslt
    } catch (error) {
        ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
        ctx.status = 400;
        ctx.body = {}
    }
}

async function editDep (ctx) {
    try {
        const models = ctx.fs.dc.models;
        const { depId, name, dependence } = ctx.request.body;
        if (dependence) {
            let dep = await models.Department.findOne({
                where: {
                    id: dependence,
                    delete: false
                },
            })
            if (!dep) {
                ctx.status = 400;
                ctx.body = {
                    "message": "上级部门不存在"
                }
                return
            }
        }
        if (depId) {
            await models.Department.update({
                name: name,
                dependence: dependence || null,
            }, {
                where: {
                    id: depId
                }
            })
        } else {
            await models.Department.create({
                name: name,
                delete: false,
                dependence: dependence || null,
            })
        }
        ctx.status = 204;
    } catch (error) {
        ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
        ctx.status = 400;
        ctx.body = {}
    }
}

async function delDep (ctx) {
    const transaction = await ctx.fs.dc.orm.transaction();
    try {
        const models = ctx.fs.dc.models;
        const { depId } = ctx.params;

        let depIds = []
        let depLevel0 = await models.Department.findAll({
            where: {
                id: depId
            },
        })

        const getDep = async (d) => {
            let depRes = await models.Department.findAll({
                where: {
                    dependence: d.id,
                    delete: false
                },
            })
            if (depRes.length)
                for (let d of depRes) {
                    depIds.push(d.dataValues.id)
                    await getDep(d.dataValues)
                }
        }
        for (let d of depLevel0) {
            depIds.push(d.id)
            getDep(d.dataValues)
        }

        const undeleteUserCount = await models.User.count({
            where: {
                departmentId: {
                    $in: depIds
                },
                delete: false
            }
        })
        if (undeleteUserCount) {
            throw '该部门下有用户,不能删除'
        }

        await models.Department.update({
            delete: true,
        }, {
            where: {
                id: { $in: depIds },
            },
            transaction
        })
        await models.User.update({
            delete: true,
        }, {
            where: {
                departmentId: { $in: depIds },
            },
            transaction
        })

        await transaction.commit();
        ctx.status = 204;
    } catch (error) {
        await transaction.rollback();
        ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
        ctx.status = 400;
        ctx.body = {
            message: typeof error == 'string' ? error : undefined
        }
    }
}

module.exports = {
    getdep, editDep, delDep,
};