package com.malk.cloudpure.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.malk.cloudpure.helper.ApiRequestWrapper;
import com.malk.server.common.McException;
import com.malk.server.common.McR;
import com.malk.server.xbongbong.DigestUtil;
import com.malk.server.xbongbong.XBBConf;
import com.malk.service.dingtalk.DDClient;
import com.malk.service.dingtalk.DDClient_Contacts;
import com.malk.service.dingtalk.DDClient_Notable;
import com.malk.service.dingtalk.DDClient_Personnel;
import com.malk.service.xbongbong.XBBClient;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 错误抛出与拦截详见 CatchException
 */
@Slf4j
@RestController
@RequestMapping("crm")
public class XBBController {

    @Autowired
    private XBBClient xbbClient;
    @Autowired
    private DDClient ddClient;
    @Autowired
    private DDClient_Contacts ddClientContacts;

    @Autowired
    private DDClient_Notable ddClientNotable;

    private static List<Integer> AUTH_WHITELIST_DEPFIDS=Arrays.asList(95172190,333372743); // 权限白名单

    /**
     * 模糊查询归属权限下客户列表
     */
    @PostMapping("list/customer")
    McR customerList(@RequestBody Map<String, String> data) {

        log.info("客户列表, {}", data);
        McException.assertParamException_Null(data, "name, userId");
        boolean isNeedAuth = !UtilMap.getString(data,"isNeedAuth").equals("false"); // 调用方是否需要验证权限
        if(!isNeedAuth){
            // 判断用户部门是否是交付部、售前部门
            Map userInfo=ddClientContacts.getUserInfoById(ddClient.getAccessToken(), data.get("userId"));
            List<Integer> temp = new ArrayList<>(AUTH_WHITELIST_DEPFIDS);
            List<Integer> dept_id_list=UtilMap.getList(userInfo,"dept_id_list");
            temp.retainAll(dept_id_list); // 保留两个列表中都存在的元素
            isNeedAuth=temp.isEmpty(); // 结果为空需要验证权限
        }
        List<Map> customers = new ArrayList<>();
        customers.addAll(_likeCustomerList(XBBConf.API_LIST_customer, "钉钉", data.get("name"), data.get("userId"),isNeedAuth));
        customers.addAll(_likeCustomerList(XBBConf.API_LIST_customer, "Teambition", data.get("name"), data.get("userId"),isNeedAuth));

        log.info("客户响应, {}", customers);
        return McR.success(customers);
    }

    /**
     * 模糊查询归属权限下, 指定字段类型 [后置查询]
     */
    private List<Map> _likeCustomerList(String url, String type, String name, String userId,boolean isNeedAuth) {
        List<Map> rsp = xbbClient.getFormList(type, 1, 100);
        long formId = UtilMap.getLong(rsp.get(0), "formId");
        rsp = xbbClient.getFormDefine(formId, 0); // 表单定义
        String nameField = (rsp.stream().filter(item -> item.get("attrName").equals("客户名称")).findAny().get()).get("attr").toString();
        rsp = xbbClient.getDataList(url, formId, Arrays.asList(XBBConf.getConditionMap(nameField, "like", name)), null);
        return rsp.stream().filter(item -> {
            List<String> ownerId = (List<String>) JSON.parse(String.valueOf(((Map) item.get("data")).get("ownerId")));
            List<String> coUserId = (List<String>) JSON.parse(String.valueOf(((Map) item.get("data")).get("coUserId")));
            // 后置查询, 属于客户负责人和协同人
            return isNeedAuth ? ownerId.contains(userId) || coUserId.contains(userId) :true;
        }).map(item -> UtilMap.map("name", String.valueOf(((Map) item.get("data")).get(nameField)))).collect(Collectors.toList());
    }

    /**
     * 模糊查询归属权限下, 指定字段类型 [后置查询]
     */
    private List<Map> _likeContractList(String url, String type, String name, String userId) {
        List<Map> rsp = xbbClient.getFormList(type, 1, 201);
        long formId = UtilMap.getLong(rsp.get(0), "formId");
        rsp = xbbClient.getFormDefine(formId, 0); // 表单定义
        String nameField = (rsp.stream().filter(item -> item.get("attrName").equals("合同名称")).findAny().get()).get("attr").toString();
        String codeField = (rsp.stream().filter(item -> item.get("attrName").equals("合同编号")).findAny().get()).get("attr").toString();
        String cashField = (rsp.stream().filter(item -> item.get("attrName").equals("合同金额")).findAny().get()).get("attr").toString();
        rsp = xbbClient.getDataList(url, formId, Arrays.asList(XBBConf.getConditionMap(nameField, "like", name)), null);
        return rsp.stream().filter(item -> {
            List<String> ownerId = (List<String>) JSON.parse(String.valueOf(((Map) item.get("data")).get("ownerId")));
            List<String> coUserId = (List<String>) JSON.parse(String.valueOf(((Map) item.get("data")).get("coUserId")));
            // 后置查询, 属于客户负责人和协同人
            return ownerId.contains(userId) || coUserId.contains(userId);
        }).map(item -> {
            Map data = (Map) item.get("data");
            return UtilMap.map("name, value", data.get(nameField), data.get(codeField) + "/" + data.get(cashField));
        }).collect(Collectors.toList());
    }

    /**
     * 模糊查询归属权限下合同列表
     */
    @PostMapping("list/contract")
    McR contractList(@RequestBody Map<String, String> data) {

        log.info("合同列表, {}", data);
        McException.assertParamException_Null(data, "name, userId");

        List<Map> customers = new ArrayList<>();
        customers.addAll(_likeContractList(XBBConf.API_LIST_contract, "钉钉", data.get("name"), data.get("userId")));
        customers.addAll(_likeContractList(XBBConf.API_LIST_contract, "Teambition", data.get("name"), data.get("userId")));

        log.info("合同响应, {}", customers);
        return McR.success(customers);
    }

