package com.sifang.modules.sunshine.SystemSetting.service;

import com.google.common.collect.Lists;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

import com.sifang.modules.sunshine.SystemSetting.dao.DepartmentSettingDao;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmDepartment;
import com.sifang.modules.sunshine.SystemSetting.form.DepartmentVo;
import com.sifang.modules.sunshine.SystemSetting.utils.Result;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.service.BaseService;
import com.sifang.modules.sys.common.utils.DateUtils;
import com.sifang.modules.sys.common.utils.IdGen;
import com.sifang.modules.sys.util.GuardUtils;
import com.sifang.modules.sys.util.SqlUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;


@Service
public class DepartmentSettingService extends BaseService {


    @Autowired
    private DepartmentSettingDao departmentSettingDao;

    public CrmDepartment getById(String id){
        return departmentSettingDao.get(id);
    }


    public List<DepartmentVo> getDepartList(String id) {
        // logger.info(" >> 系统设置获取部门列表数据 getDepartList");
        String sql1 = " SELECT d.id,d.name,d.code,d.parent_id,d.create_time FROM `crm_department` d  WHERE d.hierarchy=1 AND d.`status`='1' ORDER BY d.`sort` DESC  ";
        String sql2 = " SELECT d.id,d.name,d.code,d.parent_id,d.create_time,d.`sort` FROM `crm_department` d  WHERE d.hierarchy<>1 AND d.`status`='1' ORDER BY d.`sort` asc  ";
        List<DepartmentVo> list1 = setDepartmentVo(Db.find(sql1));
        List<DepartmentVo> list2 = setDepartmentVo(Db.find(sql2));
        for (DepartmentVo record1 : list1) {
            if(StringUtil.isNotBlank(id)){
                if(id.equals(record1.getId())){
                    record1.setChecked(true);
                }
            }
            List<DepartmentVo> list = getChildren(record1, list2,id);
            if (list.size() > 0) {
                record1.setChildren(list);
            }
        }
        return list1;
    }

    public List<DepartmentVo> setDepartmentVo(List<Record> list ){
        List<DepartmentVo> deps = Lists.newArrayList();
        if(list.size()>0){
            for(Record rd:list){
                DepartmentVo vo = new DepartmentVo();
                vo.setId(rd.getStr("id"));
                vo.setName(rd.getStr("name"));
                vo.setTitle(rd.getStr("name"));
                vo.setCreateTime(DateUtils.formatDateTime(rd.getDate("create_time")));
                vo.setCode(rd.getStr("code"));
                vo.setParentId(rd.getStr("parent_id"));
                vo.setHierarchy(rd.getInt("hierarchy"));
                vo.setFrontDepartment(rd.getStr("front_department"));
                deps.add(vo);
            }
        }

        return deps;
    }

    /**
     * 递归函数 获取下级部门
     *
     * @param
     * @return
     */
    public List<DepartmentVo> getChildren(DepartmentVo department, List<DepartmentVo> all,String depId) {
        List<DepartmentVo> child = new ArrayList<>();
        String id = department.getId();
        for (DepartmentVo record : all) {
            if(StringUtil.isNotBlank(id)){
                if(depId != null && depId.equals(record.getId())){
                    record.setChecked(true);
                }
            }
            if (id.equals(record.getParentId())) {
                child.add(record);
            }
        }
        for (DepartmentVo r : child) {
            List<DepartmentVo> li = getChildren(r, all,depId);
            if (li.size() > 0) {
                r.setChildren(li);
            }
        }
        return child;
    }

