package cn.iocoder.yudao.server.rest;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.oa.SslSkippingRestTemplate;
import cn.iocoder.yudao.server.controller.admin.vo.crm.CrmTodoVo;
import cn.iocoder.yudao.server.dal.dataobject.CrmNoticeDO;
import cn.iocoder.yudao.server.dal.dataobject.CrmPersonDO;
import cn.iocoder.yudao.server.dal.mysql.CrmNoticeMapper;
import cn.iocoder.yudao.server.dal.mysql.CrmPersonMapper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableMap;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Component
public class CrmRest {
    private static final String CLIENT_ID = "baca57533e1909447a6f1918cad00bc2";
    private static final String CLIENT_SECRET = "d38fcf6dcb0f754cece55862b1ae77b3";
    private static final String REDIRECT_URI = "https://api-tencent.xiaoshouyi.com/";
    private final CrmNoticeMapper crmNoticeMapper;
    private final CrmPersonMapper crmPersonMapper;

    public CrmRest(CrmNoticeMapper crmNoticeMapper, CrmPersonMapper crmPersonMapper) {
        this.crmNoticeMapper = crmNoticeMapper;
        this.crmPersonMapper = crmPersonMapper;
    }

    /**
     * 刷新token
     * @param refreshToken
     * @return
     */
    public ImmutableMap<String, String> refreshToken(String refreshToken) {
        HttpHeaders headers = new HttpHeaders();
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();

        String result = restTemplate.postForObject("https://login.xiaoshouyi.com/auc/oauth2/token?grant_type=refresh_token&client_id="
                +CLIENT_ID+"&client_secret="+CLIENT_SECRET+"&refresh_token="+refreshToken, requestEntity, String.class);
        JSONObject jsonObject = JSON.parseObject(result);
        String accessToken = String.valueOf(jsonObject.get("access_token"));
        String refreshToken1 = String.valueOf(jsonObject.get("refresh_token"));
        return ImmutableMap.of("access",accessToken,"refresh",refreshToken1);
    }

    /**
     * 查询用户信息，为了获取userid
     *
     * @param token
     * @return
     */
    public String querySqlUser(String token, String dingUserId) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", token);
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
        ResponseEntity<String> exchange = restTemplate.exchange("https://api-tencent.xiaoshouyi.com/rest/data/v2/query?" +
                        "q=select id,name,unionId,phone,personalEmail from user where unionId is not null limit 0,300",
                HttpMethod.GET, requestEntity, String.class);
        String body = exchange.getBody();
        String result = JSON.parseObject(body).getString("result");
        String records = JSON.parseObject(result).getJSONArray("records").toJSONString();

        List<CrmUser> crmUsers = JSON.parseArray(records, CrmUser.class);
        List<CrmPersonDO> crmPersonDOS = crmPersonMapper.selectList();
        Set<String> existIds = crmPersonDOS.stream()
                .map(CrmPersonDO::getCrmUserId)
                .collect(Collectors.toSet());


        //插入自己的数据库，保存crm人员信息
        List<CrmUser> needInsertUsers = crmUsers.stream()
                .filter(user -> !existIds.contains(user.getId()))
                .collect(Collectors.toList());
        List<CrmPersonDO> collect = needInsertUsers.stream().map(e -> {
            CrmPersonDO crmPersonDO = new CrmPersonDO();
            crmPersonDO.setCrmUserId(e.getId());
            crmPersonDO.setCrmUserName(e.getName());
            crmPersonDO.setCrmUserPhone(e.getPhone());
            crmPersonDO.setCrmUserMail(e.getPersonalEmail());
            crmPersonDO.setCrmUserUnionid(e.getUnionId());
            crmPersonDO.setDeleted(false);
            return crmPersonDO;
        }).collect(Collectors.toList());
        crmPersonMapper.insertBatch(collect);

