package nccloud.api.uapbd.wms.utils;

import com.alibaba.fastjson.JSONObject;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.RuntimeEnv;
import nc.bs.logging.Log;
import nc.itf.arap.goldentax.SysParaInitQuery;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.uap.lfw.core.log.LfwLogger;
import nc.vo.am.common.util.StringUtils;
import nc.vo.pub.BusinessException;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
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 org.apache.tomcat.util.http.fileupload.IOUtils;
import uap.mw.trans.TransactionFactory;
import uap.mw.trans.UAPTransactionManagerProxy;
import uap.mw.trans.itf.IUAPTransactionManager;
import uap.mw.trans.util.TransactionContextType;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class WmsSyncUtils implements IWmsSyncUtils {

    public static final BaseDAO dao = new BaseDAO();
    private static final Log log = Log.getInstance("wmslog");

    public static Properties loadPropertie(String fileName) throws BusinessException {
        Properties nodeProps = null;
        InputStream input = null;
        InputStreamReader inputReader = null;
        try {
            String homepath = RuntimeEnv.getInstance().getNCHome() + File.separator;
            String filepath = "resources" + File.separator + fileName.replace(".", File.separator) + ".properties";
            File file = new File(homepath + filepath);
            if (!file.exists())
                throw new BusinessException(filepath + "文件不存在，请检查");
            input = new FileInputStream(homepath + filepath);
            nodeProps = new Properties();
            inputReader = new InputStreamReader(input, StandardCharsets.UTF_8);
            nodeProps.load(inputReader);
        } catch (IOException e) {
            LfwLogger.error(e.getMessage(), e);
        } finally {
            IOUtils.closeQuietly(inputReader);
            IOUtils.closeQuietly(input);
        }
        return nodeProps;
    }

    /**
     * 获取WMS配置信息
     *
     * @return WMS配置信息
     */
    private Map<String, String> getWmsConfig() throws BusinessException {
        Map<String, String> config = new HashMap<>();
        try {
            // 从配置文件读取WMS配置
            Properties props = loadPropertie("wms.FlusWmsConfig");
            if (props != null) {
                config.put("wmsIp", props.getProperty("wms.ip", "http://172.168.16.212:18080"));
                config.put("baseUrl", props.getProperty("wms.baseUrl", "/datahubjson/FluxWmsJsonApi/"));
                config.put("format", props.getProperty("wms.format", "json"));
                config.put("apptoken", props.getProperty("wms.apptoken", "97EE89DA3DC642C22EAD5C33597DC903"));
                config.put("sign", props.getProperty("wms.sign", "1"));
                config.put("baseUrlQc", props.getProperty("wms.baseUrlQc", "/datahubjson/TK_BIP/"));
            } else {
                throw new BusinessException("未找到wms.FlusWmsConfig.properties文件");
            }
        } catch (Exception e) {
            log.error("读取WMS配置文件失败：" + e.getMessage(), e);
            throw new BusinessException("读取WMS配置文件失败：" + e.getMessage());
        }
        return config;
    }

    @Override
    public String callWMS(String method, JSONObject json) throws BusinessException {
        String wmsUrl = buildUrl(method);
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json;charset=UTF-8");
        return doPost(wmsUrl, headers, json);
    }

    /**
     * 构造WMS请求URL
     *
     * @param method WMS方法名
     * @return 完整的请求URL
     */
    private String buildUrl(String method) throws BusinessException {
        Map<String, String> config = getWmsConfig();
        String wmsIp = config.get("wmsIp");
        String baseUrl = config.get("baseUrl");
        String format = config.get("format");
        String apptoken = config.get("apptoken");
        String sign = config.get("sign");
        String baseUrlQc = config.get("baseUrlQc");

        if (wmsIp == null || wmsIp.isEmpty()) {
            throw new RuntimeException("未配置WMS服务器地址");
        }

        // 报检单单独一个地址
        if ("TK_BIP_QC_ORDER".equals(method)) {
            return wmsIp + "/" + baseUrlQc + "?method=" + method;
        }

        // 生成时间戳
        String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());

        try {
            // 构造URL参数
            StringBuilder urlBuilder = new StringBuilder(wmsIp);
            if (!wmsIp.endsWith("/")) {
                urlBuilder.append("/");
            }
            urlBuilder.append(baseUrl.substring(1));
            urlBuilder.append("?method=").append(URLEncoder.encode(method, StandardCharsets.UTF_8));
            urlBuilder.append("&format=").append(URLEncoder.encode(format, StandardCharsets.UTF_8));
            urlBuilder.append("&apptoken=").append(URLEncoder.encode(apptoken, StandardCharsets.UTF_8));
            urlBuilder.append("&timestamp=").append(URLEncoder.encode(timestamp, StandardCharsets.UTF_8));
            urlBuilder.append("&sign=").append(URLEncoder.encode(sign, StandardCharsets.UTF_8));

            return urlBuilder.toString();
        } catch (Exception e) {
            throw new RuntimeException("构造WMS请求URL失败: " + e.getMessage(), e);
        }
    }

    @Override
    public void sendToExternalSystem(String method, Map<String, Object> requestData) throws BusinessException {
        try {
            log.debug("WMS请求方法：" + method + "，请求数据：" + JSONObject.toJSONString(requestData));
            JSONObject jsonRequest = new JSONObject(requestData);

            String response = callWMS(method, jsonRequest);
            JSONObject jsonResponse = JSONObject.parseObject(response);
            log.debug("WMS接口返回：" + jsonResponse.toJSONString());

            // 解析新的WMS响应格式
            parseWmsResponse(jsonResponse);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException("调用WMS接口失败：" + e.getMessage(), e);
        }
    }

    /**
     * 解析WMS响应
     *
     * @param jsonResponse WMS返回的JSON响应
     * @throws BusinessException 业务异常
     */
    private void parseWmsResponse(JSONObject jsonResponse) throws BusinessException {
        if (!jsonResponse.containsKey("Response")) {
            throw new BusinessException("WMS响应格式错误：缺少Response节点");
        }

        JSONObject response = jsonResponse.getJSONObject("Response");
        if (!response.containsKey("return")) {
            throw new BusinessException("WMS响应格式错误：缺少return节点");
        }

        JSONObject returnObj = response.getJSONObject("return");
        String returnFlag = returnObj.getString("returnFlag");
        String returnCode = returnObj.getString("returnCode");
        String returnDesc = returnObj.getString("returnDesc");

        // returnFlag: 1-成功, 2-失败
        if (!"1".equals(returnFlag)) {
            StringBuilder errorMsg = new StringBuilder("向WMS发起同步失败：");
            errorMsg.append("返回码：").append(returnCode);
            errorMsg.append("，描述：").append(returnDesc);

            // 检查是否有详细错误信息
            if (returnObj.containsKey("resultInfo")) {
                com.alibaba.fastjson.JSONArray resultInfo = returnObj.getJSONArray("resultInfo");
                if (resultInfo != null && !resultInfo.isEmpty()) {
                    errorMsg.append("，详细错误：");
                    for (int i = 0; i < resultInfo.size(); i++) {
                        JSONObject errorItem = resultInfo.getJSONObject(i);
                        errorMsg.append("[doc：").append(errorItem.getString("docNo"))
                                .append("，错误码：").append(errorItem.getString("errorcode"))
                                .append("，错误描述：").append(errorItem.getString("errordescr")).append("]");
                        if (i < resultInfo.size() - 1) {
                            errorMsg.append("；");
                        }
                    }
                }
            }

            throw new BusinessException(errorMsg.toString());
        }
    }

    /**
     * 检查当前用户是否需要跳过同步
     */
    @Override
    public boolean checkIfExcludeUser() {
        return false;
    }

    @Override
    public boolean checkIfIncludeOrg(String code) throws BusinessException {
        String targetCode = SysParaInitQuery.getParaString("GLOBLE00000000000000", "WMSORG");
        if (targetCode == null || StringUtils.isEmpty(targetCode)) {
            throw new BusinessException("未配置组织参数,请前往 [业务参数设置-全局] 配置WMSORG 参数");
        }
        String[] orgItem = targetCode.split(";");
        for (String orgCode : orgItem) {
            if (!orgCode.isEmpty() && orgCode.equals(code)) {
                log.debug("当前处理组织校验为WMS可同步:" + code);
                return true;
            }
        }
        return false;
    }


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

            // 设置标准请求头
            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) {
            throw new RuntimeException("HTTP POST 请求到 " + url + " 失败: " + e.getMessage(), e);
        }
    }

    /**
     * 根据主键查询编码
     */
    public String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException {
        if (pk == null || pk.trim().isEmpty()) {
            log.warn("未传入主键信息，无法查询编码：" + pkField + ":" + tableName + ":" + selectField);
            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();
    }

    /**
     * 根据主键查询字段值（允许为空）
     *
     * @param tableName   表名
     * @param selectField 查询字段
     * @param pkField     主键字段
     * @param pk          主键值
     * @return 查询结果，如果未查询到或字段值为空则返回null
     */
    public String transferFieldByPkAllowNull(String tableName, String selectField, String pkField, String pk) {
        if (pk == null || pk.trim().isEmpty()) {
            log.debug("未传入主键信息，无法查询字段值：" + pkField + ":" + tableName + ":" + selectField);
            return null;
        }
        try {
            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) {
                log.debug("未查询到字段值或字段值为空，sql【" + sqlBuilder + "】");
                return null;
            }
            String result = o.toString();
            // 如果字段值为空字符串，也返回null
            if (result.trim().isEmpty()) {
                log.debug("查询到的字段值为空字符串，表：" + tableName + "，字段：" + selectField + "，主键：" + pk);
                return null;
            }
            return result;
        } catch (Exception e) {
            log.warn("查询字段值失败：" + e.getMessage() + "，表：" + tableName + "，字段：" + selectField + "，主键：" + pk);
            return null;
        }
    }

    @Override
    public boolean isWMS() {
        String code = InvocationInfoProxy.getInstance().getUserCode();
        return code != null && code.equals("WMS");
    }

    public static void fillOutBillsInfo() {
        return;
    }
}
