package com.sunxung.factoring.service.sys.impl;

import com.github.pagehelper.PageHelper;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.dict.impl.OrgLevelDict.ChildEnum;
import com.sunxung.factoring.entity.GridPage;
import com.sunxung.factoring.entity.ValidatorEntity.ValidatorType;
import com.sunxung.factoring.entity.sys.*;
import com.sunxung.factoring.entity.sys.vo.GradationVo;
import com.sunxung.factoring.entity.sys.vo.OrgTreeNode;
import com.sunxung.factoring.entity.sys.vo.SearchOrg;
import com.sunxung.factoring.entity.sys.vo.SysGradationVo;
import com.sunxung.factoring.mapper.sys.OrgMapper;
import com.sunxung.factoring.service.sys.DictionaryService;
import com.sunxung.factoring.service.sys.OrgService;
import com.sunxung.factoring.service.sys.RoleService;
import com.sunxung.factoring.service.sys.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description:系统组织结构业务层实现类
 * @Author:JingJiang
 * @E-mail:254702920@qq.com
 * @Date:2017年6月6日 下午6:27:12
 */
@Service
@PropertySource("classpath:config.properties")
public class OrgServiceImpl implements OrgService {

    @Autowired
    private OrgMapper orgMapper;
    @Autowired
    private DictionaryService dictionaryService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private UserService userService;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${config.org.url}")
    private String orgUrl;

    @Value("${config.userOrgRel.url}")
    private String userOrgRelUrl;

    @Value("${config.user.url}")
    private String userUrl;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Org add(Org org) {
        if (null == org || null == org.getParent()) {
            throw new BusinessException(CodeUtil.FAIL, "父部门ID不能为空！");
        }
        if (StringUtil.isEmpty(org.getName())) {
            throw new BusinessException(CodeUtil.FAIL, "部门名称不能为空！");
        }
        Org parentOrg = getAll(org.getParent().getId());
        if (parentOrg == null) {
            org.setInternalCode(INTERVAL);
        } else {
            org.setDeptNo(MathRandomUtil.getRandomNumber());
            org.setGradation(parentOrg.getSubCountMax());
            org.setSeq(parentOrg.getGradation() + org.getGradation());
            org.setInternalCode(parentOrg.getInternalCode() + (parentOrg.getSubCountMax() + 1) + INTERVAL);
            validatorOrgName(parentOrg.getId(), org.getName(), null);
        }
        //ValidatorUtil.validator(ValidatorType.ADD, org);
        String str = org.getInternalCode();
        org.setSeq(str.length() - str.replace(".", "").length());
        orgMapper.add(org);
        modifySubCountMaxAndSubCountById(parentOrg);
        return get(org.getId());
    }

    /**
     * 获取根节点
     */
    @Override
    public List<OrgTreeNode> findRootOrgTreeNode(boolean number) {
       // List<Org> orgs = orgMapper.findByParentId(null);
        List<Org> all = orgMapper.findAll();
        List<OrgTreeNode> trees = new ArrayList<OrgTreeNode>();
        if (all != null) {
            for (Org org : all) {
                if (number) {
                    String name = org.getName() + countDisplayName(org.getInternalCode());
                    org.setName(name);
                } else {
                    org.setName(org.getName());
                }
                trees.add(new OrgTreeNode(org));
            }
        }
        //
        List<OrgTreeNode> orgTreeNodes = buidTree(trees, 0L);
        if(orgTreeNodes.size()>2){
            orgTreeNodes.remove(1);
           // orgTreeNodes.remove(1);
        }
        return orgTreeNodes;
    }


    //把一个List转成树
    public   List<OrgTreeNode> buidTree(List<OrgTreeNode> list, Object parentId) {
        List<OrgTreeNode> tree = new ArrayList<>();
        for (OrgTreeNode node : list) {
            if (node.getParentId().equals(parentId)) {
                tree.add(findChild(node, list));
            }
        }
        return tree;
    }

    private   OrgTreeNode findChild(OrgTreeNode node, List<OrgTreeNode> list) {
        for (OrgTreeNode n : list) {
            if (node.getId().equals(n.getParentId())) {
                if (node.getChildren() == null) {
                    node.setChildren(new ArrayList<OrgTreeNode>());
                }
                node.getChildren().add(findChild(n, list));
            }
        }
        return node;
    }



