package com.malk.hake.service.impl;

import com.alibaba.fastjson.JSON;
import com.malk.hake.service.HKClient;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.common.McException;
import com.malk.server.dingtalk.DDConf;
import com.malk.service.aliwork.YDClient;
import com.malk.service.dingtalk.DDClient;
import com.malk.service.dingtalk.DDClient_Contacts;
import com.malk.service.dingtalk.DDService;
import com.malk.utils.*;
import lombok.SneakyThrows;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
public class HKImplClient implements HKClient {

    @Autowired
    private YDClient ydClient;

    // monitor接口ip
    String _getEnvApi(String path) {
        if (UtilEnv.getActiveProfile().equals(UtilEnv.ENV_PROD)) {
            return "http://172.16.20.13:10002/api/public" + path;
        }
        return "http://116.228.113.106:10001/api/public" + path;
    }

    /**
     * 通用流程发起
     */
    @SneakyThrows
    @Override
    public Map<String, Object> startProcess(String code, Map data) {
        Map meta = (Map) UtilFile.readJsonObjectFromResource("static/json/form.json"); // 本地匹配了宜搭组件ID
        McException.assertAccessException(!meta.containsKey(code), "单据编码未匹配!");
        // 组织单据数据
        Map<String, ?> component = (Map) ((Map) meta.get(code)).get("compIds");
        Map formData = UtilMap.empty();
        for (String key : component.keySet()) {
            if (key.startsWith("employeeField_")) {
                formData.put(key, Arrays.asList(data.get(component.get(key))));
            } else if (key.startsWith("tableField_")) {
                List<Map> rows = (List<Map>) data.get("rows");
                List<Map> details = new ArrayList<>();
                Map<String, String> compIds = (Map) component.get(key);
                for (Map row : rows) {
                    Map detail = UtilMap.empty();
                    for (String prop : compIds.keySet()) {
                        detail.put(prop, row.get(compIds.get(prop)));
                    }
                    details.add(detail);
                }
                formData.put(key, details);
            } else {
                formData.put(key, data.get(component.get(key)));
            }
        }
        // 发起人匹配规则
        String userId = _getUserId(code, meta, data);
        Object InstanceId = ydClient.operateData(YDParam.builder()
                .formUuid(String.valueOf(((Map) meta.get(code)).get("formUuid")))
                .processCode(String.valueOf(((Map) meta.get(code)).get("processCode")))
                .userId(userId)
                .formDataJson(JSON.toJSONString(formData))
                .build(), YDConf.FORM_OPERATION.start);
        // 回传钉钉单据号
        Thread.sleep(800);
        Map form = ydClient.queryData(YDParam.builder()
                .formInstanceId(String.valueOf(InstanceId))
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
        return UtilMap.map("ddProcessId, dtNumber", InstanceId, form.get(meta.get(code + "_RC")));
    }

    /// 发起人处理
    String _getUserId(String code, Map meta, Map data) {
        String userId = String.valueOf(data.get(String.valueOf(((Map) meta.get(code)).get("creator"))));
        // 报价单
        if ("BJ".equals(code)) {
            if (Arrays.asList("样品", "大货").contains(data.get("quoteType"))) {
                userId = String.valueOf(data.get("dtOurReferencePersonId"));
            } else {
                userId = String.valueOf(data.get("dtSellerPersonId"));
            }
        }
        if (UtilString.isBlankCompatNull(userId)) {
            userId = YDConf.PUB_ACCOUNT;
        }
        return userId;
    }

    @Autowired
    private DDClient ddClient;

    @Autowired
    private DDClient_Contacts ddClient_contacts;

    @Autowired
    private DDService ddService;

    private static final String AUTH = "bbb76928-a9db-42fa-ac83-cc9a2ed75162";

    /**
     * 通用审批回调 [区分类型, 宜搭提示不同报错信息]
     */
    @Override
    public void callbackProcess(Map data) {

        // 拒绝审批意见必填校验
        McException.assertParamException_Null(data, "Result");
        if ("0".equals(data.get("Result"))) {
            McException.assertParamException_Null(data, "Remark");
        }
        // 回调monitor审批信息
        data.put("Url", "https://pxi03f.aliwork.com/APP_QWUVLI1R6XYUXWAOPF6O/processDetail?procInsId=" + data.get("DdProcessId"));
        data.put("ApprovalDate", UtilDateTime.formatLocalDateTime(LocalDateTime.now()));
        Map UserInfo = ddClient_contacts.getUserInfoById(ddClient.getAccessToken(), String.valueOf(data.get("Approver")));
        data.put("Approver", String.valueOf(UserInfo.get("name")));
        log.info("审批回调, {}", JSON.toJSONString(data));
        // prd: 通过 http status 判定, 200 即为成功
        String rsp = UtilHttp.doPost(_getEnvApi("/Approval"), UtilMap.map("Authorization", AUTH), UtilMap.map("Code", data.get("Code")), data);
        Map result = (Map) JSON.parse(rsp);
        McException.assertException(result.containsKey("errorMsg"), String.valueOf(result.get("status")), String.valueOf(result.get("errorMsg")), "Monitor");
    }

    /**
     * 通讯录同步
     */
    @Override
    @Synchronized
    public void syncContact() {

        // prd: 非全量同步: 总部\哈克\负责人
        List<Long> deptList = UtilList.asList(DDConf.TOP_DEPARTMENT);
        deptList.addAll(ddClient_contacts.getDepartmentId_all(ddClient.getAccessToken(), true, 129113277L)); // 总部
        deptList.addAll(ddClient_contacts.getDepartmentId_all(ddClient.getAccessToken(), true, 128984162L)); // 哈克
        for (long deptId : deptList) {
            List<String> userIds = ddClient_contacts.listDepartmentUserId(ddClient.getAccessToken(), deptId);
            if (userIds.size() == 0) {
                continue;
            }
            // prd: 取第3层作为部门, 为空取值总经办
            String dpetCascade = ddService.getUserDepartmentHierarchyJoin(ddClient.getAccessToken(), userIds.get(0), "-");
            String deptName = "总经办";
            String[] depts = dpetCascade.split("-");
            if (depts.length >= 3) {
                deptName = depts[2];
            }
            for (String userId : userIds) {
                Map userInfo = ddClient_contacts.getUserInfoById(ddClient.getAccessToken(), userId);
                Map data = UtilMap.map("employeeNumber, employeeName, dtPersonId, lastName", userInfo.get("job_number"), userInfo.get("name"), userInfo.get("userid"), userInfo.get("title"));
                // prd: 手机号花名册未展示, 因此添加判空, 避免覆盖Monitor
                if (StringUtils.isNotBlank(String.valueOf(userInfo.get("mobile")))) {
                    data.put("mobilePhone", userInfo.get("mobile"));
                }
                if (userInfo.containsKey("org_email")) {
                    data.put("email", userInfo.get("org_email"));
                }
                data.put("employeeDept", deptName);
                data.put("dtDepts", dpetCascade);
                data.put("dtPersonGroup", "");
                log.info("同步人员, {}", JSON.toJSONString(UtilMap.map("employees", Arrays.asList(data))));
                _syncContact(data, userId);
            }
        }

        // 离职人员同步
        Date sDate = UtilDateTime.convertToDateFromLocalDateTime(LocalDateTime.now().minusDays(1));
        List<Map<String, String>> maps = ddClient_contacts.getLeaveEmployeeRecords(ddClient.getAccessToken(), sDate, null);
        for (Map<String, String> map : maps) {
            // prd 钉钉离职数据获取不到工号, 通过99999 monitor判断, 若存在则更新部门, 负责忽略
            Map data = UtilMap.map("employeeNumber, employeeName, dtPersonId, mobilePhone, employeeDept", "99999", map.get("name"), map.get("userId"), map.get("mobile"), "离职");
            _syncContact(data, map.get("userId"));
            log.info("离职人员, {}", JSON.toJSONString(UtilMap.map("employees", Arrays.asList(data))));
        }
    }

    /// 员工信息写入monitor
    void _syncContact(Map data, String userId) {

        // prd: 通过 http status 判定, 200 即为成功
        String rsp = UtilHttp.doPost(_getEnvApi("/EmployeeImport"), UtilMap.map("Authorization", AUTH), null, UtilMap.map("employees", Arrays.asList(data)));
        Map result = (Map) JSON.parse(rsp);
        if (UtilList.isNotEmpty(UtilMap.getList(result, "fail"))) {
            result = (Map) UtilMap.getList(result, "fail").get(0); // 单条同步, 记录错误人员
        }
        //McException.assertException(result.containsKey("msg"), String.valueOf(result.get("status")), String.valueOf(result.get("msg")), "Monitor");
        if (result.containsKey("msg")) {
            ydClient.operateData(YDParam.builder()
                    .formUuid("FORM-W2A66Z91912F39B2AHY0VD4CRK9F3C4JB74OLN")
                    .formDataJson(JSON.toJSONString(UtilMap.map("dateField_lo47byyd, employeeField_lo47byyj, textareaField_lo47byyo, textareaField_lo47sanj", new Date().getTime(), userId, result, data)))
                    .build(), YDConf.FORM_OPERATION.create);
        }
    }

    /**
     * 拉取数据发起
     */
    @Override
    public void syncMonitor(String code) {

        String rsp = UtilHttp.doPost(_getEnvApi("/Payment"), UtilMap.map("Authorization", AUTH), null, UtilMap.empty());
        Map result = (Map) JSON.parse(rsp);
        // prd: 通过 http status 判定, 200 即为成功
        for (Map row : (List<Map>) UtilMap.getList(result, "rows")) {
            startProcess(code, row);
        }
    }
}
