package com.dxhy.admin.sys.service.impl;

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

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dxhy.admin.sys.config.SysConfig;
import com.dxhy.admin.sys.dao.SysDeptDao;
import com.dxhy.admin.sys.entity.SysDeptEntity;
import com.dxhy.admin.sys.service.SysDeptService;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.util.redis.RedisUtils;
import com.dxhy.common.utils.Aops;
import com.dxhy.common.utils.Constant;
import com.dxhy.common.utils.PageUtils;
import com.dxhy.common.utils.Query;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author jiaohongyang
 */
@Service("sysDeptService")
@Slf4j
public class SysDeptServiceImpl extends ServiceImpl<SysDeptDao, SysDeptEntity> implements SysDeptService {
    @Resource
    private RedisUtils redisUtils;

    @Override
    public List<SysDeptEntity> queryList(String company) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        List<SysDeptEntity> deptList = baseMapper.queryList(company);
        long parentId = 0;
        if (StringUtils.isNotBlank(company)) {
            for (SysDeptEntity deptEntity : deptList) {
                if ("1".equals(deptEntity.getDeptType())) {
                    parentId = deptEntity.getParentId();
                    break;
                }
            }
        }
        return this.getChildPerms(deptList, parentId);
    }

    @Override
    public List<SysDeptEntity> queryList(String company, long parentId) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        List<SysDeptEntity> deptList = baseMapper.queryList(company);
        if(parentId == -1){
            parentId = 0;
            if (StringUtils.isNotBlank(company)) {
                for (SysDeptEntity deptEntity : deptList) {
                    if ("1".equals(deptEntity.getDeptType())) {
                        parentId = deptEntity.getParentId();
                        break;
                    }
                }
            }
        }
        return this.getChildPerms(deptList, parentId);
    }

    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list
     *            分类表
     * @param parentId
     *            传入的父节点ID
     * @return String
     */
    public List<SysDeptEntity> getChildPerms(List<SysDeptEntity> list, long parentId) {
        List<SysDeptEntity> returnList = new ArrayList<>();
        for (SysDeptEntity t : list) {
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if(t.getParentId() != null) {
                if (t.getParentId() == parentId) {
                    recursionFn(list, t);
                    returnList.add(t);
                }
            }
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     *            菜单列
     * @param t
     *            菜单信息
     */
    private void recursionFn(List<SysDeptEntity> list, SysDeptEntity t) {
        // 得到子节点列表
        List<SysDeptEntity> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysDeptEntity tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                for (SysDeptEntity n : childList) {
                    recursionFn(list, n);
                }
            }
        }
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysDeptEntity> list, SysDeptEntity t) {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 得到子节点列表
     */
    private List<SysDeptEntity> getChildList(List<SysDeptEntity> list, SysDeptEntity t) {
        List<SysDeptEntity> tlist = new ArrayList<>();
        for (SysDeptEntity n : list) {
            if (Objects.equals(n.getParentId(), t.getDeptId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    @Override
    public List<SysDeptEntity> queryListUser(String company) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryListUser(company);
    }

    @Override
    public List<SysDeptEntity> queryListParentTree(String company) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        List<SysDeptEntity> deptList = baseMapper.queryListParent(company);
        long parentId = 0;
        if (StringUtils.isNotBlank(company)) {
            for (SysDeptEntity deptEntity : deptList) {
                if ("1".equals(deptEntity.getDeptType())) {
                    parentId = deptEntity.getParentId();
                    break;
                }
            }
        }
        return this.getChildPerms(deptList, parentId);
    }

    @Override
    public List<SysDeptEntity> queryListParent(String company) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryListParent(company);
    }

    @Override
    public List<Long> queryDetpIdList(Long parentId) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryDetpIdList(parentId);
    }

    @Override
    public List<Long> getSubDeptIdList(Long deptId) {
        // 部门及子部门ID列表
        List<Long> deptIdList = new ArrayList<>();

        // 获取子部门ID
        List<Long> subIdList = queryDetpIdList(deptId);
        getDeptTreeList(subIdList, deptIdList);

        return deptIdList;
    }

    /**
     * 递归
     */
    public void getDeptTreeList(List<Long> subIdList, List<Long> deptIdList) {
        for (Long deptId : subIdList) {
            List<Long> list = queryDetpIdList(deptId);
            if (list.size() > 0) {
                getDeptTreeList(list, deptIdList);
            }

            deptIdList.add(deptId);
        }
    }

    /**
     * 分页查询组织机构信息
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        String deptId = (String)params.get("deptId");
        String company = (String)params.get("company");
        IPage<SysDeptEntity> page = this.page(new Query<SysDeptEntity>().getPage(params),
            new QueryWrapper<SysDeptEntity>().eq(StringUtils.isNoneBlank(deptId), "parent_id", deptId)
                .eq(StringUtils.isNoneBlank(company), "company", company)
                .eq(StringUtils.isBlank(deptId), "org_type", "1")
                .apply(params.get(Constant.SQL_FILTER) != null, (String)params.get(Constant.SQL_FILTER)));
        return new PageUtils(page);
    }

    @Override
    public List<SysDeptEntity> queryDept(String company, String orgType) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return this.baseMapper.selectDeptByCompany(company, orgType);
    }

    @Override
    public void saveDept(SysDeptEntity dept) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        dept.setCreateTime(DateUtil.date());
        dept.setUpdateTime(DateUtil.date());
        Aops.getSelf(this).insertDept(dept);
        // //获取可以采集的机构税号存放到redis
        // List<SysDeptEntity> queryDeptList = this.queryDeptList();
        // //重新保存redis
        // redisUtils.set(RedisConstant.KEY_DEPT, queryDeptList);

    }

    @Transactional(rollbackFor = Exception.class)
    public void insertDept(SysDeptEntity dept) {
        baseMapper.insert(dept);
    }

    public List<SysDeptEntity> queryDeptList() {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryDeptList();
    }

    @Override
    public void updateDept(SysDeptEntity dept) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        dept.setUpdateTime(DateUtil.date());
        Aops.getSelf(this).updateDeptId(dept);
        // //获取可以采集的机构税号存放到redis
        // List<SysDeptEntity> queryDeptList = this.queryDeptList();
        // //重新保存redis
        // redisUtils.set(RedisConstant.KEY_DEPT, queryDeptList);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateDeptId(SysDeptEntity dept) {
        baseMapper.updateById(dept);
        baseMapper.updateDeptCompany(dept.getCompany(), dept.getIsCollext(), dept.getAceKey(), dept.getAceId(),
            dept.getDbName(), dept.getQsStatus());
    }

    @Override
    public void deleteDept(Long id) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        Aops.getSelf(this).deleteById(id);
        // //获取可以采集的机构税号存放到redis
        // List<SysDeptEntity> queryDeptList = this.queryDeptList();
        // //重新保存redis
        // redisUtils.set(RedisConstant.KEY_DEPT, queryDeptList);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) {
        baseMapper.deleteById(id);
    }

    @Override
    public SysDeptEntity queryDeptById(Long deptId) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.selectById(deptId);
    }

    @Override
    public Integer queryDeptTaxNo(String taxno, String orgtype, String company, Long deptId, String orgCode) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        Integer count = 0;
        switch (orgtype) {
            case "5":
                if (StringUtils.isNotBlank(orgCode)) {
                    count = Math.toIntExact(baseMapper.selectCount(new QueryWrapper<SysDeptEntity>()
                            .eq("org_code", orgCode).eq("org_type", orgtype).ne(deptId != null, "dept_id", deptId)));
                } else {
                    count = Math.toIntExact(baseMapper.selectCount(new QueryWrapper<SysDeptEntity>().eq("taxno", taxno)
                            .eq("org_type", orgtype).ne(deptId != null, "dept_id", deptId)));
                }
                break;
            case "1":
                count = Math.toIntExact(baseMapper.selectCount(new QueryWrapper<SysDeptEntity>().eq("org_type", orgtype)
                        .eq("company", company).ne(deptId != null, "dept_id", deptId)));
                break;
            case "8":
                count = Math.toIntExact(baseMapper.selectCount(new QueryWrapper<SysDeptEntity>().eq("taxno", taxno)
                        .eq("org_type", orgtype).eq("company", company).ne(deptId != null, "dept_id", deptId)));
                break;
            default:
                break;
        }

        return count;
    }

    @Override
    public void saveDeptList(List<SysDeptEntity> deptList) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        Aops.getSelf(this).insertDeptList(deptList);
        // //获取可以采集的机构税号存放到redis
        // List<SysDeptEntity> queryDeptList = this.queryDeptList();
        // //重新保存redis
        // redisUtils.set(RedisConstant.KEY_DEPT, queryDeptList);
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertDeptList(List<SysDeptEntity> deptList) {
        this.saveOrUpdateBatch(deptList);
    }

    @Override
    public void deleteDeptList(List<SysDeptEntity> dept) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        for (SysDeptEntity sysDeptEntity : dept) {
            Aops.getSelf(this).deleteById(sysDeptEntity.getDeptId());
        }
        // //获取可以采集的机构税号存放到redis
        // List<SysDeptEntity> queryDeptList = this.queryDeptList();
        // //重新保存redis
        // redisUtils.set(RedisConstant.KEY_DEPT, queryDeptList);

    }

    @Override
    public PageUtils queryVenderDept(Map<String, Object> params) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        String company = (String)params.get("company");
        IPage<SysDeptEntity> page = this.page(new Query<SysDeptEntity>().getPage(params),
            new QueryWrapper<SysDeptEntity>().eq(StringUtils.isNoneBlank(company), "company", company)
                .in("org_type", "8", "9")
                .apply(params.get(Constant.SQL_FILTER) != null, (String)params.get(Constant.SQL_FILTER)));
        return new PageUtils(page);
    }

    @Override
    public List<SysDeptEntity> queryDeptParentId(Long parentId) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.selectList(new QueryWrapper<SysDeptEntity>().eq("parent_id", parentId).eq("org_type",
            SysConfig.OrgType.ORG_TYPE_5.getCode()));
    }

    @Override
    public SysDeptEntity queryDeptTaxno(String company, String taxno) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.selectOne(new QueryWrapper<SysDeptEntity>().eq("taxno", taxno).eq("company", company)
            .eq("org_type", SysConfig.OrgType.ORG_TYPE_5.getCode()));
    }

    @Override
    public List<String> getOrgCodeList(Long userId) {
        return baseMapper.getOrgCodeList(userId);
    }

}
