package com.zcxk.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zcxk.dao.OrgMapper;
import com.zcxk.dto.OrgBaseTreeInfoDto;
import com.zcxk.dto.OrgTree;
import com.zcxk.entity.Org;
import com.zcxk.model.LoginUser;
import com.zcxk.model.ProgramItem;
import com.zcxk.service.OrgService;
import com.zcxk.util.ByteArrayUtils;
import com.zcxk.util.RedisUtil;
import com.zcxk.util.UserUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

import static com.google.common.collect.Lists.newArrayList;

/**
 * 组织(Org表)服务实现类
 *
 * @author makejava
 * @since 2020-10-26 14:55:43
 */
@Service("orgService")
public class OrgServiceImpl implements OrgService {
    @Resource
    private OrgMapper orgMapper;
    @Autowired
    private RedisUtil redisUtil;


    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Org selectById(Integer id) {
        return this.orgMapper.selectById(id);
    }


    /**
     * 查询所有
     *
     * @return 实例对象的集合
     */
    @Override
    public List<Org> selectAll() {
        return this.orgMapper.selectAll();
    }

    /**
     * 根据条件查询
     *
     * @return 实例对象的集合
     */
    @Override
    public List<Org> selectList(Org org) {
        return this.orgMapper.selectList(org);
    }

    /**
     * 新增数据
     *
     * @param org 实例对象
     * @return 实例对象
     */
    @Override
    public int insert(Org org) {
        LoginUser currentUser = UserUtil.getCurrentUser();
        org.setTenantId(currentUser.getTenantId());
        org.setCreateBy(currentUser.getUsername());
        org.setDateCreate(new Date());
        org.setStatus(1);
        if(org.getParentOrgId()==null){
            org.setParentOrgId(0);
        }
        redisUtil.del("orgInfo"+currentUser.getTenantId());
        return this.orgMapper.insert(org);
    }

    /**
     * 批量新增
     *
     * @param orgs 实例对象的集合
     * @return 生效的条数
     */
    @Override
    public int batchInsert(List<Org> orgs) {
        return this.orgMapper.batchInsert(orgs);
    }

    /**
     * 修改数据
     *
     * @param org 实例对象
     * @return 实例对象
     */
    @Override
    public int update(Org org) {
        Org orgType = orgMapper.findOrgType(org);
        if(!orgType.getOrgType().equals(org.getOrgType())){
            if(orgType.getChildType()!=null&&org.getOrgType().equals("department")
                    &&orgType.getChildType().equals("company")){
                    return -2;
            }else if(orgType.getParentType()!=null&&org.getOrgType().equals("company")&&
                      orgType.getParentType().equals("department")){
                    return -3;
            }
        }
        //將禁用的角色放入redis，作为登出判断
        String keyName="";
        if(org.getOrgType().equals("company")){
            keyName="disableCompany:";
        }else if(org.getOrgType().equals("department")){
            keyName="department:";
        }
        if(org.getOrgState()==0){

            String orgKey=keyName+org.getId();

            redisUtil.setExpire(orgKey.getBytes(), ByteArrayUtils.objectToBytes("1").get(), 60*60*24);//15分钟过期

        } if(org.getOrgState()==1){
            String orgKey=keyName+org.getId();
            redisUtil.del(orgKey.getBytes());

        }

        LoginUser currentUser = UserUtil.getCurrentUser();
        org.setUpdateBy(currentUser.getUsername());
        redisUtil.del("orgInfo"+currentUser.getTenantId());
        return this.orgMapper.update(org);
    }


    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public int deleteById(Integer id) {
        return this.orgMapper.deleteById(id);
    }

    @Override
    public List<String> deleteAll(List<Integer> ids) {
         List<String>fail=new ArrayList<>();
            ids.forEach(id->{
                        Org org=new Org();
                        org.setId(id);
                        Org orgUser = orgMapper.findOrgUser(org);
                        if(orgUser==null){
                            org.setStatus(0);
                            orgMapper.update(org);
                        }else {
                            fail.add(orgUser.getOrgName());
                        }

                 });

        LoginUser currentUser = UserUtil.getCurrentUser();
        redisUtil.del("orgInfo"+currentUser.getTenantId());
        return fail;
    }

    /**
     * 查询总数据数
     *
     * @return 数据总数
     */
    @Override
    public int count() {
        return this.orgMapper.count();
    }

    /**
     * 分页查询
     *
     * @return 对象列表
     */
    @Override
    public IPage<Org> selectPage(Org org, IPage<Org> page) {
        LoginUser currentUser = UserUtil.getCurrentUser();
        org.setTenantId(currentUser.getTenantId());
        return this.orgMapper.selectPage(page, org);
    }

    @Override
    public List<OrgTree> getTrees(Org org) {
        LoginUser currentUser = UserUtil.getCurrentUser();
        org.setTenantId(currentUser.getTenantId());
        Set<Integer>orgIds=new HashSet<>();
        List<ProgramItem> programItemList = currentUser.getProgramItemList();
        if(programItemList!=null){
            programItemList.forEach(programItem -> {
                orgIds.add(programItem.getOrgId());
            });
        }

        List<OrgTree> trees=orgMapper.selectTrees(org);
        if(currentUser.getDepartmentId()==null){
            trees=getOrgTreeByOrg(trees,currentUser.getCompanyId(),orgIds);
        }else {
            trees=getOrgTreeByOrg(trees,currentUser.getDepartmentId(),orgIds);
        }


        return trees;
    }

