package com.artfess.cqlt.manager.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.CollectionUtils;
import com.artfess.base.util.PinyinUtil;
import com.artfess.cqlt.manager.BizOrgManager;
import com.artfess.uc.manager.OrgManager;
import com.artfess.uc.manager.OrgUserManager;
import com.artfess.uc.manager.PwdStrategyManager;
import com.artfess.uc.manager.UserManager;
import com.artfess.uc.model.Org;
import com.artfess.uc.model.OrgUser;
import com.artfess.uc.model.PwdStrategy;
import com.artfess.uc.model.User;
import com.google.api.client.util.Lists;
import com.google.api.client.util.Sets;
import lombok.extern.slf4j.Slf4j;
import net.hasor.db.transaction.interceptor.Transactional;
import org.springframework.http.HttpHeaders;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.function.client.WebClient;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author 黎沐华
 * @date 2023/3/15 10:52
 */
@Slf4j
@Service
public class BizOrgManagerImpl implements BizOrgManager {

    @Resource
    private OrgManager orgManager;
    @Resource
    private UserManager userManager;
    @Resource
    private OrgUserManager relateManager;
    @Resource
    private PwdStrategyManager pwdStrategyManager;
    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
    @Transactional
    public Boolean sync() throws Exception {
        log.info("开始同步泛微组织人员信息");
        WebClient webClient = WebClient.builder()
                .baseUrl("http://192.168.3.3:80")
                .defaultHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)")
                .build();

        JSONArray obtainOrg = JSONArray.parseArray(webClient.post().uri("/getzzdw").retrieve().bodyToMono(String.class).block());
        JSONArray obtainDept = JSONArray.parseArray(webClient.post().uri("/getzzbm").retrieve().bodyToMono(String.class).block());
        JSONArray obtainUser = JSONArray.parseArray(webClient.post().uri("/getQFServlet").retrieve().bodyToMono(String.class).block());
        Assert.notNull(obtainOrg, "请求组织数据失败");
        Assert.notNull(obtainDept, "请求部门数据失败");
        Assert.notNull(obtainUser, "请求用户数据失败");
        log.info("泛微组织信息:{}", obtainOrg);
        log.info("泛微组织信息obtainDept:{}", obtainDept);
        log.info("泛微组织信息obtainUser:{}", obtainUser);

        List<Org> orgList = buildOrgList(obtainOrg, obtainDept);
        orgManager.saveOrUpdateBatch(orgList);
        List<User> userList = Lists.newArrayList();
        List<OrgUser> orgUserList = Lists.newArrayList();
        buildOrgUserList(obtainUser, userList, orgUserList);

        userManager.saveOrUpdateBatch(userList);
        relateManager.saveOrUpdateBatch(orgUserList);
        return true;
    }

    private void buildOrgUserList(JSONArray obtainUser, List<User> userList, List<OrgUser> orgUserList) {
        PwdStrategy pwdStrategy = pwdStrategyManager.getDefault();
        List<OrgUser> list = relateManager.list();
        Set<String> orgIdsAndUserIds = Sets.newHashSet();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(orgUser -> {
                orgIdsAndUserIds.add(orgUser.getOrgId() + orgUser.getUserId());
            });
        }
        for (Object obj : obtainUser) {
            JSONObject orgUserJson = JSON.parseObject(obj.toString());
            User user = new User();
            user.setId(orgUserJson.getString("ryid"));
            user.setFullname(orgUserJson.getString("lastname"));
            user.setAccount(orgUserJson.getString("loginid"));
            if (StringUtils.isEmpty(user.getAccount())) {
                user.setAccount(PinyinUtil.getPinyin(user.getFullname().substring(0, 1)) + PinyinUtil.getPinYinHeadChar(user.getFullname().substring(1)));
            }
            if ("admin".equals(user.getAccount()) || "cqlt".equals(user.getAccount())) {
                continue;
            }
            String defaultPswd = "123456";
            if (pwdStrategy != null) {
                defaultPswd = pwdStrategy.getInitPwd();
            }
            user.setPassword(passwordEncoder.encode(defaultPswd));
            user.setEmail(orgUserJson.getString("accounttype"));
            user.setMobile(orgUserJson.getString("mobile"));
            user.setPhoto(orgUserJson.getString("photo"));
            user.setStatus(orgUserJson.getInteger("status"));
            user.setFrom(User.FROM_RESTFUL);
            user.setGroupId(orgUserJson.getString("departmentid"));
            userList.add(user);

            OrgUser relate = new OrgUser();
            relate.setOrgId(orgUserJson.getString("departmentid"));
            relate.setUserId(orgUserJson.getString("ryid"));
            relate.setIsMaster(0);
            if (!orgIdsAndUserIds.contains(relate.getOrgId() + relate.getUserId())) {
                orgUserList.add(relate);
            }
        }
    }

    private List<Org> buildOrgList(JSONArray obtainOrg, JSONArray obtainDept) throws Exception {
        Map<String, Org> orgMap = new HashMap<>(100);
        List<Org> allOrg = orgManager.list();
        String demId = null;
        for (Org org : allOrg) {
            if ("1".equals(org.getId())) {
                demId = org.getDemId();
            }
        }
        List<Org> orgList = Lists.newArrayList();
        for (Object obj : obtainOrg) {
            JSONObject orgJson = JSON.parseObject(obj.toString());
            Org org = new Org();
            org.setId(orgJson.getString("id"));
            org.setName(orgJson.getString("subcompanyname"));
            org.setParentId(orgJson.getString("supsubcomid"));
            org.setCode(PinyinUtil.getPinYinHeadChar(org.getName()));
            org.setOrgKind("OGN");
            org.setDemId(demId);
            if (BeanUtils.isNotEmpty(orgMap.get(org.getParentId()))) {
                org.setPath(orgMap.get(org.getParentId()).getPath() + org.getId() + ".");
                org.setPathName(orgMap.get(org.getParentId()).getPathName() + "/" + org.getName());
            } else {
                org.setPath(org.getId() + ".");
                org.setPathName("/" + org.getName());
            }
            orgMap.put(org.getId(), org);
            if ("1".equals(org.getId())) {
                continue;
            }
        }

        for (Object deptObj : obtainDept) {
            JSONObject deptJson = JSON.parseObject(deptObj.toString());
            Org dept = new Org();
            dept.setId(deptJson.getString("bmid"));
            dept.setName(deptJson.getString("departmentname"));
            dept.setParentId(deptJson.getString("subcompanyid"));
            dept.setCode(PinyinUtil.getPinYinHeadChar(dept.getName()));
            dept.setDemId(demId);
            dept.setOrgKind("DEPT");
            if (BeanUtils.isNotEmpty(orgMap.get(dept.getParentId()))) {
                dept.setPath(orgMap.get(dept.getParentId()).getPath() + dept.getId() + ".");
                dept.setPathName(orgMap.get(dept.getParentId()).getPathName() + "/" + dept.getName());
            } else {
                dept.setPath(dept.getId() + ".");
                dept.setPathName("/" + dept.getName());
            }
            orgList.add(dept);
            orgMap.put(dept.getId(), dept);
        }
        return orgList;
    }

}