    @Override
    public List<OrgTreeNode> findOrgAndUserTreeNode(Long parentId, boolean number) {
        List<Org> orgs = orgMapper.findByParentId(parentId);
        List<OrgTreeNode> trees = new ArrayList<OrgTreeNode>();
        List<User> userList = new ArrayList<>();
        if (orgs != null) {
            for (Org org : orgs) {
                if (number) {
                    String name = org.getName() + countDisplayName(org.getInternalCode());
                    org.setName(name);
                    userList = userService.getUserList(org.getId());
                } else {
                    org.setName(org.getName());
                }
                trees.add(new OrgTreeNode(org));
            }
        }
        if (null != parentId) {
            userList = userService.getUserList(parentId);
        }
        for (User user : userList) {
            if (null != user && user.getId() != ConstantConversionUtil.ADMIN_ID) {
                trees.add(new OrgTreeNode(user, true));
            }
        }
        return trees;
    }

    @Override
    public List<OrgTreeNode> findOperationCenterAndUserTreeNode(Long parentId, boolean number) {
        List<Org> orgs = orgMapper.findByParentId(parentId);
        List<OrgTreeNode> trees = new ArrayList<>();
        List<User> userList = new ArrayList<>();
        if (!orgs.isEmpty()) {
            for (Org org : orgs) {
                if (number) {
                    String name = org.getName() + countDisplayName(org.getInternalCode());
                    org.setName(name);
                } else {
                    org.setName(org.getName());
                }
                trees.add(new OrgTreeNode(org));
            }
        }

        if (null != parentId) {
            userList = userService.getUserList(parentId);
        }
        for (User user : userList) {
            if (null != user && !user.getId().equals(ConstantConversionUtil.ADMIN_ID)) {
                trees.add(new OrgTreeNode(user, true));
            }
        }
        return trees;
    }


    private String countDisplayName(String orgCode) {
        String countDisplayName = "";
        Integer count = userService.countUserOrgRelByOrgCode(orgCode);
        if (count == null) {
            count = 0;
        }
        // 系统超级管理员不包含在内，所以此处减一
        if (orgCode.equals(INTERVAL) && count > 0) {
            count = count - 1;
        }
        countDisplayName = "（" + count + "人）";
        return countDisplayName;
    }

    /**
     * 获取组织机构树信息
     *
     * @param parentId 父级id
     */
    @Override
    public List<OrgTreeNode> findOrgTreeNodeByParentId(Long parentId, boolean number) {
        List<Org> orgs = orgMapper.findByParentId(parentId);
        List<OrgTreeNode> trees = new ArrayList<OrgTreeNode>();
        if (orgs != null) {
            for (Org org : orgs) {
                if (number) {
                    String name = org.getName() + countDisplayName(org.getInternalCode());
                    org.setName(name);
                } else {
                    org.setName(org.getName());
                }
                trees.add(new OrgTreeNode(org));
            }
        }
        return trees;
    }

