package com.malk.cloudpure.controller;

import com.alibaba.fastjson.JSON;
import com.malk.server.common.McException;
import com.malk.server.common.McR;
import com.malk.server.dingtalk.DDConf;
import com.malk.service.dingtalk.DDClient;
import com.malk.service.h3yun.CYClient;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 氚云数据接口
 *
 * 功能说明：
 * 1. 查询客户是否存在：传入客户名称，查询氚云客户表
 * 2. 提交待审批数据：传入氚云字段键值对，在氚云发起提交
 * 3. 查询客户最新机会：传入客户编码，查询氚云客户机会表最新一条
 * 4. 查询客户最新合同：传入客户编码，查询氚云合同表最新一条
 *
 * 错误抛出与拦截详见 CatchException
 */
@Slf4j
@RestController
@RequestMapping("h3yun")
public class H3yunController {

    @Autowired
    private CYClient cyClient;

    @Autowired
    private DDClient ddClient;

    @Autowired
    private DDConf ddConf;

    // ===================== 氚云表单编码常量 =====================
    // TODO: 请替换为实际的氚云表单编码(SchemaCode)

    /** 客户表SchemaCode */
    private static final String SCHEMA_CUSTOMER = "D00086786d02a447942405d9e27821538a57834";

    /** 客户机会表SchemaCode */
    private static final String SCHEMA_CUSTOMER_OPPORTUNITY = "D000867wjisvgvjybui6620yj2a8ad53";

    /** 合同表SchemaCode */
    private static final String SCHEMA_CONTRACT = "D000867fhlpdb6a82f59spkf1vzac5p1";



    // ===================== 氚云用户表 =====================
    /** 氚云用户系统表SchemaCode，用于通过钉钉userId查询氚云userId */
    private static final String SCHEMA_H_USER = "D000867sme291ffe61b834a8ea7456f8b9a0ccc29";

    // ===================== 客户表字段编码 =====================
    // TODO: 请替换为实际的字段编码

    /** 客户名称 */
    private static final String FIELD_CUSTOMER_NAME = "F0000001";

    /** 客户创建人氚云ID -默认夕瑶*/
    // private static final String opUserId = "37a89511-6a83-4ee5-aa06-b6a6744a9bb0";

    // ===================== 客户机会表字段编码 =====================

    /** 机会编号 */
    private static final String FIELD_OPP_CODE = "SeqNo";

     /* 意向产品 */
    private static final String Desired_Product = "D000867F4941a772370545088cef9366ee01aaca";

    /** 成单信心 */
    private static final String Order_Placement_Confidence = "F0000028";

    /** 预计成交日期 */
    private static final String Estimated_Closing_Date = "F0000007";
    /** 预估GMV */
    private static final String Estimated_GMV = "F0000031";
    /** 预估CASH */
    private static final String Estimated_CASH = "F0000035";
    /** 商机阶段 */
    private static final String Opportunity_Stage = "F0000019";
    /** 流失原因 */
    private static final String Reasons_Loss = "F0000042";


    /** 新建机会表-客户编码（关联字段）-查询机会用 */
    private static final String FIELD_OPP_CUSTOMER_CODE = "F0000041";

    // ===================== 合同表字段编码 =====================

    /** 合同编号 */
    private static final String FIELD_CONTRACT_CODE = "SeqNo";
    /** 实际成交GMV-合同总金额 */
    private static final String FIELD_CONTRACT_ACTUAL_GMV = "F0000062";
    /** 计收CASH *///先不加
//    private static final String FIELD_CONTRACT_CASH = "F0000003";
    /** 回款金额 */
    private static final String Payment_Collection_Time = "F0000099";

    /** 客户编码（关联字段）-查询合同用 */
    private static final String FIELD_CONTRACT_CUSTOMER_CODE = "F0000098";

    // ===================== 系统字段 =====================

    /** 创建时间（氚云系统字段） */
    private static final String FIELD_CREATED_TIME = "CreatedTime";

    /**
     * 需求1: 查询客户是否存在
     * 传入客户名称，在氚云客户表中查询该客户是否存在
     * 存在返回"是"，不存在返回"否"
     *
     * @param data 请求参数，包含 customerName 客户名称
     * @return "是" 或 "否"
     */
    @PostMapping("customer/check")
    McR checkCustomerExists(@RequestBody Map<String, String> data) {

        log.info("查询客户是否存在, {}", data);
        McException.assertParamException_Null(data, "customerName");

        String customerName = data.get("customerName");
        String accessToken = ddClient.getAccessToken();

        // 构建查询条件：客户名称 = 传入值
        Map matcher = UtilMap.map("Type, Name, Operator, Value", "Item", FIELD_CUSTOMER_NAME, 2, customerName);
        Map extInfo = UtilMap.map("matcherJson", JSON.toJSONString(matcher));
        extInfo.put("pageSize", 10);
        extInfo.put("pageNumber", 1);

        List<Map> result = cyClient.queryData(accessToken, SCHEMA_CUSTOMER, extInfo);

        boolean exists = result != null && !result.isEmpty();
        log.info("客户查询结果, customerName: {}, exists: {}", customerName, exists);

        return McR.success(exists ? "是" : "否");
    }

