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

import com.alibaba.fastjson.JSON;
import com.dingtalk.api.request.OapiDepartmentCreateRequest;
import com.dingtalk.api.request.OapiDepartmentUpdateRequest;
import com.dingtalk.api.response.OapiDepartmentGetResponse;
import com.dingtalk.api.response.OapiDepartmentListResponse;
import com.usoftchina.dingtalk.sdk.AddrBookSdk;
import com.usoftchina.uas.office.dingtalk.entity.HrOrg;
import com.usoftchina.uas.office.service.AbstractService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.support.rowset.SqlRowSet;
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_ding 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() {
        // 同步根部门
        HrOrg rootOrg = queryForBean("select * from hrorg where or_subof=0 and or_statuscode<>'DISABLE'", HrOrg.class);
        syncRoot(rootOrg);

        List<HrOrg> orgList = queryForBeanList("select * from HrOrg where or_subof<>0 and or_statuscode<>'DISABLE'", HrOrg.class);
        if (!CollectionUtils.isEmpty(orgList)) {
            List<OapiDepartmentListResponse.Department> departmentList = addrBookSdk.getDepartmentList("Uas", 1);
            checkOrg(groupOrgList(orgList), rootOrg.getOr_id(), groupDepartmentList(departmentList), 1L);
        }
    }

    /**
     * 同步根部门
     */
    private void syncRoot(HrOrg rootOrg) {
        if (null == rootOrg.getOr_ding() || 1 != rootOrg.getOr_ding()) {
            updateOrgDingId(rootOrg, 1);
        }
    }

    /**
     * 同步 uas组织资料 -> 企业微信部门资料
     */
    public void sync(HrOrg org) {
        if (null == org.getOr_subof() || 0 == org.getOr_subof()) {
            syncRoot(org);
            return;
        }
        if (null != org.getOr_ding()) {
            HrOrg parentOrg = getById(org.getOr_subof());
            if (null != parentOrg) {
                // 修改部门
                OapiDepartmentUpdateRequest req = new OapiDepartmentUpdateRequest();
                req.setId(org.getOr_ding());
                req.setName(org.getOr_name());
                req.setParentid(String.valueOf(parentOrg.getOr_ding()));
                addrBookSdk.updateDepartment("Uas", req);
            }
        } else {
            List<OapiDepartmentListResponse.Department> departmentList = addrBookSdk.getDepartmentList("Uas", 1);
            try {
                // 只需考虑父级组织已同步的情况
                HrOrg parentOrg = getById(org.getOr_subof());
                OapiDepartmentListResponse.Department dept = null;
                for (OapiDepartmentListResponse.Department department : departmentList) {
                    if (department.getParentid().equals(parentOrg.getOr_ding()) && department.getName().equals(org.getOr_name())) {
                        dept = department;
                        break;
                    }
                }
                if (null != dept) {
                    // 修改部门名称
                    OapiDepartmentUpdateRequest req = new OapiDepartmentUpdateRequest();
                    req.setId(dept.getId());
                    req.setName(org.getOr_name());
                    addrBookSdk.updateDepartment("Uas", req);
                    updateOrgDingId(org, dept.getId());
                } else {
                    OapiDepartmentCreateRequest req = new OapiDepartmentCreateRequest();
                    req.setName(org.getOr_name());
                    req.setParentid(String.valueOf(parentOrg.getOr_ding()));
                    req.setCreateDeptGroup(true);
                    Long departmentId = addrBookSdk.createDepartment("Uas", req);
                    updateOrgDingId(org, departmentId);
                }
            } catch (EmptyResultDataAccessException e) {
            }
        }
    }

    private void updateOrgDingId(HrOrg org, long dingDepartmentId) {
        org.setOr_ding(dingDepartmentId);
        jdbcTemplate.update("update HrOrg set or_ding=? where or_id=?", dingDepartmentId, 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<Long, List<OapiDepartmentListResponse.Department>> groupDepartmentList(List<OapiDepartmentListResponse.Department> departmentList) {
        Map<Long, List<OapiDepartmentListResponse.Department>> deptMap = new HashMap<>();
        if (null != departmentList) {
            for (OapiDepartmentListResponse.Department department : departmentList) {
                List<OapiDepartmentListResponse.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<Long, List<OapiDepartmentListResponse.Department>> deptMap, Long parentDeptId) {
        List<HrOrg> orgList = orgMap.get(parentOrgId);
        List<OapiDepartmentListResponse.Department> departmentList = deptMap.get(parentDeptId);
        if (null != orgList) {
            for (HrOrg org : orgList) {
                OapiDepartmentListResponse.Department department = findDeptByName(departmentList, org.getOr_name());
                if (null == department) {
                    if (null != org.getOr_ding() && org.getOr_ding() > 0) {
                        department = findDeptById(departmentList, org.getOr_ding());
                    }
                    if (null == department && parentDeptId == 0 && !CollectionUtils.isEmpty(departmentList)) {
                        department = departmentList.get(0);
                    }
                    if (null == department) {
                        OapiDepartmentCreateRequest req = new OapiDepartmentCreateRequest();
                        req.setName(org.getOr_name());
                        req.setParentid(String.valueOf(parentDeptId));
                        req.setCreateDeptGroup(true);
                        Long departmentId = addrBookSdk.createDepartment("Uas", req);
                        updateOrgDingId(org, departmentId);
                        checkOrg(orgMap, org.getOr_id(), deptMap, departmentId);
                    } else {
                        // 修改部门名称
                        OapiDepartmentUpdateRequest req = new OapiDepartmentUpdateRequest();
                        req.setId(department.getId());
                        req.setName(org.getOr_name());
                        addrBookSdk.updateDepartment("Uas", req);
                        if (!department.getId().equals(org.getOr_ding())) {
                            updateOrgDingId(org, department.getId());
                        }
                        checkOrg(orgMap, org.getOr_id(), deptMap, department.getId());
                    }
                } else {
                    if (!department.getId().equals(org.getOr_ding())) {
                        // 企业微信存在同级别同名的部门名称，还未绑定到uas系统
                        updateOrgDingId(org, department.getId());
                    }
                    checkOrg(orgMap, org.getOr_id(), deptMap, department.getId());
                }
            }
        }
    }

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

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

    /**
     * 修改部门管理员
     */
    public void updateManagerUser() {
        SqlRowSet orgSet = jdbcTemplate.queryForRowSet("select or_ding,em_ding from HrOrg,employee where or_headmancode=em_code and or_subof<>0 and or_statuscode<>'DISABLE' and or_ding is not null and em_ding is not null");
        while (orgSet.next()) {
            OapiDepartmentUpdateRequest req = new OapiDepartmentUpdateRequest();
            req.setId(orgSet.getLong("or_ding"));
            req.setDeptManagerUseridList(orgSet.getString("em_ding"));
            addrBookSdk.updateDepartment("Uas", req);
        }
    }

    /**
     * 清除下面没有人员的部门
     */
    public void clearUseless() {
        List<OapiDepartmentListResponse.Department> departmentList = addrBookSdk.getDepartmentList("Uas", 1);
        Map<Long, List<OapiDepartmentListResponse.Department>> group = groupDepartmentList(departmentList);
        while (!departmentList.isEmpty()) {
            Iterator<OapiDepartmentListResponse.Department> iterator = departmentList.iterator();
            boolean changed = false;
            while (iterator.hasNext()) {
                OapiDepartmentListResponse.Department department = iterator.next();
                // 必须先删末级部门
                if (!group.containsKey(department.getId())) {
                    int count = queryForObject("select count(1) from HrOrg where or_ding = ? 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<String> users = addrBookSdk.getUserIdList("Uas", department.getId());
                        if (CollectionUtils.isEmpty(users)) {
                            addrBookSdk.deleteDepartment("Uas", 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;
            }
        }
    }
}
