package com.malk.huagao.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.malk.huagao.entity.KdYdCustomer;
import com.malk.huagao.entity.KdYdCustomerLiaison;
import com.malk.huagao.entity.KdYdDeliveryDetail;
import com.malk.huagao.mapper.KdYdCustomerLiaisonMapper;
import com.malk.huagao.mapper.KdYdCustomerMapper;
import com.malk.huagao.service.IKdYdCustomerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.common.McException;
import com.malk.server.dingtalk.DDR_New;
import com.malk.service.aliwork.YDClient;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author LQY
 * @since 2025-10-09
 */
@Service
@Slf4j
public class KdYdCustomerServiceImpl extends ServiceImpl<KdYdCustomerMapper, KdYdCustomer> implements IKdYdCustomerService {
    @Autowired
    private YDClient ydClient;
    @Autowired
    private KdYdCustomerMapper kdYdCustomerMapper;
    @Autowired
    private KdYdCustomerLiaisonMapper kdYdCustomerLiaisonMapper;

    @Value(value = "${kd.host}")
    private String kdHost;

    @Override
    public Map<String, Object> insertCustomer(Map map) {
        Map<String, Object> result = new HashMap<>();

        try {
            MDC.put("MDC_KEY_PID", "1003");
            String formInstId = UtilMap.getString(map, "formInstId");
            String action = UtilMap.getString(map, "type");

            // 处理特殊操作类型
            if ("del".equals(action)) {
                String bm = UtilMap.getString(map, "bm");
                Map<String, String> headers = new HashMap<>();
                headers.put("Content-Type", "application/x-www-form-urlencoded");
                Map<String, Object> formParams = new HashMap<>();
                Map<String, Object> djbh = new HashMap<>();
                djbh.put("djbh", bm);
                result.put("data", djbh);
                String jsonStr = JSON.toJSONString(result);

                formParams.put("jsons", jsonStr);

                System.out.println("====" + formParams);
                HttpResponse response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbdeletecust")
                        .headerMap(headers, true)
                        .form(formParams)
                        .timeout(90000)  // 30秒超时
                        .execute();

                String responseBody = response.body();
                // 返回删除操作的格式
                result.put("table", "KD_YD_CUSTOMER");
                result.put("action", "del");
                result.put("data", new HashMap<String, Object>() {{
                    put("bm", bm);  // 删除的主键或标识
                    put("msg", "删除成功");
                }});
                return result;
            }

            // === 获取表单数据 ===
            DDR_New ddrNew = retryQueryData(
                    YDParam.builder().formInstId(formInstId).build(),
                    YDConf.FORM_QUERY.retrieve_id
            );
            Map formData = ddrNew.getFormData();

            // === 提取主表字段 ===
            String khmc = UtilMap.getString(formData, "textField_lqanqe6j");
//            String khmc = "26228测试客户11";
            String khbm = UtilMap.getString(formData, "textField_meqhqqvg");
            String xssx = UtilMap.getString(formData, "selectField_megi74y7");
            String khxypj = UtilMap.getString(formData, "selectField_mewirdx4");
            String khsx = UtilMap.getString(formData, "selectField_megi74y8");
            String jxr = cleanEmployeeField(UtilMap.getString(formData, "employeeField_megi74yl"));
            String khlb = UtilMap.getString(formData, "selectField_lqanqe6l");
            String khfz = UtilMap.getString(formData, "selectField_lqanqe6q");
            String fptt = UtilMap.getString(formData, "textField_llujklkr");
            String nsdjh = UtilMap.getString(formData, "textField_meqhqqvm");
//            String nsdjh = "121212";
            String khyh = UtilMap.getString(formData, "textField_meqhqqvn");
            String yhzh = UtilMap.getString(formData, "textField_meqhqqvs");
            String jxslx = UtilMap.getString(formData, "selectField_mis6kl56");
            String kplx = UtilMap.getString(formData, "selectField_lwopqbye");
            String kplxdh = UtilMap.getString(formData, "textField_llujklkp");
            String kptxdz = UtilMap.getString(formData, "textField_llujklkv");
            String tyshxydm = UtilMap.getString(formData, "textField_mfxrrysq");
            String spdzyx = UtilMap.getString(formData, "textField_mg0fq6l4");
            String khtjr = UtilMap.getString(formData, "textField_mfdrrg87");
            String sktj = UtilMap.getString(formData, "selectField_meqhqqvh");
            String xsy = cleanEmployeeField(UtilMap.getString(formData, "employeeField_lqanqe6n"));
            String jsbb = UtilMap.getString(formData, "selectField_mfxrryt0");
            String khyxj = UtilMap.getString(formData, "numberField_mfxs7rd3");
            if (khyxj == null || khyxj.trim().isEmpty()) {
                khyxj = "1";
            }
            String qyxygl = UtilMap.getString(formData, "radioField_mfxs7rd2");
            String mrsl = UtilMap.getString(formData, "selectField_mfxrryt3");
            String sfl = UtilMap.getString(formData, "selectField_mfxrryt2");
            String sfjtkh = UtilMap.getString(formData, "radioField_mhe8e937");
            String dyjtkh = UtilMap.getString(formData, "textField_mis6kl57");

            // 构建主表数据
            Map<String, Object> customData = new HashMap<>();
            customData.put("khmc", khmc);
            if("edit".equals(action)){
                customData.put("khbm", khbm);
            }
            customData.put("xssx", xssx);
            customData.put("khxypj", khxypj);
            customData.put("khsx", khsx);
            customData.put("jxr", jxr);
            customData.put("khlb", khlb);
            customData.put("khfz", khfz);
            customData.put("fptt", fptt);
            customData.put("nsdjh", nsdjh);
            customData.put("khyh", khyh);
            customData.put("yhzh", yhzh);
            customData.put("khlx", jxslx);
            customData.put("kplx", kplx);
            customData.put("kplxdh", kplxdh);
            customData.put("kptxdz", kptxdz);
            customData.put("tyshxydm", tyshxydm);
            customData.put("spdzyx", spdzyx);
            customData.put("khtjr", khtjr);
            customData.put("sktj", sktj);
            customData.put("xsy", xsy);
            customData.put("jsbb", jsbb);
            customData.put("khyxj", khyxj);
            customData.put("qyxygl", qyxygl);
            customData.put("mrsl", mrsl);
            customData.put("sfl", sfl);
            customData.put("sfjtkh", sfjtkh);
            customData.put("dyjtkh", dyjtkh);
            System.out.println("====="+customData);
            // 处理子表数据
            List<Map<String, Object>> contactList = new ArrayList<>();
            List<Map> tableField = (List<Map>) formData.get("tableField_mfkks8ww");

            if (tableField != null && !tableField.isEmpty()) {
                // 用于收集回写用的子表行
                List<Map> updatedTableRowsForYD = new ArrayList<>();

                for (Map item : tableField) {
                    Map<String, Object> contactData = new HashMap<>();
                    String xm = safeGetString(item, "textField_l3s6ubhq");
                    String yddh = safeGetString(item, "textField_lqbzc3gq");
                    String zw = safeGetString(item, "textField_l3s6ubht");
                    String gddh = safeGetString(item, "textField_mfxu5dnk");
                    String bm = safeGetString(item, "textField_mfkp33s5");
                    String yx = safeGetString(item, "textField_lqbzc3gr");

                    // 添加到联系人列表
                    contactData.put("xm", xm);
                    contactData.put("yddh", yddh);
                    contactData.put("zw", zw);
                    contactData.put("gddh", gddh);
                    contactData.put("bm", bm);
                    contactData.put("yx", yx);
                    contactList.add(contactData);

                }

                // 将联系人列表添加到主数据
                customData.put("contactList", contactList);
                Map<String, String> headers = new HashMap<>();
                headers.put("Content-Type", "application/x-www-form-urlencoded");

                result.put("data", customData);
// 将result转换为JSON字符串
                String jsonStr = JSON.toJSONString(result);
// 构建form参数
                Map<String, Object> formParams = new HashMap<>();
                formParams.put("jsons", jsonStr);
                log.info("客户请求参数：" + formParams);
// 发送请求
                HttpResponse response = null;
                if ("add".equals(action)) {
                    response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbcreatecust")
                            .headerMap(headers, true)
                            .form(formParams)
                            .timeout(90000)  // 60秒超时
                            .execute();
                } else {
                    response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbupdatecust")
                            .headerMap(headers, true)
                            .form(formParams)
                            .timeout(90000)  // 30秒超时
                            .execute();
                }

                String responseBody = response.body();
                try {
                    // 一行代码提取
                    String khbh = JSON.parseArray(responseBody)
                            .getJSONObject(0)
                            .getJSONObject("data")
                            .getString("djbh");
                    String msg = JSON.parseArray(responseBody)
                            .getJSONObject(0)
                            .getString("msg");
                    String code = JSON.parseArray(responseBody)
                            .getJSONObject(0)
                            .getString("code");
                    retryOperateData(
                            YDParam.builder()
                                    .formInstanceId(formInstId)
                                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_ml08nk3y, textareaField_mkxqgrvq, textField_meqhqqvg", code, msg, khbh)))
                                    .useLatestVersion(true).build(),
                            YDConf.FORM_OPERATION.update);
//
                    log.info("回写数据到宜搭成功，formInstId: {}，responseBody:{}", formInstId, responseBody);
                } catch (Exception e) {
                    log.warn("回写数据到宜搭失败，formInstId: {}, 错误: {}", formInstId, e.getMessage());
                }
            }

            // 构建返回结果
            result.put("data", customData);

            log.info("客户信息同步成功: formInstId={}, khmc={}", formInstId, khmc);

        } catch (Exception e) {
            log.error("客户信息同步异常", e);
            result.put("table", "KD_YD_CUSTOMER");
            result.put("action", "error");
            result.put("data", new HashMap<String, Object>() {{
                put("errorMsg", "操作失败：" + e.getMessage());
            }});
        }

        return result;
    }