    public Result saveDepartment(CrmDepartment department ) {
        logger.info(" 保存部门 saveDepartment  FrontDepartment:{}", department.getFrontDepartment());
        Result result = new Result();
        GuardUtils.notBlank(department.getCode(), "部门编号不能为空！");
        GuardUtils.notBlank(department.getName(), "部门名称不能为空！");
        //校验部门编号和部门
        if (checkDeptName(department.getName(), department.getId())) {
            result.setMsg("该部门名称已存在！");
            result.setCode("202");
            return result;
        }
        if (checkDeptCode(department.getCode(), department.getId())) {
            result.setMsg("该部门编号已存在！");
            result.setCode("202");
            return result;
        }
        if (Objects.deepEquals("d56d5797dd9049fead6bb4c19040d2f0",department.getId())) {
            result.setMsg("该一级部门不可编辑！");
            result.setCode("202");
            return result;
        }

        String front_department="";
        int hier = 1;
        if (StringUtil.isNotBlank(department.getParentId())) {
            CrmDepartment par = departmentSettingDao.get(department.getParentId());
            hier = par.getHierarchy() + 1;
            front_department = par.getFrontDepartment();
        }

        department.setHierarchy(hier);
        User currentUser = UserUtils.getUser();
        if (StringUtil.isBlank(department.getId())) {
            department.setId(IdGen.uuid());
            department.setCreateTime(new Date());
            department.setCreateBy(currentUser.getId());
            department.setStatus("1");
            department.setFrontDepartment(StringUtil.isNotBlank(front_department)?front_department+","+department.getParentId():department.getParentId());
            departmentSettingDao.save(department);
        } else {
            CrmDepartment oldDepart = departmentSettingDao.get(department.getId());
            oldDepart.setCode(department.getCode());
            oldDepart.setName(department.getName());
            oldDepart.setParentId(department.getParentId());
            oldDepart.setFrontDepartment(front_department+","+department.getParentId());
            int oldHierarchy = oldDepart.getHierarchy();
            if (oldHierarchy > hier) {
                //修改部门时，层级改变了，那么该部门下的所有子部门也要变更层级
                List<String> listChild = getAllChildDepartment(oldDepart.getId());
                int cha = oldHierarchy - hier;
                if (listChild.size() > 0) {
                    int count = Db.update(" UPDATE `crm_department` SET hierarchy=hierarchy-?  WHERE id IN (" + SqlUtils.inParam(listChild) + ") ", cha);
                    logger.info(">>>>>>>修改部门时，变更的子部门   size:{}  ;  count :{} ", listChild.size(), count);
                }
            }
            oldDepart.setHierarchy(department.getHierarchy());
            departmentSettingDao.save(oldDepart);

        }
        result.setCode("200");
        result.setMsg("保存成功！");
        return result;
    }

    //根据部门，获取所有要修改的下级部门
    public List<String> getAllChildDepartment(String id) {
        List<CrmDepartment> departments = new ArrayList<>();
        CrmDepartment dep = departmentSettingDao.get(id);
        List<String> list = new ArrayList<>();
        int cj = dep.getHierarchy();
        if ("1".equals(cj)) {
            //一级部门
            return list;
        }
        if (cj == 2) { //二级部门
            //查三级部门
            List<String> rds = Db.query("SELECT id FROM crm_department WHERE STATUS='1' AND parent_id=? ", dep.getId());
            list.addAll(rds);
            //查四级部门
            List<String> rds2 = Db.query("SELECT id FROM crm_department WHERE STATUS='1' AND parent_id in(" + SqlUtils.inParam(rds) + ") ");
            list.addAll(rds2);
            //查五级部门
            List<String> rds3 = Db.query(" SELECT id FROM crm_department WHERE STATUS='1' AND parent_id in(" + SqlUtils.inParam(rds2) + ") ");
            list.addAll(rds3);

        } else if (cj == 3) { //三级部门
            //查四级部门
            List<String> rds = Db.query("SELECT id FROM crm_department WHERE STATUS='1' AND parent_id=? ", dep.getId());
            list.addAll(rds);
            //查五级部门
            List<String> rds2 = Db.query("SELECT id FROM crm_department WHERE STATUS='1' AND parent_id in (" + SqlUtils.inParam(rds) + " ");
            list.addAll(rds2);
        } else if (cj == 4) { //四级部门
            //查五级部门
            List<String> rds = Db.query("SELECT id FROM crm_department WHERE STATUS='1' AND parent_id=? ", dep.getId());
            list.addAll(rds);
        }
        return list;
    }

