package com.cpop.oam.web;

import cn.hutool.poi.excel.ExcelDateUtil;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.table.SysUser;
import com.cpop.core.mapper.CoreMapper;
import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.file.FileUtils;
import com.cpop.core.utils.uuid.IdUtils;
import com.cpop.oam.business.dto.DataImportDto;
import com.cpop.oam.business.entity.Dept;
import com.cpop.oam.business.entity.Staff;
import com.cpop.oam.business.entity.StaffMidDept;
import com.cpop.oam.business.service.DeptService;
import com.cpop.oam.business.service.StaffMidDeptService;
import com.cpop.oam.business.service.StaffService;
import com.cpop.oam.framework.config.wxCp.WxCpConfiguration;
import com.mybatisflex.core.row.Db;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.bean.export.WxCpExportRequest;
import me.chanjar.weixin.cp.bean.export.WxCpExportResult;
import me.chanjar.weixin.cp.bean.external.WxCpUserExternalGroupChatInfo;
import me.chanjar.weixin.cp.bean.external.WxCpUserExternalGroupChatList;
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactBatchInfo;
import me.chanjar.weixin.cp.bean.user.WxCpDeptUserResult;
import org.apache.commons.codec.binary.Base64;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author DB
 * @createTime 2023/10/12 15:19
 * @description 企业微信Api测试
 */
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Slf4j
public class CpopWxCpTests {

    /**
     * @descriptions 获取成员ID列表
     * @author DB
     * @date 2023/10/12 15:33
     * @return: void
     */
    @Test
    public void userListId() {
        try {
            WxCpDeptUserResult userListId = WxCpConfiguration.getCpService(1000024).getUserService().getUserListId("", 100);
            System.out.println(userListId);
        } catch (WxErrorException e) {
            throw new ServiceException(e.getMessage());
        }
    }

