package gaf3.core.services.dept.service

import gaf3.core.exception.BusinessError
import gaf3.core.services.dept.dao.GafDeptItemDAO
import gaf3.core.services.dept.domain.DeptForm
import gaf3.core.services.dept.entity.GafDeptItem
import gaf3.core.util.DataBeanHelper
import gaf3.core.util.StringUtil
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.util.Assert
import java.util.*
import kotlin.streams.toList

@Service
class DeptService(@Autowired val itemDao: GafDeptItemDAO) {
    fun create(pid: String, data: DeptForm): GafDeptItem {
        // TODO: 检查数据约束
        Assert.notNull(data.code, "code不能为空")
        Assert.hasText(data.name, "name不能为空")
        // code可为空串，非空时必须唯一
        if(data.code != "" && itemDao.exists(data.code!!)) throw BusinessError(BusinessError.ERR_DATA_EXISTED, "部门编码已经存在")
        // 同一个部门下子部门名称不能相同
        if(itemDao.existsByPidAndName(pid, data.name!!)) throw BusinessError(BusinessError.ERR_DATA_EXISTED, "同一个部门下子部门名称不能相同")
        if(pid != "" && !itemDao.existsById(pid)) throw BusinessError(BusinessError.ERR_DATA_NOTEXIST, "上级部门不存在")

        // TODO: 保存数据
        var entity = GafDeptItem()
        DataBeanHelper.Bean2Obj(data, entity)
        entity.id = UUID.randomUUID().toString()
        entity.pid = pid
        entity = itemDao.save(entity)
        return entity
    }

    fun delete(id: String) {
        if(!itemDao.existsById(id)) throw BusinessError(BusinessError.ERR_DATA_NOTEXIST)
        if(itemDao.existsByPid(id)) throw BusinessError(BusinessError.ERR_SERVICE_FAULT, "存在下级部门，无法删除")
        itemDao.deleteById(id)
    }

    fun update(id: String, data: DeptForm): GafDeptItem {
        // TODO: 检查数据约束
        Assert.hasText(id, "ID不能为空")

        // TODO: 设置修改的属性
        var entity = itemDao.findByIdOrNull(id) ?: throw BusinessError(BusinessError.ERR_DATA_NOTEXIST)
        // TODO: 检查code是否重复
        if(!StringUtil.isNullOrEmpty(data.code) && data.code != entity.code && itemDao.exists(data.code!!)) {
            throw BusinessError(BusinessError.ERR_DATA_EXISTED, "部门编码已经存在")
        }
        DataBeanHelper.Bean2Obj(data, entity)

        entity = itemDao.save(entity)
        return entity
    }

    fun find(pid: String?, recursive: Boolean): List<GafDeptItem> {
        var rs = if(pid.isNullOrBlank()) itemDao.findRoot() else itemDao.findByPid(pid)
        if(recursive){
            val children = rs.parallelStream().map { p->find(p.id!!, recursive) }.toList().flatten()
            rs = rs + children
        }
        return rs
    }

    fun fetch(id: String): GafDeptItem? {
        return itemDao.findByIdOrNull(id)
    }
    
}