    public Boolean checkDeptName(String name, String id) {
        StringBuffer sb = new StringBuffer();
        sb.append(" SELECT COUNT(d.id) FROM `crm_department` d WHERE d.`status`='1' AND d.name=? ");
        if (StringUtil.isNotBlank(id)) {
            sb.append(" and d.id <> '" + id + "'");
        }
        Long count = Db.queryLong(sb.toString(), name);
        if (count > 0) {
            return true;
        }
        return false;
    }

    public Boolean checkDeptCode(String code, String id) {
        StringBuffer sb = new StringBuffer();
        sb.append(" SELECT COUNT(d.id) FROM `crm_department` d WHERE d.`status`='1' AND d.code=? ");
        if (StringUtil.isNotBlank(id)) {
            sb.append(" and d.id <> '" + id + "'");
        }
        Long count = Db.queryLong(sb.toString(), code);
        if (count > 0) {
            return true;
        }
        return false;
    }

    public Result deleteDepartment(String id) {
        Result reslut = new Result();
        if (StringUtil.isBlank(id)) {
            reslut.setCode("203");
            reslut.setMsg("请求参数为空！");
            return reslut;
        }
        if (Objects.deepEquals("d56d5797dd9049fead6bb4c19040d23",id)) {
            reslut.setMsg("该一级部门不可删除！");
            reslut.setCode("203");
            return reslut;
        }
        //判断是不是有下级部门
        String sq = " SELECT COUNT(d.id) FROM `crm_department` d WHERE d.parent_id=? AND d.status='1'  ";
        long counDept = Db.queryLong(sq, id);
        if (counDept > 0) {
            reslut.setCode("203");  // 有下级部门不可删除。
            reslut.setMsg("有下级部门，不能删除！");
            return reslut;
        }
        String sql = "SELECT COUNT(id) FROM `sys_user` WHERE department_id=? AND STATUS='0'";
        Long count = Db.queryLong(sql, id);
        if (count > 0) {
            reslut.setCode("203");  // 有在职员工则不可删除。
            reslut.setMsg("该部门下有在职员工，不可删除！");
            return reslut;
        } else {
            String sql2 = " UPDATE `crm_department` d SET d.status='2' WHERE d.id=? ";
            Db.update(sql2, id);
        }
        reslut.setCode("200");
        return reslut;
    }

    public List<Record> getAllTopDept() {
        String sql = " SELECT d.id,d.name FROM `crm_department` d where d.hierarchy='1' AND d.`status`='1' ORDER BY d.`create_time` DESC ";
        return Db.find(sql);
    }

    public List<Record> getTopDeptByTwo() {
        String sql = " SELECT d.id,d.name FROM `crm_department` d where d.hierarchy='2' AND d.`status`='1' ORDER BY d.`create_time` DESC ";
        return Db.find(sql);
    }

