package com.usoftchina.uas.office.qywx.service;

import com.usoftchina.qywx.sdk.AddrBookSdk;
import com.usoftchina.qywx.sdk.dto.CreateDepartmentReq;
import com.usoftchina.qywx.sdk.dto.GetDepartmentListResp;
import com.usoftchina.qywx.sdk.dto.GetSimpleUserListResp;
import com.usoftchina.qywx.sdk.dto.UpdateDepartmentReq;
import com.usoftchina.uas.office.qywx.entity.HrOrg;
import com.usoftchina.uas.office.service.AbstractService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author yingp
 * @date 2020/2/9
 */
@Service
public class UasOrgService extends AbstractService {
    @Autowired
    private AddrBookSdk addrBookSdk;

    public HrOrg getById(Integer id) {
        return queryForBean("select * from HrOrg where or_statuscode<>'DISABLE' and or_qywx is not null and or_id=?", HrOrg.class,
                id);
    }

    public HrOrg getRemovedById(Integer id) {
        HrOrg org = queryFlashbackBean("HrOrg", "where or_id=?", HrOrg.class, id);
        if (null == org) {
            org = queryRecycleBean("HrOrg", HrOrg.class, id);
        }
        return org;
    }

    /**
     * 同步全部 uas组织资料 -> 企业微信部门资料
     */
    public void sync() {
        List<HrOrg> HrOrgList = queryForBeanList("select * from HrOrg where or_statuscode<>'DISABLE'", HrOrg.class);
        if (!CollectionUtils.isEmpty(HrOrgList)) {
            List<GetDepartmentListResp.Department> departmentList = addrBookSdk.getDepartmentList();
            checkOrg(groupOrgList(HrOrgList), 0, groupDepartmentList(departmentList), 0);
        }
    }

    /**
     * 同步 uas组织资料 -> 企业微信部门资料
     */
    public void sync(HrOrg org) {
        if (null != org.getOr_qywx() && !addrBookSdk.isReadonly()) {
            if (null == org.getOr_subof() || 0 == org.getOr_subof()) {
                // 修改部门
                addrBookSdk.updateDepartment(new UpdateDepartmentReq()
                        .id(org.getOr_qywx())
                        .name(org.getOr_name())
                        .parent(0));
            } else {
                HrOrg parentOrg = getById(org.getOr_subof());
                if (null != parentOrg) {
                    // 修改部门
                    addrBookSdk.updateDepartment(new UpdateDepartmentReq()
                            .id(org.getOr_qywx())
                            .name(org.getOr_name())
                            .parent(parentOrg.getOr_qywx()));
                }
            }
        } else {
            List<GetDepartmentListResp.Department> departmentList = addrBookSdk.getDepartmentList();
            if (null == org.getOr_subof() || 0 == org.getOr_subof()) {
                GetDepartmentListResp.Department rootDept = null;
                for (GetDepartmentListResp.Department department : departmentList) {
                    if (department.getParentid() == 0) {
                        rootDept = department;
                        break;
                    }
                }
                if (!addrBookSdk.isReadonly()) {
                    // 修改部门名称
                    addrBookSdk.updateDepartment(new UpdateDepartmentReq()
                            .id(rootDept.getId())
                            .name(org.getOr_name())
                            .parent(0));
                }
                updateOrgQywxId(org, rootDept.getId());
            } else {
                try {
                    // 只需考虑父级组织已同步的情况
                    HrOrg parentOrg = getById(org.getOr_subof());
                    GetDepartmentListResp.Department dept = null;
                    for (GetDepartmentListResp.Department department : departmentList) {
                        if (department.getParentid().equals(parentOrg.getOr_qywx()) && department.getName().equals(org.getOr_name())) {
                            dept = department;
                            break;
                        }
                    }
                    if (null != dept) {
                        if (!addrBookSdk.isReadonly()) {
                            // 修改部门名称
                            addrBookSdk.updateDepartment(new UpdateDepartmentReq()
                                    .id(dept.getId())
                                    .name(org.getOr_name()));
                        }
                        updateOrgQywxId(org, dept.getId());
                    } else {
                        if (!addrBookSdk.isReadonly()) {
                            Integer departmentId = addrBookSdk.createDepartment(new CreateDepartmentReq()
                                    .name(org.getOr_name())
                                    .parent(parentOrg.getOr_qywx()));
                            updateOrgQywxId(org, departmentId);
                        }
                    }
                } catch (EmptyResultDataAccessException e) {
                }
            }
        }
    }

    private void updateOrgQywxId(HrOrg org, int qywxDepartmentId) {
        org.setOr_qywx(qywxDepartmentId);
        jdbcTemplate.update("update HrOrg set or_qywx=? where or_id=?", qywxDepartmentId, org.getOr_id());
    }

    private Map<Integer, List<HrOrg>> groupOrgList(List<HrOrg> orgList) {
        Map<Integer, List<HrOrg>> orgMap = new HashMap<>();
        if (null != orgList) {
            for (HrOrg HrOrg : orgList) {
                List<HrOrg> orgs = orgMap.get(HrOrg.getOr_subof());
                if (null == orgs) {
                    orgs = new ArrayList<>(1);
                    orgMap.put(HrOrg.getOr_subof(), orgs);
                }
                orgs.add(HrOrg);
            }
        }
        return orgMap;
    }