    /**
     * 自动填充合同编号/合同金额
     */
    @PostMapping("code/contract")
    McR contractCode(@RequestBody Map<String, String> data) {

        String[] content = data.get("code").split("/");
        log.info("自动填充, {}, {}", content);
        return McR.success(UtilMap.map("code, cash", content[0], content[1]));
    }

//    根据工单编号查看工单信息

private Long getWorkOrderInfo(@RequestParam String workOrderSerierNO) {
    JSONArray workOrderList = (JSONArray) xbbClient.getWorkOrderInfo(workOrderSerierNO).get("list");
    Map workOrderNo = (Map) workOrderList.get(0);
    Long dataId = Long.valueOf(workOrderNo.get("dataId").toString());
    return dataId ;
}





    /**
     *完成工单接口
     */
    @PostMapping("workOrde/finish")
    McR finishWorkOrder(@RequestBody Map<String, String> data) {
        try{
            log.info("完成工单, {}", data);
            McException.assertParamException_Null(data, "workOrderId");
            if(!data.get("projectType").equals("工时服务")){
                Long dataId = getWorkOrderInfo(data.get("workOrderId"));
                Map result = xbbClient.workOrderComplete(dataId);
                return McR.success(result);
            }else{
                return McR.success();
            }
        }catch(Exception e){
            return McR.errorParam(e.getMessage());
        }
    }

    @PostMapping("test")
    McR test() {

        ddClientContacts.getUserInfoById(ddClient.getAccessToken(), "16608972969409067");
        return McR.success();
    }

    /**
     * 测试token
     */
    private static final String TOKEN = "b88c3b27b11fa252500ce3041cc918fe";
    @RequestMapping(value = "/callback", method = RequestMethod.POST)
    public String test(HttpServletRequest httpServletRequest) {
        String response;
        try {
            // 获取请求体中的参数
            JSONObject params = getParams(httpServletRequest);
//            System.out.println(JSON.toJSONString(params));
            log.info("callback request= " + JSON.toJSONString(params));
            // 获取请求头中的sign
            String sign = httpServletRequest.getHeader("sign");
            if (checkSign(params, sign)) {
                log.info("callback check success!");
                if(params.getString("type").equals("customerCommunicate")
                && params.getString("operate").equals("new")){
                    Map map=xbbClient.getDataDetail(XBBConf.API_DETAIL_communicate,params.getLong("dataId"));
                    Map data = (Map) map.get("data");
                    System.out.println(JSONObject.toJSONString(map));
                    String creatorId=UtilMap.getString(UtilMap.getMap(data,"creatorId"),"id");
                    String content=String.valueOf(data.get("text_6"));
                    String merName=UtilMap.getString(UtilMap.getMap(data,data.containsKey("text_1")?"text_1":"text_5"),"name");
                    System.out.println(merName+":"+content);

                    Map<String,Object> paramsMap = new HashMap<>();
                    paramsMap.put("filter", UtilMap.map("combination, conditions","and", Arrays.asList(UtilMap.map("field, operator, value","客户全称","equal",Arrays.asList(merName)))));
                    List<Map> list=ddClientNotable.getRecords(ddClient.getAccessToken(),"bxgzX5wq4YoJPQG3jLvR8Ry2OB79ALPD","dulvlx8e4ru1wmna9lt8m","0LeoESGUiSKn272PRD8Qv3AiEiE",paramsMap);
                    for(Map detail:list){
                        String id=UtilMap.getString(detail,"id");
                        Map <String,Object> map1=new HashMap<>();
                        map1.put("id",id);
                        map1.put("fields",UtilMap.map("详情", content));
                        List<Map> updateRecords= Arrays.asList(map1);
                        ddClientNotable.updateRecords(ddClient.getAccessToken(),"bxgzX5wq4YoJPQG3jLvR8Ry2OB79ALPD","dulvlx8e4ru1wmna9lt8m","0LeoESGUiSKn272PRD8Qv3AiEiE",updateRecords);
                    }
                }

            }
            response = "request analysis success!";
        } catch (Exception e) {
            response = "request analysis error!";
        }
        return response;
    }

    /**
     * sign校验，如果需要对回调请求进行合法性校验，需要对传过来的sign做验证
     * @param params 有序的接收到的参数
     * @param orSign 请求传过来的sign
     * @return
     */
    private boolean checkSign(JSONObject params, String orSign) {
        // 将请求参数与token进行SHA256运算，得到校验签名sign
        String sign = DigestUtil.Encrypt(params.toJSONString() + TOKEN, "SHA-256");
        // 将请求过来的checkSign与生成的sign进行匹配，匹配成功则证明到达该接口的请求是由销帮帮发出的安全的请求
        if (Objects.equals(orSign, sign)) {
            return true;
        }
        return false;
    }

    /**
     * 获取参数
     * @param request
     * @return JSONObject 将请求参数有序接收后格式示例：{"corpid":"XXX","dataId":123456,"formId":714275,"operate":"EDIT","saasMark":1,"type":"CUSTOMER"}
     * @throws IOException
     */
    public static JSONObject getParams(HttpServletRequest request) throws IOException {
        ApiRequestWrapper requestWrapper = new ApiRequestWrapper(request);
        byte[] requestWrapperBody = requestWrapper.getBody();
        String requestWrapperString = new String(requestWrapperBody, StandardCharsets.UTF_8);
        LinkedHashMap params = JSON.parseObject(requestWrapperString, LinkedHashMap.class, Feature.OrderedField);
        JSONObject requestJsonObject = new JSONObject(true);
        requestJsonObject.putAll(params);
        return requestJsonObject;
    }
}