    public List<DepartmentVo> getDepartmentAll(String id) {
      /*  if(StringUtil.isNotBlank(id)){  //修改部门时   获取上级 部门
            CrmDepartment department=CrmDepartment.dao.findById(id);
            int hierarchy=department.getHierarchy();
            return CrmDepartment.dao.find("SELECT * FROM crm_department WHERE STATUS='1' and id !=? AND hierarchy <?",id,hierarchy);
        }
        return CrmDepartment.dao.find("SELECT * FROM crm_department WHERE STATUS='1' AND hierarchy<>'5' ");*/

        if (StringUtil.isNotBlank(id)) {  //修改部门时   获取上级 部门
            logger.info(" >> 修改部门时 获取所有的所属部门信息  getDepartmentAll");
            CrmDepartment department = departmentSettingDao.get(id);
            int hierarchy = department.getHierarchy();
            /* return CrmDepartment.dao.find("SELECT * FROM crm_department WHERE STATUS='1' and id !=? AND hierarchy <?",id,hierarchy);*/
            String sql1 = " SELECT d.id,d.name,d.code,d.parent_id,d.create_time FROM `crm_department` d  WHERE d.hierarchy=1 AND d.`status`='1' ORDER BY d.`create_by` DESC  ";
            String sql2 = " SELECT d.id,d.name,d.code,d.parent_id,d.create_time FROM `crm_department` d  WHERE  id !=? and d.hierarchy <? and d.hierarchy<>'1' AND d.`status`='1'  ORDER BY d.`create_by` asc  ";
            List<DepartmentVo> list1 = setDepartmentVo(Db.find(sql1));
            List<DepartmentVo> list2 = setDepartmentVo(Db.find(sql2, id, hierarchy));
            if (list2.size() == 0) {
                return list1;
            }
            for (DepartmentVo record1 : list1) {
                List<DepartmentVo> li = getChildren(record1, list2,id);
                if (li.size() > 0) {
                    record1.setChildren(li);
                }
            }
            return list1;
        } else {
            logger.info(" >> 新建部门时 获取所有的所属部门信息  getDepartmentAll");
            String sql1 = " SELECT d.id,d.name,d.code,d.parent_id,d.create_time FROM `crm_department` d  WHERE d.hierarchy=1 AND d.`status`='1' ORDER BY d.`create_by` DESC  ";
            String sql2 = " SELECT d.id,d.name,d.code,d.parent_id,d.create_time FROM `crm_department` d  WHERE d.hierarchy not in('1','5') AND d.`status`='1' ORDER BY d.`create_by` asc  ";
            List<DepartmentVo> list1 = setDepartmentVo(Db.find(sql1));
            List<DepartmentVo> list2 = setDepartmentVo(Db.find(sql2));
            if (list2.size() == 0) {
                return list1;
            }
            for (DepartmentVo record1 : list1) {
                List<DepartmentVo> l2 = getChildren(record1, list2,id);
                if (l2.size() > 0) {
                    record1.setChildren(l2);
                }
            }
            return list1;
        }
    }

    /**
     * 获取部门分层级。
     *
     * @param depId 带获取部门的层级
     * @return 该部门的层级
     */
    public long getDepLevel(String depId) {
        if (StringUtils.isBlank(depId)) {
            return 0;
        }
        return Db.queryLong("select hierarchy from crm_department where id=?", depId);
    }

    /**
     * subLevel:
     * <p>
     * 0: 全国
     * 1: 一级部门
     * 2: 二级部门
     * 3: 三级部门
     * 4: 四级部门
     *
     * @param depId    部门id
     * @param subLevel depId部门下的某个层级，注意这个层级也是从顶级开始计数的。
     * @return 指定部门下某个层级的所有子部门
     */
    public List<String> getSubDeps(String depId, int subLevel) {
        logger.info(">>>>>>>>> getSubDeps depId:{};subLevel:{};", depId, subLevel);
        if (StringUtils.isBlank(depId)) { // admin的depId为空
            List<String> ret = new ArrayList<>();
            List<Record> records;
            if (subLevel == 0) {
                records = Db.find("select id from crm_department where status='1'");
            } else {
                records = Db.find("select id from crm_department where status='1' and hierarchy=?", subLevel);
            }
            for (Record r : records) {
                ret.add(r.getStr("id"));
            }
            return ret;
        }
        int levelDiff = subLevel - (int) getDepLevel(depId);
        if (levelDiff < 0) {
            throw new IllegalArgumentException("invalid sub level: " + subLevel);
        }
        List<String> ids = new ArrayList<>();
        ids.add(depId);
        logger.info(">>>>>>>>>>>>>>>>>>>>>>> getSubDeps :{}", ids);
        for (int i = 0; i < levelDiff; i++) {
            if (ids.size() == 0 & i <= levelDiff - 1) {
                return ids;
            }
            List<Record> records = Db.find("select id from crm_department where status='1' and parent_id in " + SqlUtils.inParam(ids));
            List<String> tmp = new ArrayList<>();
            for (Record r : records) {
                tmp.add(r.getStr("id"));
            }
            ids = tmp;
        }
        return ids;
    }
}