    @Override
    public List<OrgTree> getUserTrees(Org org) {
        LoginUser currentUser = UserUtil.getCurrentUser();
        org.setTenantId(currentUser.getTenantId());
        Integer id=org.getId();
        org.setId(null);
        Set<Integer>orgIds=new HashSet<>();
        List<ProgramItem> programItemList = currentUser.getProgramItemList();
        if(programItemList!=null){
            programItemList.forEach(programItem -> {
                orgIds.add(programItem.getOrgId());
            });
        }

        List<OrgTree> trees=new ArrayList<>();
        if("company".equals(org.getOrgType())){

            if(currentUser.getDepartmentId()==null&&currentUser.getPermissonType()==2){
                trees=orgMapper.selectTrees(org);
                trees=getOrgTreeByOrg(trees,currentUser.getCompanyId(),orgIds);
            }else{
                org.setId(currentUser.getCompanyId());
                trees=orgMapper.selectTrees(org);
            }
        }else{
            if(currentUser.getDepartmentId()!=null&&currentUser.getPermissonType()==4){
                org.setOrgType("department");
                trees=orgMapper.selectTrees(org);
                trees=getOrgTreeByOrg(trees,currentUser.getDepartmentId(),orgIds);
            }if(currentUser.getDepartmentId()!=null&&currentUser.getPermissonType()==3){
                org.setId(currentUser.getDepartmentId());
                trees=orgMapper.selectTrees(org);
            }else{
                trees=orgMapper.selectTrees(org);
                trees=getOrgDepartmentTree(trees,id);

            }

        }

        return trees;
    }
    List<OrgTree> getOrgTreeByOrg(List<OrgTree> trees,int id, Set<Integer>orgIds){
        OrgTree fatherOrgTree=new OrgTree();
        for (OrgTree tree : trees) {
            if(tree.getId()==id){
                fatherOrgTree=tree;
                break;
            }

        }

        trees=getOrgTree(trees,id,1,orgIds);
        fatherOrgTree.setOrgs(trees);
        List<OrgTree> result=new ArrayList<>();
        result.add(fatherOrgTree);
        trees=result;
        return trees;
    }
    public  List<OrgTree> getOrgTree(List<OrgTree> list, Integer id, Integer level, Set<Integer>orgIds) {
        List<OrgTree> temList = newArrayList();
        if (list != null) {
            for (OrgTree orgTree : list) {

                if (id.equals(orgTree.getParentOrgId())) {

                        orgTree.setDisabled(false);

                    List<OrgTree> chidren = getOrgTree(list, orgTree.getId(),level,orgIds);
                    OrgTree temPermission = new OrgTree();
                    BeanUtils.copyProperties(orgTree, temPermission);
                    temPermission.setOrgs(chidren);
                    temList.add(temPermission);
                    level--;
                }

            }
        }
        if (temList.size() > 0) {
            return temList;
        } else {
            return null;
        }
    }
    public  List<OrgTree> getOrgDepartmentTree(List<OrgTree> list, Integer id) {
        List<OrgTree> temList = newArrayList();
        if (list != null) {
            for (OrgTree orgTree : list) {

                if (id.equals(orgTree.getParentOrgId())
                        &&"department".equals(orgTree.getOrgType())) {

                    List<OrgTree> chidren = getOrgDepartmentTree(list, orgTree.getId());
                    OrgTree temPermission = new OrgTree();
                    BeanUtils.copyProperties(orgTree, temPermission);
                    temPermission.setOrgs(chidren);
                    temList.add(temPermission);
                    ;
                }

            }
        }
        if (temList.size() > 0) {
            return temList;
        } else {
            return null;
        }
    }
   public String findParentOrgByChildId(Integer childId)
   {
      return  orgMapper.findParentOrgByChildId(childId);
   }

    @Override
    public Integer countCompanyByUser() {
        LoginUser loginUser = UserUtil.getCurrentUser();
        return orgMapper.countCompanyByUser(loginUser.getTenantId(),loginUser.getType(),loginUser.getProgramItemList());
    }

    @Override
    public List<OrgBaseTreeInfoDto> getCompanyByUser(String condition,List<Integer> companyIds) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        List<OrgBaseTreeInfoDto> list = orgMapper.getCompanyByUser(condition,companyIds,loginUser.getTenantId(),loginUser.getType(),loginUser.getProgramItemList());
        //获取每个节点的父id集合
//        getOrgPids(null,0,list);
//        getOrgchildIds(new OrgBaseTreeInfoDto(),0,list);
        return list;
    }

    //获取每个节点的父id集合
    private void getOrgPids(OrgBaseTreeInfoDto pOrg, Integer pid, List<OrgBaseTreeInfoDto> orgs){

        for(OrgBaseTreeInfoDto org :orgs){
            if(org.getParentOrgId() != null  && org.getParentOrgId().equals( pid)){
                if(pid == 0){
                    org.setParentOrgIds( org.getId()+"");
                }else{
                    org.setParentOrgIds( pOrg.getParentOrgIds()+","+org.getId());
                }
                getOrgPids(org ,org.getId() , orgs);
            }
        }
    }

    //获取每个节点的子id集合
    private String getOrgchildIds(OrgBaseTreeInfoDto pOrg, Integer pid, List<OrgBaseTreeInfoDto> orgs){
        String childIds="";
        for(OrgBaseTreeInfoDto org :orgs){
            if(org.getParentOrgId() != null  && org.getParentOrgId().equals( pid)){
                childIds = childIds +","+getOrgchildIds(org ,org.getId() , orgs);
            }
        }
        if(pOrg == null){
            return childIds;
        }
        pOrg.setChildOrgIds(pOrg.getId()+childIds);
        return pOrg.getChildOrgIds();
    }

}