package com.yihu.ehr.basic.org.service;

import com.yihu.ehr.basic.org.dao.OrganizationRepository;
import com.yihu.ehr.basic.org.model.OrgDept;
import com.yihu.ehr.basic.org.model.OrgMemberRelation;
import com.yihu.ehr.basic.org.model.Organization;
import com.yihu.ehr.basic.org.dao.LdapEntriesRepository;
import com.yihu.ehr.basic.org.dao.OrgDeptRepository;
import com.yihu.ehr.basic.org.dao.OrgMemberRelationRepository;
import com.yihu.ehr.basic.org.model.LdapEntries;
import com.yihu.ehr.util.ldap.LdapUtil;
import org.hibernate.service.spi.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 机构ldap服务
 */
@Service
@Transactional(rollbackFor = {ServiceException.class})
public class OrgLdapService  {

    @Autowired
    private OrganizationRepository organizationRepository;

    @Autowired
    private OrgDeptRepository orgDeptRepository;

    @Autowired
    private OrgMemberRelationRepository orgMemberRelationRepository;

    @Autowired
    private LdapEntriesRepository ldapEntriesRepository;

    @Autowired
    LdapUtil ldapUtil;

    @Value("${spring.ldap.root}")
    String rootDn;

    private void importOrgDept(String orgId,Integer patientDept,Long parent,String parentDn)
    {
        List<OrgDept> deptList = orgDeptRepository.findByOrgIdAndParentDeptId(orgId,patientDept);

        if(deptList!=null && deptList.size()>0)
        {
            for(OrgDept dept :deptList)
            {
                String dn = "ou="+dept.getCode()+","+parentDn;

                LdapEntries item = new LdapEntries();
                item.setDn(dn);
                item.setParent(parent);
                item.setOcMapId(2);
                item.setKeyval(Long.valueOf(dept.getId()));
                ldapEntriesRepository.save(item);

                importOrgDept(orgId,dept.getId(),item.getId(),dn);
            }
        }
    }


    /**
     * 初始化ldap机构科室数据
     */
    private void importOrgAndDept(Long rootId) {
        //获取所有有效机构
        List<Organization> orgList = organizationRepository.findAllOrg();

        if(orgList!=null && orgList.size()>0)
        {
            for(Organization org:orgList)
            {
                try {
                    String dn = "o=" + org.getOrgCode() + "," + rootDn;

                    LdapEntries item = new LdapEntries();
                    item.setDn(dn);
                    item.setParent(rootId);
                    item.setOcMapId(3);
                    item.setKeyval(org.getId());
                    ldapEntriesRepository.save(item);

                    importOrgDept(String.valueOf(org.getId()), 0, item.getId(), dn);
                    importMember(String.valueOf(org.getId()));
                }
                catch (Exception ex)
                {
                    System.out.print("机构"+org.getOrgCode()+"导入失败！"+ ex.getMessage());
                }
            }
        }

    }

    /**
     *  初始化ldap机构成员数据
     */
    private void importMember(String orgId) throws Exception {
        //获取所有有效机构
        List<OrgMemberRelation> memberList = orgMemberRelationRepository.findByOrgId(orgId);
        if(memberList!=null && memberList.size()>0)
        {
            List<LdapEntries> newList = new ArrayList<>();
            for(OrgMemberRelation member:memberList)
            {
                //找到所属科室
                LdapEntries parent = ldapEntriesRepository.findByOcMapIdAndKeyval(2,Long.valueOf(member.getDeptId()));
                if(parent!=null)
                {
                    String dn = "cn="+member.getId()+ ","+parent.getDn();
                    LdapEntries newEntries = new LdapEntries();
                    newEntries.setDn(dn);
                    newEntries.setParent(parent.getId());
                    newEntries.setOcMapId(1);
                    newEntries.setKeyval(Long.valueOf(member.getId()));
                    newList.add(newEntries);
                }
                else{
                    System.out.print("导入成员"+member.getUserId()+"失败,机构"+orgId+"科室"+member.getDeptId()+"不存在！");
                }
            }
            ldapEntriesRepository.save(newList);
        }

    }

    //**************************************************************************************//*
    /**
     初始化Ldap数据
     */
    @Transactional
    public void importLdapData() throws Exception
    {
        //清空数据
        ldapEntriesRepository.deleteAll();

        //创建根节点
        LdapEntries root = new LdapEntries();
        root.setDn(rootDn);
        root.setKeyval(Long.valueOf(0));
        root.setParent(Long.valueOf(0));
        root.setOcMapId(4);
        ldapEntriesRepository.save(root);

        importOrgAndDept(root.getId());
    }

    private String getObjectClass(Integer type)
    {
        String objectClass = "*";
        if(type!=null)
        {
            if(type.equals(1))
            {
                objectClass = "inetOrgPerson";
            }
            else if(type.equals(2))
            {
                objectClass = "organizationalUnit";
            }
            else if(type.equals(3))
            {
                objectClass = "organization";
            }
            else{
                objectClass = "null";
            }
        }

        return objectClass;
    }

    /**
     节点类型，1用户 2科室 3机构 为空全部
     */
    public List<Map<String,Object>> queryAllByObjectClass(String searchDN, Integer type) throws Exception
    {
        String objectClass = getObjectClass(type);
        return ldapUtil.queryAllByObjectClass(searchDN,objectClass);
    }

    /**
     节点类型，1用户 2科室 3机构 为空全部
     */
    public List<Map<String,Object>> queryChildren(String searchDN, Integer type) throws Exception
    {
        String objectClass = getObjectClass(type);
        return ldapUtil.queryChildren(searchDN,objectClass);
    }

    /**
     节点类型，1用户 2科室 3机构 为空全部
     */
    public Map<String,Object> queryBase(String searchDN, Integer type) throws Exception
    {
        String objectClass = getObjectClass(type);
        return ldapUtil.queryBase(searchDN,objectClass);
    }

    /**
     节点类型，1用户 2科室 3机构 为空全部
     */
    public List<Map<String,Object>> queryAllWithoutSelf(String searchDN, Integer type) throws Exception
    {
        String objectClass = getObjectClass(type);
        return ldapUtil.queryAllWithoutSelf(searchDN,objectClass);
    }
}