    // 清理员工字段格式
    private String cleanEmployeeField(String employeeField) {
        if (employeeField == null) return "";
        return employeeField.replace("[\"", "").replace("\"]", "").trim();
    }

    // === 工具方法（保持不变）===
    private String safeGetString(Map formData, String key) {
        Object val = formData.get(key);
        return val == null ? "" : String.valueOf(val);
    }

    /**
     * 从编码如 CXR04454 生成 CXR04455
     */
    private String incrementCode(String code) {
        if (code == null || code.isEmpty()) {
            return "CXR00001";
        }
        Pattern pattern = Pattern.compile("^(\\D*)(\\d+)$");
        Matcher matcher = pattern.matcher(code.trim());
        if (matcher.matches()) {
            String prefix = matcher.group(1);
            String numberPart = matcher.group(2);
            long number = Long.parseLong(numberPart);
            String newNumber = String.format("%0" + numberPart.length() + "d", number + 1);
            return prefix + newNumber;
        } else {
            return "CXR00001";
        }
    }

    //自带重试的operateData方法
    private Object retryOperateData(YDParam param, YDConf.FORM_OPERATION formOperation) {
        int maxAttempts = 3; // 尝试的最大次数
        int attempt = 0;
        long baseWaitTime = 3000; // 基础等待时间3秒

        while (attempt < maxAttempts) {
            try {
                Object result = ydClient.operateData(param, formOperation);
                // 成功调用后，如果有之前失败的重试日志，记录成功
                if (attempt > 0) {
                    log.info("第{}次重试成功", attempt + 1);
                }
                return result;
            } catch (McException e) {
                String errorMsg = e.getMessage();
                log.warn("第{}次调用失败，错误信息：{}", attempt + 1, errorMsg);

                // 判断是否是可重试的异常
                if (isRetryableError(errorMsg)) {
                    attempt++;
                    // 如果已达到最大尝试次数，不再重试，直接抛出异常
                    if (attempt >= maxAttempts) {
                        log.error("已达最大重试次数{}次，放弃重试", maxAttempts);
                        throw new RuntimeException("超出最大重试次数, param:" + JSONObject.toJSONString(param) + ", FORM_OPERATION:" + formOperation, e);
                    }

                    // 线程睡眠，使用指数退避策略
                    try {
                        long waitTime = baseWaitTime * (long) Math.pow(2, attempt - 1);
                        log.info("等待{}ms后重试第{}次, param:{}, FORM_OPERATION:{}",
                                waitTime, attempt + 1, JSONObject.toJSONString(param), formOperation);
                        Thread.sleep(waitTime);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt(); // 重新设置中断状态
                        log.error("重试睡眠被中断", ie);
                        throw new RuntimeException("重试过程被中断", ie);
                    }
                } else {
                    // 不可重试的异常，直接抛出
                    log.error("发生不可重试的异常，直接失败: {}", errorMsg);
                    throw new RuntimeException("宜搭操作失败: " + errorMsg, e);
                }
            } catch (Exception e) {
                // 非McException异常，直接抛出，不重试
                log.error("操作失败,param:{},FORM_OPERATION:{},异常信息:{}",
                        JSONObject.toJSONString(param), formOperation, e.getMessage());
                throw new RuntimeException(e);
            }
        }

        // 理论上不会执行到这里，但为了安全保留
        throw new RuntimeException("超出最大重试次数, param:" + JSONObject.toJSONString(param) + ", FORM_OPERATION:" + formOperation);
    }