    /**
     * 需求2: 提交待审批数据
     * 传入氚云字段键值对，在氚云发起一条提交待审批数据
     *
     * 流程说明：
     * 1. 直接将传入的JSON作为氚云表单数据
     * 2. 创建草稿数据
     * 3. 提交数据（发起审批流程）
     *
     * @param data 氚云字段键值对，如 {"F0000014":"KH-00001","F0000001":"测试客户","F0000015":"转单中"}
     * @return 提交结果，包含bizObjectId
     */
    @PostMapping("data/submit")
    McR submitData(@RequestBody Map<String, Object> data) {

        log.info("提交待审批数据到氚云, {}", data);

        String accessToken = ddClient.getAccessToken();
        String opUserId ="";
        if (data.get("CRNAME").toString()!=""){
              opUserId =  _getCYUserIdByDingTalkUserId(data.get("CRNAME").toString());
        }


        // 第一步：创建草稿数据（传入的JSON直接作为氚云表单数据）
        Map extInfo = UtilMap.map("opUserId, bizObjectJson, isDraft", opUserId, JSON.toJSONString(data), true);
        Map rsp = cyClient.operateData(accessToken, SCHEMA_CUSTOMER, extInfo);

        // 第二步：提交数据（发起审批流程）
        String bizObjectId = String.valueOf(rsp.get("bizObjectId"));
        cyClient.operateData(accessToken, SCHEMA_CUSTOMER, UtilMap.map("bizObjectId, opUserId", bizObjectId, opUserId));

        log.info("提交待审批数据成功, schemaCode: {}, bizObjectId: {}", SCHEMA_CUSTOMER, bizObjectId);
        return McR.success(UtilMap.map("bizObjectId", bizObjectId));
    }

    /**
     * 通过钉钉userId查询对应的氚云userId
     * 氚云H_User系统表中，F0000003为DingTalkAccount字段，F0000002为氚云用户ID字段
     */
    private String _getCYUserIdByDingTalkUserId(String dingTalkUserId) {
        Map extInfo = UtilMap.map("matcherJson", JSON.toJSONString(UtilMap.map("Type, Name, Operator, Value", "Item", "dingid", 2, dingTalkUserId)));
        List<Map> userList = cyClient.queryData(ddClient.getAccessToken(), SCHEMA_H_USER, extInfo);
        if (userList != null && !userList.isEmpty()) {
            return String.valueOf(userList.get(0).get("h3yunid"));
        }
        log.warn("未找到钉钉用户对应的氚云用户, dingTalkUserId: {}", dingTalkUserId);
        return dingTalkUserId;
    }

