package com.hz.pm.api.organization;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.common.collect.Lists;
import com.ningdatech.basic.model.GenericResult;
import com.hz.pm.api.AppTests;
import com.hz.pm.api.ding.model.DingOrgInfoTreeDTO;
import com.hz.pm.api.ding.task.EmployeeBatchGetTask;
import com.hz.pm.api.ding.task.GovBusinessStripsTask;
import com.hz.pm.api.ding.task.OrganizationBatchGetTask;
import com.hz.pm.api.organization.model.entity.DingOrganization;
import com.hz.pm.api.organization.service.IDingOrganizationService;
import com.ningdatech.zwdd.client.ZwddClient;
import com.ningdatech.zwdd.model.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author liuxinxin
 * @date 2023/2/9 下午3:54
 */
@Slf4j
class OrganizationTest extends AppTests {

    @Autowired
    private OrganizationBatchGetTask organizationBatchGetTask;

    @Autowired
    private EmployeeBatchGetTask employeeBatchGetTask;

    @Autowired
    private GovBusinessStripsTask govBusinessStripsTask;

    @Autowired
    private ZwddClient zwddClient;

    @Autowired
    private IDingOrganizationService organizationService;

    private static final Integer GROUP_SIZE = 100;

    @Test
    public void testBatchGetOrganization() {
        organizationBatchGetTask.batchGetOrganizationTask();
    }

    @Test
    public void testEmployeeBatchGetTask() {
        employeeBatchGetTask.batchGetEmployeeTask();
    }

    @Test
    public void testGovBusinessStripsTask() {
        govBusinessStripsTask.batchGetGovBusinessStripsTask();
    }

    @Test
    public void getEmployeeInfo() {
        GenericResult<DingInfoByMobileDTO> dingInfoByMobile = zwddClient.getDingInfoByMobile("13164388876");
//        GenericResult<EmployeeInfoDTO> ge_809a061236b941d281446df6f14dc8f0 = zwddClient.getEmployeeByCode("GE_809a061236b941d281446df6f14dc8f0");
        GenericResult<EmployeeInfoDTO> ge_809a061236b941d281446df6f14dc8f0 = zwddClient.getEmployeeByCode("GE_e68c7af513474eaa959b7ce7141a4d9f");

        System.out.println("---");
    }

    @Test
    public void test2() {
        // 获取顶级组织code
        GenericResult<DingScopesV2DTO> scopesV2Result = zwddClient.getScopesV2();
        DingScopesV2DTO scopesV2 = scopesV2Result.getData();

        if (Objects.nonNull(scopesV2)) {
            List<DingOrganization> currentAllOrganizationList = organizationService.list();

            // 顶级组织code
            List<String> deptVisibleScopes = scopesV2.getDeptVisibleScopes();
            log.info("顶级组织code: size = " + deptVisibleScopes.size() + "列表：" + JSONObject.toJSONString(deptVisibleScopes));
            // 获取顶级节点信息
            GenericResult<List<DingOrgInfoDTO>> listGenericResult = zwddClient.listOrganizationsByCodes(deptVisibleScopes);
            log.info("listGenericResult: {}" + JSON.toJSONString(listGenericResult));
            List<DingOrgInfoDTO> dingOrgInfoDtos = listGenericResult.getData();
            for (String orgCode : deptVisibleScopes) {
                List<DingOrgInfoTreeDTO> treeDTOList = new ArrayList<>();

                DingOrgInfoTreeDTO childDingOrgInfoTreeDTO = new DingOrgInfoTreeDTO();
                //设置节点详情
                if (dingOrgInfoDtos != null && !dingOrgInfoDtos.isEmpty()) {
                    for (DingOrgInfoDTO orgInfo : dingOrgInfoDtos) {
                        if (orgInfo.getOrganizationCode().equals(orgCode)) {
                            childDingOrgInfoTreeDTO.setDingOrgInfoDTO(orgInfo);
                        }
                    }
                }
                childDingOrgInfoTreeDTO.setCode(orgCode);
                childDingOrgInfoTreeDTO.setChildCodes(new ArrayList<>());
                getDingOrgChild(childDingOrgInfoTreeDTO);
                treeDTOList.add(childDingOrgInfoTreeDTO);
                if (CollectionUtils.isNotEmpty(treeDTOList)) {
                    List<DingOrganization> saveRecordList = new ArrayList<>();
                    buildSaveRecordList(treeDTOList, saveRecordList,currentAllOrganizationList);
                    // 批量保存
                    if (saveRecordList.size() <= GROUP_SIZE) {
                        organizationService.saveOrUpdateBatch(saveRecordList);
                    } else {
                        List<List<DingOrganization>> split = Lists.partition(saveRecordList, GROUP_SIZE);
                        for (List<DingOrganization> segment : split) {
                            organizationService.saveOrUpdateBatch(segment);
                        }
                    }
                }
                log.info("----拉取浙政钉组织结构结束---,顶级code：" + orgCode);
            }
        }
    }