        AtomicReference<String> userId = new AtomicReference<>("");
        if (crmUsers != null) {
            crmUsers.stream().filter(e -> e.getUnionId().equals(dingUserId)).findAny().ifPresent(f ->{
                userId.set(f.getId());
            });
        }
        return userId.get();
    }


    public void querySqlUserJob(String token) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", token);
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
        ResponseEntity<String> exchange = restTemplate.exchange("https://api-tencent.xiaoshouyi.com/rest/data/v2/query?" +
                        "q=select id,name,unionId,phone,personalEmail from user where unionId is not null limit 0,300",
                HttpMethod.GET, requestEntity, String.class);
        String body = exchange.getBody();
        String result = JSON.parseObject(body).getString("result");
        String records = JSON.parseObject(result).getJSONArray("records").toJSONString();

        List<CrmUser> crmUsers = JSON.parseArray(records, CrmUser.class);
        List<CrmPersonDO> crmPersonDOS = crmPersonMapper.selectList();
        Set<String> existIds = crmPersonDOS.stream()
                .map(CrmPersonDO::getCrmUserId)
                .collect(Collectors.toSet());


        //插入自己的数据库，保存crm人员信息
        List<CrmUser> needInsertUsers = crmUsers.stream()
                .filter(user -> !existIds.contains(user.getId()))
                .collect(Collectors.toList());
        List<CrmPersonDO> collect = needInsertUsers.stream().map(e -> {
            CrmPersonDO crmPersonDO = new CrmPersonDO();
            crmPersonDO.setCrmUserId(e.getId());
            crmPersonDO.setCrmUserName(e.getName());
            crmPersonDO.setCrmUserPhone(e.getPhone());
            crmPersonDO.setCrmUserMail(e.getPersonalEmail());
            crmPersonDO.setCrmUserUnionid(e.getUnionId());
            crmPersonDO.setDeleted(false);
            return crmPersonDO;
        }).collect(Collectors.toList());
        crmPersonMapper.insertBatch(collect);
    }

    public ImmutableMap<String, Object> getCrmTodoList(String token, String crmUserId, String type, Integer pageSize, Integer pageNo) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", token);
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
        ResponseEntity<String> exchange = restTemplate.exchange("https://api-tencent.xiaoshouyi.com/rest/data/v2.0/creekflow/task/filter?assigneeIds="+crmUserId+"&status="+type+"&pageNum="+pageNo+"&pageSize="+pageSize, HttpMethod.GET, requestEntity, String.class);
        String data = null;
        String records = null;
        try {
            String body = exchange.getBody();
            data = JSON.parseObject(body).getString("data");
            records = JSON.parseObject(data).getJSONArray("records").toJSONString();
        } catch (Exception e) {
            return ImmutableMap.of("todoCount", 0,"todoList", new ArrayList<>());
        }
        List<CrmTodoVo> crmTodoVos = JSON.parseArray(records, CrmTodoVo.class);
        Integer dataCount = JSON.parseObject(data).getInteger("dataCount");
        List<CrmPersonDO> crmPersonDOS = crmPersonMapper.selectList();
        crmTodoVos.forEach(e ->{
            crmPersonDOS.stream().filter(f -> f.getCrmUserId().equals(String.valueOf(e.getId()))).findAny().ifPresent(f ->{
                e.setUserName(f.getCrmUserName());
            });
        });
        return ImmutableMap.of("todoCount", dataCount,"todoList", crmTodoVos);
    }

    public List getCrmNotice(String token, String crmUserId, String workcode) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", token);
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
        ResponseEntity<String> exchange = restTemplate.exchange("https://api-tencent.xiaoshouyi.com/rest/notice/v2.0/notice/actions/list?userId="+crmUserId+"&pageNo=1&pageSize=1000",
                HttpMethod.GET, requestEntity, String.class);
        JSONArray objects = null;
        try {
            String body = exchange.getBody();
            String data = JSON.parseObject(body).getString("result");
            objects = JSON.parseArray(data);
        } catch (Exception e) {
            return new ArrayList();
        }
        if (CollUtil.isEmpty(objects)) {return new ArrayList<>();}
        String data1 = JSON.parseObject(objects.get(0).toString()).getString("data");
        String records = JSON.parseObject(data1).getJSONArray("records").toJSONString();
        List<CrmNotice> crmNotices = JSON.parseArray(records, CrmNotice.class);

        //todo 异步逻辑处理
//        CompletableFuture.runAsync(()->{
            //先删除
           //crmNoticeMapper.deleteByMap(ImmutableMap.of("work_code",workcode));
        //取最近的那条纪录
        CrmNoticeDO crmNoticeDO1 = crmNoticeMapper.selectList("work_code", workcode).stream()
                .max(Comparator.comparing(CrmNoticeDO::getCreatedAt))
                .orElse(null);
        if (crmNoticeDO1 == null) {
            insertBatchNotice(crmNotices, workcode);
        }else {
            List<CrmNotice> collect = crmNotices.stream().filter(e -> {
                CrmNoticeDetail notice = e.getNotice();
                if (notice == null) {return false;}
                return notice.getStatus() != 1&&notice.getCreatedAt()>Long.parseLong(crmNoticeDO1.getCreatedAt());
            }).collect(Collectors.toList());
            insertBatchNotice(collect, workcode);
        }
        return crmNotices;
    }

    public void insertBatchNotice(List<CrmNotice> crmNotices, String workcode) {
        crmNotices.forEach(e ->{
            CrmNoticeDO crmNoticeDO = new CrmNoticeDO();
            CrmNoticeDetail notice = e.getNotice();
            BeanUtils.copyProperties(notice,crmNoticeDO);
            crmNoticeDO.setContentMajor(e.getContent());
            crmNoticeDO.setDeleted(false);
            crmNoticeDO.setWorkCode(workcode);
            crmNoticeMapper.insert(crmNoticeDO);
        });
    }

    @Data
    static class CrmUser{
        private String id;
        private String name;
        private String unionId;
        private String phone;
        private String personalEmail;
    }

    @Data
    static class CrmNotice{
        private String content;
        private CrmNoticeDetail notice;
    }
    @Data
    static class CrmNoticeDetail {
        private Long sourceId;
        private int typeFlg;
        private String systemId;
        private Long targetId;
        private Long operateId;
        private int noticeType;
        private String content;
        private Long createdAt;
        private int appType;
        private Long tenantId;
        private Long beLongId;
        private Long id;
        private int status;
    }
}