    /**
     * 需求3: 查询客户最新机会
     * 传入客户编码，查询氚云客户机会表中该客户的数据
     * 取创建时间最新的一条，返回：机会编号、回款日期、回款金额
     *
     * @param data 请求参数，包含 customerCode 客户编码
     * @return 最新一条机会数据，若无数据返回null
     */
    @PostMapping("opportunity/latest")
    McR queryLatestOpportunity(@RequestBody Map<String, String> data) {

        log.info("查询客户最新机会, {}", data);
        McException.assertParamException_Null(data, "customerCode");

        String customerCode = data.get("customerCode");
        String accessToken = ddClient.getAccessToken();

        // 构建查询条件：客户编码匹配
        Map matcher = UtilMap.map("Type, Name, Operator, Value", "Item", FIELD_OPP_CUSTOMER_CODE, 2, customerCode);
        Map extInfo = UtilMap.map("matcherJson", JSON.toJSONString(matcher));
        extInfo.put("pageSize", 100);
        extInfo.put("pageNumber", 1);

        // 按创建时间降序排序，获取最新一条
        List<Map> sortByFields = new ArrayList<>();
        sortByFields.add(UtilMap.map("fieldName, direction", FIELD_CREATED_TIME, "Descending"));
        extInfo.put("sortByFields", sortByFields);

        // 只返回需要的字段
        extInfo.put("returnFields", Arrays.asList(FIELD_OPP_CODE, Desired_Product, Order_Placement_Confidence,Estimated_Closing_Date,Estimated_GMV,Estimated_CASH, Opportunity_Stage,Reasons_Loss,FIELD_CREATED_TIME));

        List<Map> result = cyClient.queryData(accessToken, SCHEMA_CUSTOMER_OPPORTUNITY, extInfo);

        if (result == null || result.isEmpty()) {
            log.info("未查询到客户机会, customerCode: {}", customerCode);
            return McR.success(null);
        }

        // 取创建时间最新的一条
        Map latest = result.get(0);
        Map<String, Object> response = new HashMap<>();
        response.put("opportunityCode", UtilMap.getString(latest, FIELD_OPP_CODE));
        List<Map> desiredProductRows = (List<Map>) latest.get("D000867F4941a772370545088cef9366ee01aaca");
        String desiredProductStr = "";
        if (desiredProductRows != null && !desiredProductRows.isEmpty()) {
            List<String> values = new ArrayList<>();
            for (Map row : desiredProductRows) {
                String val = String.valueOf(row.get("F0000043"));
                if (val != null && !"null".equals(val) && !val.isEmpty()) {
                    values.add(val);
                }
            }
            desiredProductStr = String.join("；", values);
        }
        response.put("Desired_Product", desiredProductStr);//意向产品明细表  -名称用；隔开
        response.put("Order_Placement_Confidence", UtilMap.getString(latest, Order_Placement_Confidence));
        response.put("Estimated_Closing_Date", UtilMap.getString(latest, Estimated_Closing_Date));
        response.put("Estimated_GMV", UtilMap.getString(latest, Estimated_GMV));
        response.put("Estimated_CASH", UtilMap.getString(latest, Estimated_CASH));
        response.put("Opportunity_Stage", UtilMap.getString(latest, Opportunity_Stage));
        response.put("Reasons_Loss", UtilMap.getString(latest, Reasons_Loss));
        response.put("FIELD_CREATED_TIME", UtilMap.getString(latest, FIELD_CREATED_TIME));
        log.info("查询客户最新机会结果, customerCode: {}, result: {}", customerCode, response);
        return McR.success(response);
    }

    /**
     * 需求4: 查询客户最新合同
     * 传入客户编码，查询氚云合同表中该客户的数据
     * 取创建时间最新的一条，返回：合同编号、实际成交GMV、计收CASH、回款金额
     *
     * @param data 请求参数，包含 customerCode 客户编码
     * @return 最新一条合同数据，若无数据返回null
     */
    @PostMapping("contract/latest")
    McR queryLatestContract(@RequestBody Map<String, String> data) {

        log.info("查询客户最新合同, {}", data);
        McException.assertParamException_Null(data, "customerCode");

        String customerCode = data.get("customerCode");
        String accessToken = ddClient.getAccessToken();

        // 构建查询条件：客户编码匹配
        Map matcher = UtilMap.map("Type, Name, Operator, Value", "Item", FIELD_CONTRACT_CUSTOMER_CODE, 2, customerCode);
        Map extInfo = UtilMap.map("matcherJson", JSON.toJSONString(matcher));
        extInfo.put("pageSize", 100);
        extInfo.put("pageNumber", 1);

        // 按创建时间降序排序，获取最新一条
        List<Map> sortByFields = new ArrayList<>();
        sortByFields.add(UtilMap.map("fieldName, direction", FIELD_CREATED_TIME, "Descending"));
        extInfo.put("sortByFields", sortByFields);

        // 只返回需要的字段
        extInfo.put("returnFields", Arrays.asList(FIELD_CONTRACT_CODE, FIELD_CONTRACT_ACTUAL_GMV, Payment_Collection_Time, FIELD_CREATED_TIME));

        List<Map> result = cyClient.queryData(accessToken, SCHEMA_CONTRACT, extInfo);

        if (result == null || result.isEmpty()) {
            log.info("未查询到合同, customerCode: {}", customerCode);
            return McR.success(null);
        }

        // 取创建时间最新的一条
        Map latest = result.get(0);
        Map<String, Object> response = new HashMap<>();
        response.put("contractCode", UtilMap.getString(latest, FIELD_CONTRACT_CODE));
        response.put("actualGMV", latest.get(FIELD_CONTRACT_ACTUAL_GMV));
     //   response.put("cash", latest.get(FIELD_CONTRACT_CASH));
        response.put("Payment_Collection_Time", latest.get(Payment_Collection_Time));

        log.info("查询客户最新合同结果, customerCode: {}, result: {}", customerCode, response);
        return McR.success(response);
    }
}