    private void getDingOrgChild(DingOrgInfoTreeDTO parentDingOrgInfoTreeDTO) {
        String parentOrgCode = parentDingOrgInfoTreeDTO.getCode();
        DingOrgInfoDTO orgInfoDTO = parentDingOrgInfoTreeDTO.getDingOrgInfoDTO();
        boolean leaf = orgInfoDTO.getLeaf();
        if (!leaf) {
            int currentPage = 1;
            int pageSize = 100;
            GenericResult<PageSubOrganizationCodeDTO> pageSubOrganizationCodeDTOGenericResult = zwddClient.pageSubOrganizationCodes(currentPage++, pageSize, parentOrgCode);
            PageSubOrganizationCodeDTO pageSubOrganizationCodeDTO = pageSubOrganizationCodeDTOGenericResult.getData();

            if (CollUtil.isNotEmpty(pageSubOrganizationCodeDTO.getSubOrganizationCodeList())) {
                List<String> subOrganizationCodeList = new ArrayList<>(pageSubOrganizationCodeDTO.getSubOrganizationCodeList());
                Long totalSize = pageSubOrganizationCodeDTO.getTotalSize();

                while (totalSize > (long) currentPage * pageSize) {
                    GenericResult<PageSubOrganizationCodeDTO> subPageSubOrganizationCodeDTOGenericResult = zwddClient
                            .pageSubOrganizationCodes(currentPage++, pageSize, parentOrgCode);
                    PageSubOrganizationCodeDTO subOrganizationCodeDTO = subPageSubOrganizationCodeDTOGenericResult.getData();
                    if (CollectionUtils.isNotEmpty(subOrganizationCodeDTO.getSubOrganizationCodeList())) {
                        subOrganizationCodeList.addAll(subOrganizationCodeDTO.getSubOrganizationCodeList());
                    }
                }

                if (CollectionUtils.isNotEmpty(subOrganizationCodeList)) {
                    GenericResult<List<DingOrgInfoDTO>> listGenericResult = zwddClient
                            .listOrganizationsByCodes(subOrganizationCodeList);
                    List<DingOrgInfoDTO> dingOrgInfoDtos = listGenericResult.getData();
                    List<DingOrgInfoTreeDTO> dingOrgInfoTreeDTOList = dingOrgInfoDtos.stream().map(r -> {
                        DingOrgInfoTreeDTO dingOrgInfoTreeDTO = new DingOrgInfoTreeDTO();
                        dingOrgInfoTreeDTO.setCode(r.getOrganizationCode());
                        dingOrgInfoTreeDTO.setDingOrgInfoDTO(r);
                        dingOrgInfoTreeDTO.setChildCodes(new ArrayList<>());
                        getDingOrgChild(dingOrgInfoTreeDTO);
                        return dingOrgInfoTreeDTO;
                    }).collect(Collectors.toList());
                    parentDingOrgInfoTreeDTO.setChildCodes(dingOrgInfoTreeDTOList);
                }
            }
        }
    }

    private void buildSaveRecordList(List<DingOrgInfoTreeDTO> treeDTOList, List<DingOrganization> saveRecordList,
                                     List<DingOrganization> oldList) {
        Set<String> set = new HashSet();
        Map<String,DingOrganization> map = oldList.stream()
                .filter(o -> set.add(o.getOrganizationCode()))
                .collect(Collectors.toMap(DingOrganization::getOrganizationCode,o -> o));
        if (CollectionUtils.isEmpty(treeDTOList)) {
            return;
        }
        for (DingOrgInfoTreeDTO dingOrgInfoTreeDTO : treeDTOList) {
            DingOrganization saveRecord = new DingOrganization();
            DingOrgInfoDTO dingOrgInfoDTO = dingOrgInfoTreeDTO.getDingOrgInfoDTO();
            List<DingOrgInfoTreeDTO> childCodes = dingOrgInfoTreeDTO.getChildCodes();
            if(map.containsKey(dingOrgInfoDTO.getOrganizationCode())) {
                DingOrganization organization = map.get(dingOrgInfoDTO.getOrganizationCode());
                saveRecord.setId(organization.getId());
                if (CollectionUtils.isNotEmpty(childCodes)) {
                    buildSaveRecordList(childCodes, saveRecordList,oldList);
                }
                continue;
            }

            saveRecord.setDisplayOrder(dingOrgInfoDTO.getDisplayOrder());
//            saveRecord.setEnabled("1");
            saveRecord.setParentCode(dingOrgInfoDTO.getParentCode());
            saveRecord.setTypeCode(dingOrgInfoDTO.getTypeCode());
            saveRecord.setTypeName(dingOrgInfoDTO.getTypeName());
            saveRecord.setOrganizationCode(dingOrgInfoDTO.getOrganizationCode());
//            saveRecord.setSubCount((long) dingOrgInfoTreeDTO.getChildCodes().size());
            saveRecord.setOrganizationName(dingOrgInfoDTO.getOrganizationName());
            saveRecord.setDivisionCode(dingOrgInfoDTO.getDivisionCode());
            saveRecordList.add(saveRecord);
            if (CollectionUtils.isNotEmpty(childCodes)) {
                buildSaveRecordList(childCodes, saveRecordList,oldList);
            }
        }
    }
}
