package nccloud.pubift.commen.impl.utils;


import com.alibaba.fastjson.JSONObject;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.logging.Log;
import nc.hr.utils.PubEnv;
import nc.itf.arap.goldentax.SysParaInitQuery;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.vo.am.common.util.StringUtils;
import nc.vo.pub.BusinessException;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
import nccloud.pubift.commen.itf.utils.IHttpPostOtherSys;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


public class HttpPostOtherSysImpl implements IHttpPostOtherSys {

    private static final String USER_ID = "BIP";

    private static final String PASSWORD = "BIP@2025bip";

    private static final String CLIENT_TYPE = "S";

    private static final String EP_ID = "";

    private static final String LOGIN_URL = "/GTHINKING/AjaxService/N_MISPRO/100208057.ashx/Login"; // 登录接口路径

    private static final String LOG_INFO_NAME = "OALOG";

    private static final Log obmlog = Log.getInstance(LOG_INFO_NAME);

    private static final BaseDAO dao = new BaseDAO();
    @Override
    public String callMes(String url, JSONObject json) {
        String mesip = SysParaInitQuery.getParaString(PubEnv.getPk_group(), "MESIP");
//        String mesip = "http://192.168.29.32"; // MES系统IP地址，实际应从配置读取
        String baseurl = mesip + url; // 拼接完整的请求URL
        String tokenValue = this.getMESToken(mesip); // 获取MES系统的认证Token
        Map<String, String> headers = new HashMap<>();
        if (tokenValue != null) {
            headers.put("Cookie", ".ASPXAUTH=" + tokenValue); // 将Token放入请求头的Cookie中
        }
        return doPost(baseurl, headers, json); // 执行POST请求
    }

    /**
     * 发送数据到外部系统
     */
    public void sendToExternalSystem(String apiPath, Map<String, Object> requestData) throws BusinessException {
        try {
            obmlog.debug("HttpPostOtherSys 请求数据 :" + JSONObject.toJSONString(requestData)); // 记录请求数据
            JSONObject jsonRequest = new JSONObject(requestData); // 将Map转换为JSONObject
            if (checkIfExcludeUser()) {
                obmlog.debug("当前用户为测试用户被配置为不同步，跳过同步MES系统");
                return;
            }
            String response = callMes(apiPath, jsonRequest); // 调用MES接口
            JSONObject jsonResponse = JSONObject.parseObject(response); // 解析返回的JSON字符串
            obmlog.debug("三方接口返回:：" + jsonResponse.toJSONString()); // 记录三方接口返回的数据

            // 检查是否存在 "Data" 数组
            if (jsonResponse.containsKey("Data") && jsonResponse.get("Data") instanceof com.alibaba.fastjson.JSONArray) {
                com.alibaba.fastjson.JSONArray dataArray = jsonResponse.getJSONArray("Data");
                for (int i = 0; i < dataArray.size(); i++) {
                    JSONObject dataObject = dataArray.getJSONObject(i);
                    String successInData = dataObject.getString("Success");
                    if ("false".equalsIgnoreCase(successInData)) {
                        String errorMessage = dataObject.getString("ErrorMessage");
                        if (errorMessage == null || errorMessage.isEmpty()) {
                            errorMessage = dataObject.getString("Message"); // 尝试获取 Message 字段
                        }
                        if (errorMessage == null || errorMessage.isEmpty()) {
                            errorMessage = "外部系统未提供错误消息。";
                        }
                        throw new BusinessException("同步mes系统失败,错误消息：" + errorMessage);
                    }
                }
                // 如果Data数组中所有项都成功，则认为整体成功
                // 当前逻辑：如果Data数组存在且所有项成功，则不再检查顶层Success，直接认为成功。
            } else {
                // 原有的逻辑，处理顶层Success字段
                String success = jsonResponse.getString("Success"); // 获取返回结果中的Success字段
                if ("false".equalsIgnoreCase(success)) { // 判断请求是否成功
                    String errorMessage = jsonResponse.getString("ErrorMessage"); // 获取错误信息
                    if (errorMessage == null || errorMessage.isEmpty()) {
                        errorMessage = jsonResponse.getString("Message"); // 尝试获取 Message 字段
                    }
                    if (errorMessage == null || errorMessage.isEmpty()) {
                        errorMessage = "外部系统未提供错误消息。";
                    }
                    throw new BusinessException("同步mes系统失败,错误消息：" + errorMessage); // 抛出业务异常
                }
            }

        } catch (BusinessException e) {
            throw e; // 直接抛出已捕获的业务异常
        } catch (Exception e) {
            throw new BusinessException("调用外部接口失败：" + e.getMessage(), e); // 捕获其他异常并包装为业务异常抛出
        }
    }