    private Map<Integer, List<GetDepartmentListResp.Department>> groupDepartmentList(List<GetDepartmentListResp.Department> departmentList) {
        Map<Integer, List<GetDepartmentListResp.Department>> deptMap = new HashMap<>();
        if (null != departmentList) {
            for (GetDepartmentListResp.Department department : departmentList) {
                List<GetDepartmentListResp.Department> departments = deptMap.get(department.getParentid());
                if (null == departments) {
                    departments = new ArrayList<>(1);
                    deptMap.put(department.getParentid(), departments);
                }
                departments.add(department);
            }
        }
        return deptMap;
    }

    private void checkOrg(Map<Integer, List<HrOrg>> orgMap, Integer parentOrgId,
                          Map<Integer, List<GetDepartmentListResp.Department>> deptMap, Integer parentDeptId) {
        List<HrOrg> orgList = orgMap.get(parentOrgId);
        List<GetDepartmentListResp.Department> departmentList = deptMap.get(parentDeptId);
        if (null != orgList) {
            for (HrOrg HrOrg : orgList) {
                GetDepartmentListResp.Department department = findDeptByName(departmentList, HrOrg.getOr_name());
                if (null == department) {
                    if (null != HrOrg.getOr_qywx() && HrOrg.getOr_qywx() > 0) {
                        department = findDeptById(departmentList, HrOrg.getOr_qywx());
                    }
                    if (null == department && parentDeptId == 0 && !CollectionUtils.isEmpty(departmentList)) {
                        department = departmentList.get(0);
                    }
                    if (null == department) {
                        Integer departmentId = addrBookSdk.createDepartment(new CreateDepartmentReq()
                                .name(HrOrg.getOr_name())
                                .parent(parentDeptId));
                        updateOrgQywxId(HrOrg, departmentId);
                        checkOrg(orgMap, HrOrg.getOr_id(), deptMap, departmentId);
                    } else {
                        // 修改部门名称
                        addrBookSdk.updateDepartment(new UpdateDepartmentReq()
                                .id(department.getId())
                                .name(HrOrg.getOr_name()));
                        if (!department.getId().equals(HrOrg.getOr_qywx())) {
                            updateOrgQywxId(HrOrg, department.getId());
                        }
                        checkOrg(orgMap, HrOrg.getOr_id(), deptMap, department.getId());
                    }
                } else {
                    if (!department.getId().equals(HrOrg.getOr_qywx())) {
                        // 企业微信存在同级别同名的部门名称，还未绑定到uas系统
                        updateOrgQywxId(HrOrg, department.getId());
                    }
                    checkOrg(orgMap, HrOrg.getOr_id(), deptMap, department.getId());
                }
            }
        }
    }

    private GetDepartmentListResp.Department findDeptById(List<GetDepartmentListResp.Department> departmentList, Integer departmentId) {
        if (null != departmentList) {
            for (GetDepartmentListResp.Department department : departmentList) {
                if (department.getId().equals(departmentId)) {
                    return department;
                }
            }
        }
        return null;
    }

    private GetDepartmentListResp.Department findDeptByName(List<GetDepartmentListResp.Department> departmentList, String name) {
        if (null != departmentList) {
            for (GetDepartmentListResp.Department department : departmentList) {
                if (department.getName().equals(name)) {
                    return department;
                }
            }
        }
        return null;
    }

    /**
     * 清除下面没有人员的部门
     */
    public void clearUseless() {
        if (addrBookSdk.isReadonly()) {
            return;
        }
        List<GetDepartmentListResp.Department> departmentList = addrBookSdk.getDepartmentList();
        Map<Integer, List<GetDepartmentListResp.Department>> group = groupDepartmentList(departmentList);
        while (!departmentList.isEmpty()) {
            Iterator<GetDepartmentListResp.Department> iterator = departmentList.iterator();
            boolean changed = false;
            while (iterator.hasNext()) {
                GetDepartmentListResp.Department department = iterator.next();
                // 必须先删末级部门
                if (!group.containsKey(department.getId())) {
                    int count = queryForObject("select count(1) from HrOrg where or_qywx = ? and (exists (select 1 from employee where em_class<>'离职' and em_defaultorid=or_id) or exists (select 1 from empsjobs where org_id=or_id))", Integer.class, department.getId());
                    if (count == 0) {
                        List<GetSimpleUserListResp.User> users = addrBookSdk.getSimpleUserList(department.getId(), true);
                        if (CollectionUtils.isEmpty(users)) {
                            addrBookSdk.deleteDepartment(department.getId());
                            group.get(department.getParentid()).remove(department);
                            if (group.get(department.getParentid()).isEmpty()) {
                                group.remove(department.getParentid());
                            }
                            iterator.remove();
                            changed = true;
                        }
                    }
                }
            }
            if (!changed) {
                break;
            }
        }
    }
}