    /**
     * 修改父级子组织机构数、织机构最大数
     */
    private void modifySubCountMaxAndSubCountById(Org org) {
        if (org == null) {
            return;
        }
        orgMapper.modifySubCountMaxAndSubCountById(org.getId(), org.getSubCount() + 1, org.getSubCountMax() + 1);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Org update(Org org) {
        if (null != org && null != org.getId()) {
            Org oldOrg = get(org.getId());
            validatorOrgName(oldOrg.getParent().getId(), org.getName(), org.getId());
            ValidatorUtil.validator(ValidatorType.UPDATE, org);
            orgMapper.update(org);
            return org;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        Org org = orgMapper.get(id);
        if (org == null) {
            return false;
        }
        // 判断当前节点是否有子节点
        List<Org> orglist = orgMapper.findByParentId(id);
        if (null != orglist && orglist.size() > 0) {
            for (Org og : orglist) {
                // 判断当前组织结构是否已被角色引用
                if (null != og) {
                    List<String> roles = orgMapper.findRoleIdByOrgId(og.getId());
                    if (null != roles && roles.size() > 0) {
                        throw new ValidatorException(CodeUtil.FAIL, "组织机构已被引用不能删除");
                    }
                }
            }
        }
        Org oldOrg = get(id);
        boolean ok = orgMapper.delete(id) > 0;
        if (ok) {
            if (org.getParent() != null) {
                Org parent = orgMapper.get(org.getParent().getId());
                orgMapper.modifySubCountById(parent.getId(), parent.getSubCount() - 1);
                orgMapper.modifySubCountMaxAndSubCountById(parent.getId(), parent.getSubCount() - 1,
                        parent.getSubCountMax() - 1);
            }
            if (null != orglist && orglist.size() > 0) {
                // 删除当前节点下的子节点
                ok = orgMapper.deleteByParentId(id) > 0;
            }
        }
        return ok;
    }

    @Override
    public Org get(Long id) {
        return orgMapper.get(id);
    }

    @Override
    public List<Org> findByParentId(Long parentId) {
        return orgMapper.findByParentId(parentId);
    }

    @Override
    public Org getByCode(String code) {
        return orgMapper.getByCode(code);
    }

    @Override
    public GridPage<Org> findListByMapForPage(SearchOrg search) {
        search.setSidx("gradation");
        List<Org> list = new ArrayList<Org>();
        PageHelper.startPage(search.getPage(), search.getRows());
        list = orgMapper.findBySearch(search);
        return new GridPage<Org>(search.getRows(), search.getPage(), orgMapper.countBySearch(search), list);
    }

    @Override
    public List<Org> findByOrgName(String orgName) {
        SearchOrg search = new SearchOrg();
        search.setName(orgName);
        List<Org> list = orgMapper.findBySearch(search);
        if (list == null || list.isEmpty()) {
            return new ArrayList<Org>();
        }
        return list;
    }

    @Override
    public List<Org> getOrgSelectbox(Long orgId, Long nowId) {
        Org org = orgMapper.get(nowId);
        List<Org> list = new ArrayList<Org>();
        while (true) {
            list.add(org);
            if (org.getId().equals(orgId)) {
                break;
            } else {
                org = orgMapper.get(org.getParent().getId());
            }
        }
        return list;
    }

    @Override
    public Org getAll(Long id) {
        Org org = get(id);
        if (org == null) {
            return null;
        }
        if (org.getParent() != null && null != org.getParent().getId()) {
            org.setParent(get(org.getParent().getId()));
        }
        // org.setOrgType(dictionaryService.get(org.getOrgType().getId()));
        // org.setOrgLevel(dictionaryService.get(org.getOrgLevel().getId()));
        return org;
    }

    /**
     * 判断添加部门编码是否有重复
     */
    @Override
    public boolean validateAdd(String code) {
        Org org = getByCode(code);
        if (org != null) {
            return false;
        }
        return true;
    }

    /**
     * 判断修改部门编码是否有重复
     */
    @Override
    public boolean validateUpdate(String deptCode, Long orgId) {
        Org org = getByCode(deptCode);
        String orgDeptCode = get(orgId).getDeptNo();
        if (org != null && !orgDeptCode.equals(org.getDeptNo())) {
            return false;
        }
        return true;
    }

    @Override
    public List<Org> findAll() {
        return orgMapper.findBySearch(null);
    }

    @Override
    public String getOrgRealNameExcludeSelf(Long orgId, ChildEnum orgTypeEnum) {
        String realName = "";
        Dictionary dict = dictionaryService.getByCode(orgTypeEnum.getCode());
        if (dict == null) {
            return realName;
        }
        List<String> nameList = new ArrayList<String>();
        getNameListByOrgIdAndDictId(orgId, dict.getId(), nameList);
        for (int i = 1, len = nameList.size(); i < len; i++) {
            realName = nameList.get(i) + realName;
        }
        return realName;
    }

    /**
     * 获取组织机构真实名称集合； <br>
     * 根据起始组织机构“orgId”查询，直到父级组织机构机构级别id与dictId相等为止；
     *
     * @param orgId    起始组织机构id
     * @param dictId   组织机构级别字典id
     * @param nameList 组织机构真实名称集合
     * @return
     */
    private List<String> getNameListByOrgIdAndDictId(Long orgId, Long dictId, List<String> nameList) {
        Org org = get(orgId);
        if (org == null || org.getParent() == null) {
            return nameList;
        }
        nameList.add(org.getName());
        // if (dictId.equals(org.getOrgLevel().getId())) {
        // return nameList;
        // }
        return getNameListByOrgIdAndDictId(org.getParent().getId(), dictId, nameList);
    }

    @Override
    public String getOrgRealName(Long orgId, Long parentOrgId) {
        String realName = "";
        List<String> nameList = new ArrayList<String>();
        getNameListByOrgIdAndParentOrgId(orgId, parentOrgId, nameList);
        for (String name : nameList) {
            realName = name + "-" + realName;
        }
        return realName.substring(0, realName.length() - 1);
        // return realName;
    }

    @Override
    public String getOrgRealNameExceptRoot(Long orgId) {
        String realName = "";
        Org org = getByCode("cayk");
        List<String> nameList = new ArrayList<String>();
        if (null != org && null != org.getId()) {
            getNameListByOrgIdAndParentOrgId(orgId, org.getId(), nameList);
            for (String name : nameList) {
                realName = name + "-" + realName;
            }
            return realName.substring(0, realName.length() - 1);
        }
        return realName;
    }

    /**
     * 获取组织机构真实名称集合； <br>
     * 根据起始组织机构“orgId”查询，直到父级组织机构id与parentOrgId相等为止；
     *
     * @param orgId       起始组织机构id
     * @param parentOrgId 组织机构父级id
     * @param nameList    组织机构真实名称集合
     * @return
     */
    private List<String> getNameListByOrgIdAndParentOrgId(Long orgId, Long parentOrgId, List<String> nameList) {
        Org org = get(orgId);
        if (org == null) {
            return nameList;
        }
        nameList.add(org.getName());
        if (org.getParent() == null || parentOrgId.equals(org.getParent().getId())) {
            return nameList;
        }
        return getNameListByOrgIdAndParentOrgId(org.getParent().getId(), parentOrgId, nameList);
    }

    @Override
    public List<Org> findAllByFillRoles() {
        List<Org> orgList = findAll();
        if (null != orgList && orgList.size() > 0) {
            List<Org> orgHasRole = new ArrayList<Org>();
            for (Org org : orgList) {
                List<Role> roles = roleService.findByOrgId(org.getId());
                if (null != roles && roles.size() > 0) {
                    org.setRoleList(roles);
                    // 仅保存存在角色的组织机构
                    orgHasRole.add(org);
                }
            }
            return orgHasRole;
        }
        return orgList;
    }

    @Override
    public boolean deleteMore(String[] ids) {
        if (null == ids || ids.length < 1) {
            throw new BusinessException(CodeUtil.FAIL, "删除的数据不能为空");
        }
        boolean flag = true;
        for (String id : ids) {
            flag = delete(Long.valueOf(id));
            if (!flag) {
                return flag;
            }
        }
        return flag;
    }

    @Override
    public Org getByParentIdAndName(Long parentId, String name) {
        return orgMapper.getByParentIdAndName(parentId, name);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adjustOrder(SysGradationVo sysVo) {
        boolean b = false;
        if (null != sysVo && null != sysVo.getList() && sysVo.getList().size() > 0) {
            for (GradationVo vo : sysVo.getList()) {
                if (null != vo.getId()) {
                    b = orgMapper.adjustOrder(vo.getId(), vo.getGradation()) > 0;
                }
            }
        }
        return b;
    }

    @Override
    public List<OrgTreeNode> findOrgUserList(String keyword) {
        List<Org> orgs = findByOrgName(keyword);
        List<OrgTreeNode> trees = new ArrayList<OrgTreeNode>();
        List<User> userList = new ArrayList<>();
        if (orgs != null && orgs.size() > 0) {
            for (Org org : orgs) {
                String realName = getOrgRealNameExceptRoot(org.getId());
                org.setName(realName);
                trees.add(new OrgTreeNode(org));
            }
        }
        userList = userService.findList(keyword);
        for (User user : userList) {
            if (null != user && user.getId() != ConstantConversionUtil.ADMIN_ID) {
                trees.add(new OrgTreeNode(user, true));
            }
        }
        return trees;
    }

    private void validatorOrgName(Long parentId, String name, Long orgId) {
        if (null != orgId) {
            Org exitOrg = get(orgId);
            if (null != exitOrg && !exitOrg.getName().equals(name)) {
                Org org = orgMapper.findOrgByNameAndParentId(parentId, name);
                if (null != org) {
                    throw new BusinessException(CodeUtil.FAIL, "该父部门下已存在子部门，请重新添加");
                }
            }
        } else {
            Org org = orgMapper.findOrgByNameAndParentId(parentId, name);
            if (null != org) {
                throw new BusinessException(CodeUtil.FAIL, "该父部门下已存在子部门，请重新添加");
            }
        }
    }

    @Override
    public List<Long> findUserIdByOrgCode(String code) {
        List<Long> userIdList = orgMapper.findUserIdByOrgCode(code);
        return userIdList;
    }

    @Override
    public List<Org> findByNameList(List<String> orgNameList) {
        List<Org> orgList = new ArrayList<>();
        for (String str : orgNameList) {
            Org org = orgMapper.findByName(str);
            if (org != null) {
                orgList.add(org);
            }
        }
        return orgList;
    }

    @Override
    public Org findByName(String orgName) {
        Org org = orgMapper.findByName(orgName);
        return org;
    }

    @Override
    public Org findRootByUseId(Long userId) {
        return orgMapper.findRootByUseId(userId);
    }

    @Override
    public List<Org> findIdentityByUseId(Long userId) {
        return orgMapper.findIdentityByUseId(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncOrgAndUser(Long orgId) {
        ResponseEntity<Org[]> responseEntity;
        if (orgId == null) {
            responseEntity = restTemplate.getForEntity(orgUrl, Org[].class);
        } else {
            responseEntity = restTemplate.getForEntity(orgUrl + "?orgId=" + orgId, Org[].class);
        }
        if (responseEntity.getBody() != null) {
            List<Org> orgList = Arrays.asList(responseEntity.getBody());
            if (orgList != null && orgList.size() > 0) {
                for (Org org : orgList) {
                    Org oldOrg = orgMapper.get(org.getId());
                    if (oldOrg == null) {
                        orgMapper.add(org);
                    } else {
                        orgMapper.update(org);
                    }
                    ResponseEntity<UserOrgRel[]> userOrgRelResponse = restTemplate.getForEntity(userOrgRelUrl + "?orgId=" + org.getId(), UserOrgRel[].class);
                    if (userOrgRelResponse.getBody() != null) {
                        List<UserOrgRel> userOrgRelList = Arrays.asList(userOrgRelResponse.getBody());
                        userService.deleteUserOrgRelByOrgId(org.getId());
                        if (userOrgRelList != null && userOrgRelList.size() > 0) {
                            for (UserOrgRel userOrgRel : userOrgRelList) {
                                User user = restTemplate.getForObject(userUrl + "?userId=" + userOrgRel.getUserId(), User.class);
                                if (user != null && user.getLoginName() != null) {
                                    User oldUser = userService.getByLoginName(user.getLoginName());
                                    if (oldUser == null) {
                                        user = userService.addBySop(user);
                                        userOrgRel.setUserId(user.getId());
                                    } else {
                                        //密码等信息不修改
                                        user.setPassword(null);
                                        user.setId(oldUser.getId());
                                        userService.update(user);
                                        userOrgRel.setUserId(oldUser.getId());
                                    }
                                    userService.addUserOrgRel(userOrgRel);
                                }
                            }
                        }
                    }
                }
            }
        }

    }

    @Override
    public List<User> findUserListByOrgId(Long orgId) {
        ResponseEntity<UserOrgRel[]> responseEntity = restTemplate.getForEntity(userOrgRelUrl + "?orgId=" + orgId, UserOrgRel[].class);

        List<User> userList = new ArrayList<>();
        if (responseEntity.getBody() != null) {
            List<UserOrgRel> userOrgRelList = Arrays.asList(responseEntity.getBody());

            if (userOrgRelList != null && userOrgRelList.size() > 0) {
                for (UserOrgRel userOrgRel : userOrgRelList) {
                    User user = restTemplate.getForObject(userUrl + "?userId=" + userOrgRel.getUserId(), User.class);
                    if (user != null) {
                        userList.add(user);
                    }
                }
            }
        }
        return userList;
    }

    @Override
    public List<OrgTreeNode> findOrgAndUserTreeNodeAndAdmin(Long parentId, boolean number) {
        List<Org> orgs = orgMapper.findByParentId(parentId);
        List<OrgTreeNode> trees = new ArrayList<OrgTreeNode>();
        List<User> userList = new ArrayList<>();
        if (orgs != null) {
            for (Org org : orgs) {
                if (number) {
                    String name = org.getName() + countDisplayName(org.getInternalCode());
                    org.setName(name);
                    userList = userService.getUserList(org.getId());
                } else {
                    org.setName(org.getName());
                }
                trees.add(new OrgTreeNode(org));
            }
        }
        if (null != parentId) {
            userList = userService.getUserList(parentId);
        }
        for (User user : userList) {
            trees.add(new OrgTreeNode(user, true));
        }
        return trees;
    }
}