    /**
     * 检查当前用户是否需要跳过同步
     */
    public boolean checkIfExcludeUser() {
        String code = InvocationInfoProxy.getInstance().getUserCode();
        //当当前操作人员是BIP的时候 直接return 不走同步MES的业务逻辑
        String excludeUsers = SysParaInitQuery.getParaString("GLOBLE00000000000000", "JINSIWEINOSYNCUESR");
        if (StringUtils.isNotEmpty(excludeUsers)) {
            String[] userItem = excludeUsers.split(";");
            for (String userCode : userItem) {
                if (userCode.isEmpty()) continue;
                if (code != null && code.equals(userCode)) {
                    obmlog.debug("AfterApprovingSynchronizeRuleMES-当前人员是测试人员，不处理,当前用户为:" + code);
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检查当前组织是否为电缆
     */
    public boolean checkIfIncludeOrg(String code) throws BusinessException {
        //当当前操作人员是BIP的时候 直接return 不走同步MES的业务逻辑
        String targetCode = SysParaInitQuery.getParaString("GLOBLE00000000000000", "INCLUDEORG");
        if (targetCode == null || StringUtils.isEmpty(targetCode)) {
            throw new BusinessException("未配置组织参数,请前往 [业务参数设置-全局] 配置INCLUDEORG参数");
        }
        String[] orgItem = targetCode.split(";");
        for (String orgCode : orgItem) {
            if (!orgCode.isEmpty() && orgCode.equals(code)) {
                obmlog.debug("当前处理组织校验为电缆:" + code);
                return true;
            }
        }
        return false;
    }

    /**
     * 业务请求post方法
     */
    private String doPost(String baseurl, Map<String, String> headers, JSONObject jsonPayload) {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) { // 创建HttpClient实例
            HttpPost httpPost = new HttpPost(baseurl); // 创建HttpPost请求

            // 设置标准请求头
            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");

            // 设置自定义请求头
            if (headers != null) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }

            if (jsonPayload != null) {
                StringEntity stringEntity = new StringEntity(jsonPayload.toJSONString(), "UTF-8"); // 创建请求体
                httpPost.setEntity(stringEntity); // 设置请求体
            }

            try (CloseableHttpResponse response = httpClient.execute(httpPost)) { // 执行请求
                HttpEntity entity = response.getEntity(); // 获取响应实体
                String responseString = EntityUtils.toString(entity, "UTF-8"); // 将响应实体转换为字符串
                return responseString;
            }
        } catch (IOException e) {
            // 在实际应用中，应使用合适的日志框架记录错误
            // e.printStackTrace(); 
            throw new RuntimeException("HTTP POST 请求到 " + baseurl + " 失败: " + e.getMessage(), e); // 抛出运行时异常
        }
    }

    // 提取 .ASPXAUTH 的值 - 此方法保持不变
    private String extractAspxAuth(String setCookieHeaderLine) {
        // setCookieHeaderLine 是一行完整的 Set-Cookie 响应头，例如:
        // ".ASPXAUTH=TOKEN_VALUE; path=/; HttpOnly"
        // 或 ".ASPXAUTH=TOKEN_VALUE;"
        String[] cookieAttributes = setCookieHeaderLine.split(";"); // 按分号分割属性
        for (String attribute : cookieAttributes) {
            String trimmedAttribute = attribute.trim(); // 去除前后空格
            if (trimmedAttribute.startsWith(".ASPXAUTH=")) { // 检查是否是 .ASPXAUTH
                return trimmedAttribute.substring(".ASPXAUTH=".length()); // 提取等号后的值
            }
        }
        return null; // 未找到 .ASPXAUTH
    }

    /**
     * 获取MES系统的认证Token (通常是从Cookie中获取 .ASPXAUTH)
     *
     * @param mesIpBase MES系统的基础IP地址
     * @return .ASPXAUTH 的Token值，如果未找到则返回null
     */
    private String getMESToken(String mesIpBase) {
        JSONObject jsonObject = new JSONObject(); // 构建登录请求的JSON对象
        jsonObject.put("userId", USER_ID);
        jsonObject.put("password", PASSWORD);
        jsonObject.put("clientType", CLIENT_TYPE);
        jsonObject.put("epId", EP_ID);

        String loginUrl = mesIpBase + LOGIN_URL; // 拼接完整的登录URL

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) { // 创建HttpClient实例
            HttpPost httpPost = new HttpPost(loginUrl); // 创建HttpPost请求用于登录
            httpPost.setHeader("Content-Type", "application/json;charset=UTF-8"); // 设置请求内容类型

            StringEntity stringEntity = new StringEntity(jsonObject.toJSONString(), "UTF-8"); // 创建登录请求体
            httpPost.setEntity(stringEntity); // 设置登录请求体

            try (CloseableHttpResponse response = httpClient.execute(httpPost)) { // 执行登录请求
                Header[] setCookieHeaders = response.getHeaders("Set-Cookie"); // 获取响应头中的Set-Cookie字段
                if (setCookieHeaders != null) {
                    for (Header header : setCookieHeaders) {
                        String aspxAuthValue = extractAspxAuth(header.getValue()); // 从Set-Cookie中提取.ASPXAUTH的值
                        if (aspxAuthValue != null) {
                            return aspxAuthValue; // 找到并返回 .ASPXAUTH token 值
                        }
                    }
                }

                return null; // 如果未找到 .ASPXAUTH cookie，则返回 null
            }
        } catch (IOException e) {
            // 记录IO异常，例如网络问题或服务器不可达
            throw new RuntimeException("从 " + loginUrl + " 获取MESToken (cookie) 失败，发生IO问题: " + e.getMessage(), e);
        }
    }

    /**
     * 根据主键查询编码
     */
    public String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException {
        if (pk == null || pk.trim().isEmpty()) {
            return null;
        }
        SqlBuilder sqlBuilder = new SqlBuilder();
        sqlBuilder.append(" select " + selectField);
        sqlBuilder.append(" from " + tableName);
        sqlBuilder.append(" where ");
        sqlBuilder.append(pkField, pk);
        Object o = dao.executeQuery(sqlBuilder.toString(), new ColumnProcessor());
        if (o == null) {
            throw new BusinessException("未查询到编码信息，sql【" + sqlBuilder + "】");
        }
        return o.toString();
    }

}