    //自带重试的queryData方法
    private DDR_New retryQueryData(YDParam param, YDConf.FORM_QUERY formQuery) {
        int maxAttempts = 3; // 尝试的最大次数
        int attempt = 0;
        long baseWaitTime = 3000; // 基础等待时间3秒

        while (attempt < maxAttempts) {
            try {
                DDR_New result = ydClient.queryData(param, formQuery);
                // 成功调用后，如果有之前失败的重试日志，记录成功
                if (attempt > 0) {
                    log.info("第{}次重试查询成功", attempt + 1);
                }
                return result;
            } catch (McException e) {
                String errorMsg = e.getMessage();
                log.warn("第{}次查询失败，错误信息：{}", attempt + 1, errorMsg);

                // 判断是否是可重试的异常
                if (isRetryableError(errorMsg)) {
                    attempt++;
                    // 如果已达到最大尝试次数，不再重试，直接抛出异常
                    if (attempt >= maxAttempts) {
                        log.error("已达最大重试次数{}次，放弃重试查询", maxAttempts);
                        throw new RuntimeException("超出最大重试次数, param:" + JSONObject.toJSONString(param) + ", FORM_QUERY:" + formQuery, e);
                    }

                    // 线程睡眠，使用指数退避策略
                    try {
                        long waitTime = baseWaitTime * (long) Math.pow(2, attempt - 1);
                        log.info("等待{}ms后重试第{}次查询, param:{}, FORM_QUERY:{}",
                                waitTime, attempt + 1, JSONObject.toJSONString(param), formQuery);
                        Thread.sleep(waitTime);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt(); // 重新设置中断状态
                        log.error("重试查询睡眠被中断", ie);
                        throw new RuntimeException("重试查询过程被中断", ie);
                    }
                } else {
                    // 不可重试的异常，直接抛出
                    log.error("发生不可重试的异常，查询直接失败: {}", errorMsg);
                    throw new RuntimeException("宜搭查询失败: " + errorMsg, e);
                }
            } catch (Exception e) {
                // 非McException异常，直接抛出，不重试
                log.error("查询操作失败,param:{},FORM_QUERY:{},异常信息:{}",
                        JSONObject.toJSONString(param), formQuery, e.getMessage());
                throw new RuntimeException(e);
            }
        }

        // 理论上不会执行到这里，但为了安全保留
        throw new RuntimeException("超出最大重试次数, param:" + JSONObject.toJSONString(param) + ", FORM_QUERY:" + formQuery);
    }
    /**
     * 判断是否是可重试的错误
     */
    private boolean isRetryableError(String errorMsg) {
        if (errorMsg == null) return false;

        // 可重试的错误关键字列表（扩展了匹配范围）
        String[] retryableKeywords = {
                "temporary failure",
                "未知异常",
                "timeout",
                "Timeout",
                "Connection refused",
                "Internal Server",
                "服务不可用",
                "Service Unavailable",
                "Gateway Timeout",
                "Bad Gateway"
        };

        for (String keyword : retryableKeywords) {
            if (errorMsg.contains(keyword)) {
                return true;
            }
        }
        return false;
    }

}
