package com.malk.cloudpure.service.impl;

import com.alibaba.fastjson.JSON;
import com.malk.cloudpure.service.CPClient;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.dingtalk.DDConf;
import com.malk.server.dingtalk.DDInterActiveCard;
import com.malk.server.xbongbong.XBBConf;
import com.malk.service.aliwork.YDClient;
import com.malk.service.aliwork.YDService;
import com.malk.service.dingtalk.DDClient;
import com.malk.service.dingtalk.DDClient_Contacts;
import com.malk.service.dingtalk.DDClient_Extension;
import com.malk.service.dingtalk.DDClient_Report;
import com.malk.service.xbongbong.XBBClient;
import com.malk.utils.UtilDateTime;
import com.malk.utils.UtilMap;
import com.malk.utils.UtilNumber;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CPImplClient implements CPClient {

    @Autowired
    private YDClient ydClient;

    @Autowired
    private YDService ydService;

    /**
     * 创建每日数据
     */
    @Synchronized
    @Override
    public void upsertDailyRecord(String userId, String tDate, Map formData) {
        LocalDate nowDate = UtilDateTime.parseLocalDate(tDate);
        YDParam ydParam = YDParam.builder()
                .formUuid("FORM-NT766881IOWD4HLW6372V8H6WS9K2OZJV74ML7")
                .searchFieldJson(JSON.toJSONString(UtilMap.map("employeeField_llw07mxm, textField_lm480aco", userId, tDate)))
                .build();
        //  查询是否存在
        List<Map> dataList = (List<Map>) ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_search_form).getData();
        if (dataList.size() > 0) {
            // OA审批连接器, 累计数字
            if (formData.containsKey("type")) {
                String compId = formData.get("type").toString();
                int num = UtilMap.getInt(((Map) dataList.get(0).get("formData")), compId);
                formData.put(compId, num + 1);
            }
            ydParam.setFormInstanceId(dataList.get(0).get("formInstanceId").toString());
            ydParam.setUpdateFormDataJson(JSON.toJSONString(formData));
            ydClient.operateData(ydParam, YDConf.FORM_OPERATION.update);
            return;
        }
        // 日期格式记录
        Map dateForm = UtilMap.map("employeeField_llw07mxm, dateField_llw07myh, textField_lm480aco, textField_lm480acu, textField_lm480acv, textField_lmdjpnoa",
                Arrays.asList(userId), UtilDateTime.getLocalDateTimeTimeStamp(LocalDateTime.of(nowDate, LocalTime.MIN)), UtilDateTime.formatLocalDate(nowDate), UtilDateTime.formatLocal(nowDate, "yyyy-MM"), UtilDateTime.formatLocalQuarter(nowDate), userId);
        formData.putAll(dateForm);
        ydParam.setFormDataJson(JSON.toJSONString(formData));
        ydClient.operateData(ydParam, YDConf.FORM_OPERATION.create);
    }

    @Autowired
    private DDClient_Report ddClient_log;

    @Autowired
    private DDClient ddClient;

    /**
     * 同步日报数据
     */
    @Override
    public void syncDingTalkLogForRecord(String sDate) {
        // 模板名称 + 取值字段
        List<Map<String, String>> names = Arrays.asList(UtilMap.map("template, category", "日报-组织团队, 有效跟进记录数量"), UtilMap.map("template, category", "业务数字化团队-日报, 当天联系客户数量"));
        long sStart = UtilDateTime.parseDateTime(sDate + " 00:00:00").getTime();
        long sEnd = UtilDateTime.parseDateTime(sDate + " 23:59:59").getTime();
        for (Map name : names) {
            List<Map> dataList = ddClient_log.reportList(ddClient.getAccessToken(), sStart, sEnd, UtilMap.map("template_name", name.get("template")));
            for (Map data : dataList) {
                List<Map> contents = (List<Map>) data.get("contents");
                Optional optional = contents.stream().filter(item -> name.get("category").equals(item.get("key")) || "".equals(item.get("key"))).findAny();
                if (optional.isPresent()) {
                    String userId = data.get("creator_id").toString();
                    // 有效跟进
                    String value = String.valueOf(((Map) optional.get()).get("value"));
                    this.upsertDailyRecord(userId, sDate, UtilMap.map("numberField_llw07mxo", value));
                }
            }
        }
    }

    @Autowired
    private XBBClient xbbClient;

    // 客户数
    private int _queryCustomerList(String url, String userId) {

        //xbbClient.testDefine("", 1, 100); // 客户
        // 查询条件: formId 钉钉客户:864836 Teambition客户:1003094, 负责人 ownerId [ include 包含任一, in 等于任一 ]
        List<Map> conditions = Arrays.asList(
                XBBConf.getConditionMap("ownerId", "in", userId));
        Map data1 = xbbClient.getDataResult(url, 864836, conditions, UtilMap.map("pageSize", 1));
        Map data2 = xbbClient.getDataResult(url, 1003094, conditions, UtilMap.map("pageSize", 1));
        // 客户数合计
        return UtilMap.getInt(data1, "totalCount") + UtilMap.getInt(data2, "totalCount");
    }

    // 跟进记录
    private List<Map> _queryFollowupList(String url, String userId, long start, long end) {

        //xbbClient.testDefine("", 1, 501); // 跟进记录
        // 查询条件: formId 864839, 创建时间 addTime, 创建人 creatorId
        List<Map> dataList = xbbClient.getDataList(url, 864839, Arrays.asList(
                XBBConf.getConditionMap("creatorId", "equal", userId),
                XBBConf.getConditionMap("addTime", "range", start, end)), null);
        // 数据筛选: 跟进内容 text_6, 跟进方式 text_4 [上门拜访 1, 远程会议 484f3265-77a4-5783-9c17-dbecfbf1b816]
        return dataList.stream().map(item -> ((Map) item.get("data"))).collect(Collectors.toList());
    }

    // 销售机会
    private List<Map> _queryOpportunityList(String url, String userId, long start, long end) {

        //xbbClient.testDefine("", 1, 301); // 销售机会
        // 查询条件: formId 864841, 创建时间 addTime, 创建人 creatorId
        List<Map> dataList = xbbClient.getDataList(url, 864839, Arrays.asList(
                XBBConf.getConditionMap("creatorId", "equal", userId),
                XBBConf.getConditionMap("addTime", "range", start, end)), null);
        return dataList.stream().map(item -> ((Map) item.get("data"))).collect(Collectors.toList());
    }

    // 合同订单
    private List<Map> _queryContractList(String url, String userId, long start, long end) {

        //xbbClient.testDefine("", 1, 201); // 合同订单
        // 查询条件: formId 钉钉部门:864843 Teambition部门合同:1283232, , 创建时间 addTime, 创建人 creatorId
        List<Map> conditions = Arrays.asList(
                XBBConf.getConditionMap("creatorId", "equal", userId),
                XBBConf.getConditionMap("addTime", "range", start, end));
        List<Map> dataList = xbbClient.getDataList(url, 864843, conditions, null);
        List<Map> dataList2 = xbbClient.getDataList(url, 1283232, conditions, null);
        dataList.addAll(dataList2);
        // 数据筛选: 合同金额 num_1
        return dataList.stream().map(item -> ((Map) item.get("data"))).collect(Collectors.toList());
    }

    // 回款单
    private List<Map> _queryPaymentSheetList(String url, String userId, long start, long end) {

        //xbbClient.testDefine("", 1, 702); // 回款单
        // 查询条件: formId 864859, 创建时间 addTime, 创建人 creatorId
        List<Map> dataList = xbbClient.getDataList(url, 864859, Arrays.asList(
                XBBConf.getConditionMap("creatorId", "equal", userId),
                XBBConf.getConditionMap("addTime", "range", start, end)), null);
        // 数据筛选: 回款金额 num_1
        return dataList.stream().map(item -> ((Map) item.get("data"))).collect(Collectors.toList());
    }

    /**
     * 同步销帮帮跟进记录, 商机, 合同, 回款
     */
    @Override
    public void syncXBongBongForRecord(String userId, long start, long end) {

        // 用户数
        int totalCount = _queryCustomerList(XBBConf.API_LIST_customer, userId);

        // prd 跟进记录: 远程+上门, 跟进记录数（10字以上）
        List<Map> dataList1 = _queryFollowupList(XBBConf.API_LIST_communicate, userId, start, end);
        int project = dataList1.stream().filter(item ->
                Arrays.asList("1", "484f3265-77a4-5783-9c17-dbecfbf1b816").contains(item.get("text_4"))
        ).collect(Collectors.toList()).size();
        int followup = dataList1.stream().filter(item ->
                UtilMap.getString(item, "text_6").length() >= 10
        ).collect(Collectors.toList()).size();

        // 销售机会: 新建商机数 & 商机金额
        List<Map> dataList2 = _queryOpportunityList(XBBConf.API_LIST_opportunity, userId, start, end);
        int opportunity = dataList2.size();
        double budget = dataList2.stream().mapToDouble(item -> UtilMap.getFloat(item, "num_1"))
                .reduce(0.f, (a, b) -> a + b);
        String budgetT = UtilNumber.formatPrecisionString(budget);

        // 合同订单: 成交合同额
        List<Map> dataList3 = _queryContractList(XBBConf.API_LIST_contract, userId, start, end);
        double amount = dataList3.stream().mapToDouble(item -> UtilMap.getFloat(item, "num_1"))
                .reduce(0.f, (a, b) -> a + b);
        String amountT = UtilNumber.formatPrecisionString(amount);

        // 回款单: 回款额
        List<Map> dataList4 = _queryPaymentSheetList(XBBConf.API_LIST_paymentSheet, userId, start, end);
        double payment = dataList4.stream().mapToDouble(item -> UtilMap.getFloat(item, "num_1"))
                .reduce(0.f, (a, b) -> a + b
                );
        String paymentT = UtilNumber.formatPrecisionString(payment);

        // 销帮帮统计
        this.upsertDailyRecord(userId, UtilDateTime.formatDate(new Date(start * 1000L)), UtilMap.map("numberField_llw07mxt, numberField_llw07mxu, numberField_llw07mxv, numberField_lmee0oez, numberField_llw07myc, numberField_llw07my7, numberField_lmee0oey", project, followup, opportunity, budgetT, amountT, paymentT, totalCount));
    }

    /**
     * 同步销帮帮跟进记录, 商机, 合同, 回款 - [全量]
     */
    @Override
    public void syncXBongBongForRecord_all(LocalDate date) {

        // 查询时间条件为秒级
        long start = UtilDateTime.getLocalDateTimeTimeStamp(LocalDateTime.of(date, LocalTime.MAX.MIN)) / 1000;
        long end = UtilDateTime.getLocalDateTimeTimeStamp(LocalDateTime.of(date, LocalTime.MAX)) / 1000;
        // 宜搭存量人员数据
        YDParam ydParam = YDParam.builder()
                .formUuid("FORM-FDA66N818M1EBF27B7Z5H5JMK3562D8F7FDMLE")
                .build();
        List<Map> formList = (List<Map>) ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_search_form).getData();
        List<String> tUserIds = formList.stream().map(itme -> ((Map) itme.get("formData")).get("textField_lmdgtqop").toString())
                .collect(Collectors.toList());
        for (String userId : tUserIds) {
            syncXBongBongForRecord(userId, start, end);
        }
    }

    @Autowired
    private DDClient_Contacts ddClient_contacts;

    /**
     * 同步销售部门人员 [服务销帮帮]
     */
    @Override
    public void syncBusinessUserInfo() {

        // 宜搭存量人员数据
        YDParam ydParam = YDParam.builder()
                .formUuid("FORM-FDA66N818M1EBF27B7Z5H5JMK3562D8F7FDMLE")
                .build();
        List<Map> formList = (List<Map>) ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_search_form).getData();
        List<String> tUserIds = formList.stream().map(itme -> ((Map) itme.get("formData")).get("textField_lmdgtqop").toString())
                .collect(Collectors.toList());

        // 钉钉事业部 - 商业团队: 94295408 [钉钉事业部 75385376] 客户成功团队: 844485110
        List<Map> deptList = ddClient_contacts.listSubDepartmentDetail(ddClient.getAccessToken(), 94295408L);
        deptList.add(ddClient_contacts.getDepartmentInfo(ddClient.getAccessToken(), 844485110L));
        for (Map deptInfo : deptList) {
            List<String> userIds = ddClient_contacts.listDepartmentUserId(ddClient.getAccessToken(), UtilMap.getLong(deptInfo, "dept_id"));
            for (String userId : userIds) {
                if (tUserIds.contains(userId)) {
                    continue;
                }
                // 增量更新宜搭人员数据
                Map userInfo = ddClient_contacts.getUserInfoById(ddClient.getAccessToken(), userId);
                ydClient.operateData(YDParam.builder()
                        .formUuid("FORM-FDA66N818M1EBF27B7Z5H5JMK3562D8F7FDMLE")
                        .formDataJson(JSON.toJSONString(UtilMap.map("employeeField_lmdf7uib, textField_lmdf7uic, textField_lmdgtqop, textField_lmio2az4, textField_lmio2az5, radioField_lmiojmqr", Arrays.asList(userId), deptInfo.get("name"), userId, userInfo.get("name"), userInfo.get("avatar"), "是")))
                        .build(), YDConf.FORM_OPERATION.create);
            }
        }
    }

    /**
     * 酷应用数据
     */
    @Override
    public Map applicationData(String tDate) {

        List<Map> dataListRank = new ArrayList<>();
        List<Map> dataListDaily = new ArrayList<>();
        // 人员档案
        List<Map> userList = ydService.queryDataList_FormData("FORM-FDA66N818M1EBF27B7Z5H5JMK3562D8F7FDMLE", UtilMap.map("radioField_lmiojmqr", "是"));
        // 每日数据
        List<Map> dailyList = ydService.queryDataList_FormData("FORM-NT766881IOWD4HLW6372V8H6WS9K2OZJV74ML7", UtilMap.map("textField_lm480aco", tDate));
        // 排名数据
        List<Map> rankList = ydService.queryDataList_FormData("FORM-TD966Z81MI1EO8BB8K3J14HDFOS42K2W79EMLF", UtilMap.map("textField_lm480acu", UtilDateTime.format(UtilDateTime.parseDate(tDate), "yyyy-MM")));
        for (Map data : userList) {
            float value = 0;
            if ("客户成功团队".equals(data.get("textField_lmdf7uic"))) {
                continue;
            }
            Map userInfo = UtilMap.map("icon, name", data.get("textField_lmio2az5"), data.get("textField_lmio2az4"));
            // 跟进记录排名
            Optional optional = dailyList.stream().filter(item -> data.get("textField_lmdgtqop").equals(item.get("textField_lmdjpnoa"))).findAny();
            if (optional.isPresent()) {
                Map form = (Map) optional.get();
                value = UtilMap.getFloat(form, "numberField_llw07mxu"); // 跟进记录
            }
            dataListDaily.add(UtilMap.map("value, appItem, team", value, userInfo, data.get("textField_lmdf7uic")));
            // 完成率排名
            optional = rankList.stream().filter(item -> data.get("textField_lmdgtqop").equals(item.get("textField_lmdjpnoa"))).findAny();
            if (optional.isPresent()) {
                Map form = (Map) optional.get();
                value = UtilMap.getFloat(form, "numberField_lme99e3l"); // 季度排名
            }
            dataListRank.add(UtilMap.map("value, appItem, team", value, userInfo, data.get("textField_lmdf7uic")));
        }
        // 排序两种形式
        Collections.sort(dataListDaily, Comparator.comparingDouble(o -> UtilMap.getFloat(o, "value")));
        Collections.reverse(dataListDaily);
        Collections.sort(dataListRank, (o1, o2) -> (int) (UtilMap.getFloat(o2, "value") - UtilMap.getFloat(o1, "value")));
        // 酷应用 table 组件必须要返回表头, 否则数据不能解析
        List<Map> meteList = new ArrayList<>();
        meteList.add(UtilMap.map("aliasName, dataType, alias, weight", "销售", "MICROAPP", "appItem", "30"));
        meteList.add(UtilMap.map("aliasName, dataType, alias, weight", "排名", "STRING", "value", "20"));

        return UtilMap.map("daily, rank, meta", dataListRank, dataListDaily, meteList);
    }

    @Autowired
    private DDClient_Extension ddClient_extension;

    @Autowired
    private DDConf ddConf;

    /**
     * 酷应用消息卡片推送
     */
    @Override
    public void sendCardMessage(String tDate, String... chatNames) {

        // 推送群配置表
        List<Map> chatIdList = ydService.queryDataList_FormData("FORM-WV866IC1ZMDEQAWTAXYSFBJL2XMM2QY4WRPML0", null);
        // 全量查询, 分团队推送
        Map data = applicationData(tDate);
        for (String name : chatNames) {
            Optional optional = chatIdList.stream().filter(item -> name.equals(item.get("textField_lmprwfmw"))).findAny();
            if (optional.isPresent()) {
                _sendCardMessage(data, (Map) optional.get());
            }
        }
    }

    /// 发送卡片消息, 微应用是否配置会话推送不强制
    void _sendCardMessage(Map data, Map<String, String> chat) {

        // 酷应用卡片模板ID
        String cardTemplateId = "bcb35ab8-e1cd-49ba-9081-950357dcf910.schema";
        // 微应用配置机器人编码
        String robotCode = ddConf.getRobotCode();
        // 群内添加酷应用后, 酷应用订阅事件回调群ID
        String openConversationId = chat.get("textField_lmprwfmx");
        Map map = UtilMap.map("meta", data.get("meta"));
        if ("是".equals(chat.get("radioField_lmprwfmz"))) {
            map.put("rank", UtilMap.getList(data, "rank").stream().filter(item -> chat.get("textField_lmprwfmw").equals(((Map) item).get("team"))).collect(Collectors.toList()));
            map.put("daily", UtilMap.getList(data, "daily").stream().filter(item -> chat.get("textField_lmprwfmw").equals(((Map) item).get("team"))).collect(Collectors.toList()));
        } else {
            map.putAll(data);
        }
        Map cardData = DDInterActiveCard.formCardDataForTable(map, "rank", "daily");
        Map extInfo = UtilMap.map("cardOptions", UtilMap.map("supportForward", true)); // 允许转发
        extInfo.put("atOpenIds", UtilMap.map("key", UtilMap.map("**@ALL**", "**@ALL**"))); // @所有人
        ddClient_extension.sendInteractiveCards(ddClient.getAccessToken(), cardTemplateId, String.valueOf(new Date().getTime()), 1, robotCode, "", openConversationId, cardData, extInfo);
    }
}