    /**
     * 根据手机号获取用户id
     */
    @Test
    public void getUserId() {
        try {
            String userId = WxCpConfiguration.getCpService(1000024).getUserService().getUserId("17728500831");
            System.out.println(userId);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据用户id获取用户
     */
    @Test
    public void getUser() {
        try {
            WxCpUser user = WxCpConfiguration.getCpService(1000024).getUserService().getById("XiaoKanTianSeMuKanYun");
            System.out.println(user);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取部门列表
     */
    @Test
    public void getDepartmentList() {
        try {
            List<WxCpDepart> wxCpDeparts = WxCpConfiguration.getCpService(1000000).getDepartmentService().simpleList(1L);
            System.out.println(wxCpDeparts);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
    }

    @Test
    public void getDeptById() {
        try {
            WxCpDepart wxCpDepart = WxCpConfiguration.getCpService(1000024).getDepartmentService().get(1L);
            System.out.println(wxCpDepart);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 导出部门
     */
    @Test
    public void exportDept() {
        try {
            WxCpExportRequest request = new WxCpExportRequest();
            request.setEncodingAesKey("DLSzfHVUZN3O9WhtL07RBXUoooqC2bjEJYwep8k8ojt");
            String jabId = WxCpConfiguration.getCpService(1000024).getExportService().department(request);
            System.out.println(jabId);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @descriptions 获取导出结果
     * @author DB
     * @date 2023/10/13 16:18
     * @return: void
     */
    @Test
    public void getExportResult() throws WxErrorException {
        //jobid_dFssU8d6nirNJjOHwoxoPV23OzWH6edwrb__ilftwyA
        WxCpExportResult result = WxCpConfiguration.getCpService(1000024).getExportService().getResult("jobid__qH9HAsRGgeErUVEaJA1UnOFpjuL7CQddh11dYtDE6s");
        System.out.println(result);
    }

    /**
     * @descriptions 解密导出数据
     * @author DB
     * @date 2023/10/13 16:49
     * @return: void
     */
    @Test
    public void decryptExportData(){
        String result = getDecryptExportData("DLSzfHVUZN3O9WhtL07RBXUoooqC2bjEJYwep8k8ojt", "https://szfront.wxwork.qq.com:443/downloadobject?fileid=080112043133303122093131343535363239362a0131322463396566396533662d626332392d346666622d623033652d623034626633343633656539388004421453e8114eb1942bcda5dfca7c8457534c237ab95448015802600768b8177207333030303030308a010b6170706c69636174696f6e90018ffba3a9069a0100a001d5b703&weixinnum=2519320458&authkey=7008001005186022606b8b2cec47b7d5c6a502d671c77f8b35bfb4908f7cc912258e5c54554a0485f9b61c484bb3f5c56fc823c2b3aefed8b319fd113a0220b6297a7879c4a3d50313c6bc91b004c50efd6d2849165eb511f52b8027d3f34de5e970d95291af935be7&filename=data_0.json");
        if (result != null) {
            System.out.println(result.substring(0, result.lastIndexOf("}") + 1));
        }
    }

    public final String getDecryptExportData(String aesKey, String url) {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<byte[]> responseEntity = restTemplate.getForEntity(url, byte[].class);
        if (responseEntity.getBody() == null) {
            return null;
        }
        byte[] key = Base64.decodeBase64(aesKey + "=");
        byte[] original = null;
        try {
            // 设置解密模式为AES的CBC模式
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
            IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(key, 0, 16));
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
            original = cipher.doFinal(responseEntity.getBody());
        } catch (Exception e) {
            log.error("", e);
        }
        assert original != null;
        return new String(original);
    }

    /**
     * @descriptions 导入部门
     * @author DB
     * @date 2023/10/13 16:54
     * @return: void
     */
    @Test
    public void importDept() {
        //将导出数据转换
        String result = getDecryptExportData("DLSzfHVUZN3O9WhtL07RBXUoooqC2bjEJYwep8k8ojt", "https://szfront.wxwork.qq.com:443/downloadobject?fileid=080112043133303122093131343535363239362a0131322463396566396533662d626332392d346666622d623033652d623034626633343633656539388004421453e8114eb1942bcda5dfca7c8457534c237ab95448015802600768b8177207333030303030308a010b6170706c69636174696f6e90018ffba3a9069a0100a001d5b703&weixinnum=2519320458&authkey=7008001005186022606b8b2cec47b7d5c6a502d671c77f8b35bfb4908f7cc912258e5c54554a0485f9b61c484bb3f5c56fc823c2b3aefed8b319fd113a0220b6297a7879c4a3d50313c6bc91b004c50efd6d2849165eb511f52b8027d3f34de5e970d95291af935be7&filename=data_0.json");
        //导出集合
        List<ExportDept> exportDeptList = JSONObject.parseObject(result).getJSONArray("department").toJavaList(ExportDept.class);
        //转换部门
        List<Dept> list = new ArrayList<>();
        exportDeptList.forEach(item -> {
            Dept dept = new Dept();
            dept.setWxCpId(item.getId())
                    .setWxCpParentId(item.getParentId())
                    .setOrderNo(item.getOrder())
                    .setName(item.getName());
            list.add(dept);
        });
        //批量导入数据
        DeptService deptService = SpringUtils.getBean(DeptService.class);
        deptService.saveBatch(list);
        //同步父id
        Map<Long, Dept> deptMap = list.stream().collect(Collectors.toMap(Dept::getWxCpId, item -> item));
        list.forEach(item->{
            if (null != deptMap.get(item.getWxCpParentId())){
                item.setParentId(deptMap.get(item.getWxCpParentId()).getId());
            }
        });
        //批量更新
        deptService.updateBatch(list);
    }

    /**
     * 导出部门数据
     */
    @Data
    public class ExportDept {

        /**
         * 部门id
         */
        private Long id;

        /**
         * 部门名
         */
        private String name;

        /**
         * 父部门id
         */
        @JSONField(name = "parentid")
        private Long parentId;

        /**
         * 排序
         */
        private Integer order;
    }

    @Test
    public void getUserList() throws WxErrorException {
        WxCpExportRequest request = new WxCpExportRequest();
        request.setEncodingAesKey("DLSzfHVUZN3O9WhtL07RBXUoooqC2bjEJYwep8k8ojt");
        String jobId = WxCpConfiguration.getCpService(1000024).getExportService().user(request);
        System.out.println(jobId);
    }

    /**
     * @descriptions 导出员工
     * @author DB
     * @date 2023/10/16 9:20
     * @return: void
     */
    @Test
    public void importStaffList() throws WxErrorException {
        //https://szfront.wxwork.qq.com:443/downloadobject?fileid=080112043133303122093131343535363239362a0131322464333430383931612d386139312d346262652d616231302d62353464653065383035316138a03b42149c55bf3c6169f900ae391370dd348245dd7308a548015802600768b8177207333030303030308a010b6170706c69636174696f6e900197a4b2a9069a0100a0019cdf03&weixinnum=2909765272&authkey=700800100918602260b996bf284cb359495885b1480d4065832650ca9911785379ca2fe340691640e9e97f18aa5e0df436f97b866f7364f9ea4b81497eca584fedd26dca5fb1afdbcf42508abe97ef4529ec213ade2dac789a350500807294c0c941157438264a30c7&filename=data_0.json
        String result = getDecryptExportData("DLSzfHVUZN3O9WhtL07RBXUoooqC2bjEJYwep8k8ojt", "https://szfront.wxwork.qq.com:443/downloadobject?fileid=080112043133303122093131343535363239362a0131322464333430383931612d386139312d346262652d616231302d62353464653065383035316138a03b42149c55bf3c6169f900ae391370dd348245dd7308a548015802600768b8177207333030303030308a010b6170706c69636174696f6e900197a4b2a9069a0100a0019cdf03&weixinnum=2909765272&authkey=700800100918602260b996bf284cb359495885b1480d4065832650ca9911785379ca2fe340691640e9e97f18aa5e0df436f97b866f7364f9ea4b81497eca584fedd26dca5fb1afdbcf42508abe97ef4529ec213ade2dac789a350500807294c0c941157438264a30c7&filename=data_0.json");
        JSONArray department = JSONObject.parseObject(result).getJSONArray("userlist");
        //转换员工，用户
        List<Staff> staffList = new ArrayList<>();
        List<SysUser> sysUserList = new ArrayList<>();
        List<ExportUser> exportUsers = department.toJavaList(ExportUser.class);
        //获取当前创建人员信息
        LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
        Map<Integer, Staff> userMapStaff = new HashMap<>();
        AtomicReference<Integer> flag = new AtomicReference<>(0);
        exportUsers.forEach(item -> {
            //创建用户
            SysUser sysUser = new SysUser();
            sysUser.setId(IdUtils.fastSimpleUUID());
            sysUser.setPassword("$2a$10$6CA0M3iyO8u8zSVtmufYGO3KfLvjaE5fxdHCqTQ2NpxYH/Dxi/fBu")
                    .setNickName(item.getAlias())
                    .setStatus(item.getStatus())
                    .setUserType(UserType.OAM_USER.toString());
            sysUser.setCreateUserId(loginUser == null ? "1" : loginUser.getUserId());
            sysUser.setUpdateUserId(loginUser == null ? "1" : loginUser.getUserId());
            sysUserList.add(sysUser);
            //转换员工
            Staff staff = BeanUtils.mapToClass(item, Staff.class);
            staff.setName(item.getName())
                    //默认售后人员，由管理人员修改
                    .setStaffType(1)
                    //设置角色信息
                    //.setRoleId()
                    .setWxCpUserId(item.getWxCpUserId());
            //放入一个map集合中
            userMapStaff.put(flag.get(), staff);
            flag.getAndSet(flag.get() + 1);
        });
        Db.executeBatch(sysUserList, CoreMapper.class, CoreMapper::insertSysUser);
        for (int i = 0; i < sysUserList.size(); i++) {
            SysUser sysUser = sysUserList.get(i);
            Staff staff = userMapStaff.get(i);
            staff.setUserId(sysUser.getId());
            staffList.add(staff);
        }
        SpringUtils.getBean(StaffService.class).saveBatch(staffList);
        //导入用户信息分组
        Map<String, ExportUser> exportUserMap = exportUsers.stream().collect(Collectors.toMap(ExportUser::getWxCpUserId, item -> item));
        //获取所有部门信息
        Map<Long, Dept> deptMap = SpringUtils.getBean(DeptService.class).list().stream().collect(Collectors.toMap(Dept::getWxCpId, item -> item));
        List<StaffMidDept> staffMidDeptList = new ArrayList<>();
        //设置中间部门表信息
        staffList.forEach(item->{
            ExportUser exportUser = exportUserMap.get(item.getWxCpUserId());
            exportUser.getDepartment().forEach(innerItem->{
                StaffMidDept staffMidDept = new StaffMidDept();
                staffMidDept.setDeptId(deptMap.get(innerItem).getId());
                staffMidDept.setStaffId(item.getId());
                staffMidDeptList.add(staffMidDept);
            });
        });
        SpringUtils.getBean(StaffMidDeptService.class).getMapper().insertBatch(staffMidDeptList);
    }

    /**
     * 导入用户
     */
    @Data
    public class ExportUser {

        /**
         * 成员名称
         */
        private String name;

        /**
         * 别名
         */
        private String alias;

        /**
         * 座机
         */
        private String telephone;

        /**
         * 职位名称
         */
        private String position;

        /**
         * 成员所属部门id列表
         */
        private List<Long> department;

        /**
         * 表示在所在的部门内是否为部门负责人
         */
        @JSONField(name = "is_leader_in_dept")
        private List<Long> isLeaderInDept;

        /**
         * 企业微信用户id
         */
        @JSONField(name = "userid")
        private String wxCpUserId;

        /**
         * 是否启用
         */
        private Boolean status;

        /**
         * 部门排序
         */
        private List<Long> order;
    }

    /**
     * 获取线索
     * @author DB
     * @since 2024/2/18
     */
    @Test
    public void getClueList() throws WxErrorException {
        WxCpService cpService = WxCpConfiguration.getCpService(1000024);
        WxCpExternalContactService externalContactService = cpService.getExternalContactService();
        String[] userIds = {"YiHaiNan","ChenShuJie","ChenWei","GuTingTing","9106a48341c538f2f634343241c7e37a","LanShengYao","LiMei","LiuYe","MaYaLan","NiXuMei","PanYanXia","YangTingHong","ZhangCongTang","ZhaoSuMin"};
        List<WxCpExternalContactBatchInfo.ExternalContactInfo> externalData = getExternalData(null,externalContactService, null, userIds);
        List<ExportClueData> exportClueDataList = new ArrayList<>();
        externalData.forEach(item->{
            ExportClueData exportClueData = new ExportClueData();
            exportClueData.setType(item.getExternalContact().getType() == 1 ? "微信用户" : "企业微信用户");
            exportClueData.setUserid(item.getFollowInfo().getUserId());
            exportClueData.setName(item.getExternalContact().getName());
            exportClueData.setExternalUserid(item.getExternalContact().getExternalUserId());
            exportClueDataList.add(exportClueData);
        });
        List<ExportClueData> filterExportClueDataList = new ArrayList<>();
        exportClueDataList.stream().collect(Collectors.groupingBy(ExportClueData::getExternalUserid))
                .forEach((key, value) ->{
                    if(value.size() > 1){
                        filterExportClueDataList.add(value.get(0));
                    }
                });
        Map<String, ExportClueData> externalUserMap = filterExportClueDataList.stream().collect(Collectors.toMap(ExportClueData::getExternalUserid, item -> item));
        WxCpUserExternalGroupChatList wxCpUserExternalGroupChatList = externalContactService.listGroupChat(1000, null, 0, userIds);
        wxCpUserExternalGroupChatList.getGroupChatList().forEach(item->{
            try {
                WxCpUserExternalGroupChatInfo groupChatInfo = externalContactService.getGroupChat(item.getChatId(), 1);
                WxCpUserExternalGroupChatInfo.GroupChat groupChat = groupChatInfo.getGroupChat();
                List<String> collect = groupChat.getMemberList().stream().map(WxCpUserExternalGroupChatInfo.GroupMember::getUserId).collect(Collectors.toList());
                collect.forEach(inner->{
                    ExportClueData exportClueData = externalUserMap.get(inner);
                    if (exportClueData != null){
                        exportClueData.setGroupName(groupChatInfo.getGroupChat().getName());
                    }
                });
            } catch (WxErrorException e) {
                throw new RuntimeException(e);
            }
        });
        File file = new File("D:\\Lost\\桌面\\线索池数据.xlsx");
        EasyExcel.write(file, ExportClueData.class)
                .sheet("已知线索池")
                .doWrite(() -> {
                    // 分页查询数据
                    return filterExportClueDataList;
                });
    }

    private List<WxCpExternalContactBatchInfo.ExternalContactInfo> getExternalData(List<WxCpExternalContactBatchInfo.ExternalContactInfo> allExternalContactList, WxCpExternalContactService externalContactService, String nextCursor, String[] userIds) throws WxErrorException {
        WxCpExternalContactBatchInfo contactDetailBatch = externalContactService.getContactDetailBatch(userIds, nextCursor, null);
        List<WxCpExternalContactBatchInfo.ExternalContactInfo> externalContactList = contactDetailBatch.getExternalContactList();
        if (allExternalContactList != null){
            allExternalContactList.addAll(externalContactList);
        } else {
            allExternalContactList = externalContactList;
        }
        if (StringUtils.isNotBlank(contactDetailBatch.getNextCursor())) {
            return getExternalData(allExternalContactList, externalContactService, contactDetailBatch.getNextCursor(), userIds);
        } else {
            return allExternalContactList;
        }
    }

    @Data
    public class ExportClueData{

        /**
         * 联系人名称
         */
        @ExcelProperty(value = "联系人名称")
        private String name;

        /**
         * 客户群名
         */
        @ExcelProperty(value = "客户群名")
        private String groupName;

        /**
         * 联系人类型
         */
        @ExcelProperty(value = "联系人类型")
        private String type;

        /**
         * 联系人userid
         */
        @ExcelProperty(value = "联系人userid")
        @JSONField(name = "external_userid")
        private String externalUserid;

        /**
         * 系统微信用户id
         */
        @ExcelProperty(value = "系统微信用户id")
        private String userid;

        /**
         * 校区名
         */
        @ExcelProperty(value = "校区名")
        private String storeName;

        /**
         * 校区id
         */
        @ExcelProperty(value = "校区id")
        private String storeId;
    }
}
