package com.ruoyi.oa.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.oa.domain.vo.OaExpressVo;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Date;
import java.util.UUID;
import org.apache.commons.codec.binary.Base64;

/**
 * 顺心捷达路由地址查询工具
 */
public class SxjdRouteQueryUtil {
    
    // 顺心捷达开放平台配置
    private static final String APP_KEY = "d2f3f98ebff25410e1280ed89c01be75";
    private static final String APP_CODE = "000466";
    private static final String APP_SECRET = "902379cccfa1981f23bfb1833264de87";
    private static final String SX_CUSTOMER_CODE = "C20001611";
    
    // 顺心捷达API地址 - 根据环境选择
    // 测试环境: https://oms.sit.sf-express.com:9010/api/gateway/service
    // 生产环境: https://oms.sxjdfreight.com/api/gateway/service
    // 沙箱环境: https://oms.sxjdfreight.com/api/gateway/sandbox
    private static final String API_URL = "https://oms.sit.sf-express.com:9010/api/gateway/service";

    /**
     * 查询顺心捷达轨迹
     * @param waybillId 运单号
     * @return 查询结果JSON
     */
    public static String queryRoute(String waybillId) {
        return queryRoute(waybillId, null, null);
    }
    
    /**
     * 查询顺心捷达轨迹（支持子单号查询）
     * @param waybillId 运单号
     * @param queryType 查询方式 1=查询母单轨迹 2=按子单号查询子单轨迹
     * @param subWaybillId 子运单号
     * @return 查询结果JSON
     */
    public static String queryRoute(String waybillId, Integer queryType, String subWaybillId) {
        try {
            // 1. 构造请求数据
            JSONObject data = new JSONObject();
            data.put("waybillId", waybillId);
            if (queryType != null) {
                data.put("queryType", queryType);
            }
            if (StringUtils.isNotBlank(subWaybillId)) {
                data.put("subWaybillId", subWaybillId);
            }
            
            String dataStr = data.toJSONString();
            String timestamp = String.valueOf(System.currentTimeMillis());
            String messageId = UUID.randomUUID().toString();
            
            // 2. 生成签名
            String dataDigest = generateDataDigest(dataStr, timestamp);
            
            // 3. 构造表单参数
            StringBuilder formParams = new StringBuilder();
            formParams.append("apiType=SX_QUERY_TRACK");
            formParams.append("&appKey=").append(URLEncoder.encode(APP_KEY, "UTF-8"));
            formParams.append("&sxCustomerCode=").append(URLEncoder.encode(SX_CUSTOMER_CODE, "UTF-8"));
            formParams.append("&timestamp=").append(URLEncoder.encode(timestamp, "UTF-8"));
            formParams.append("&dataDigest=").append(URLEncoder.encode(dataDigest, "UTF-8"));
            formParams.append("&messageId=").append(URLEncoder.encode(messageId, "UTF-8"));
            formParams.append("&data=").append(URLEncoder.encode(dataStr, "UTF-8"));
            
            String formBody = formParams.toString();
            System.out.println("顺心捷达请求参数：" + formBody);
            
            // 4. 发送POST请求
            return doPost(API_URL, formBody);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * 解析顺心捷达返回数据，转为OaExpressVo
     */
    public static OaExpressVo parseData(String result) {
        if (result == null || result.trim().isEmpty()) {
            return null;
        }
        try {
            JSONObject json = JSON.parseObject(result);
            
            // 检查响应状态
            if (!json.getBooleanValue("success")) {
                System.err.println("顺心捷达查询失败：" + json.getString("message"));
                return null;
            }
            
            JSONObject data = json.getJSONObject("data");
            if (data == null) return null;
            
            JSONArray trackInfoList = data.getJSONArray("trackInfoList");
            if (trackInfoList == null || trackInfoList.isEmpty()) return null;
            
            // 获取最新的轨迹信息（第一条是最新的）
            JSONObject latestTrack = trackInfoList.getJSONObject(0);
            
            OaExpressVo vo = new OaExpressVo();
            vo.setExpressCode(latestTrack.getString("waybillId"));
            vo.setLastUpdateTime(new Date(latestTrack.getLongValue("operationTime")));
            vo.setLastStatus(latestTrack.getString("step"));
            vo.setRemark(latestTrack.getString("trackDesc"));
            
            return vo;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 生成数据签名
     * 签名算法：MD5(data + timestamp + appSecret) 然后Base64编码
     */
    private static String generateDataDigest(String data, String timestamp) throws Exception {
        String signStr = data + timestamp + APP_SECRET;
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(signStr.getBytes(StandardCharsets.UTF_8));
        byte[] digest = md.digest();
        
        // 使用Base64编码，URL安全模式
        return new String(Base64.encodeBase64URLSafe(digest), StandardCharsets.UTF_8);
    }
    
    /**
     * 发送POST请求
     */
    private static String doPost(String urlStr, String formData) throws Exception {
        URL url = new URL(urlStr);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("Accept", "application/json");
        connection.setConnectTimeout(10000);
        connection.setReadTimeout(30000);
        
        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = formData.getBytes(StandardCharsets.UTF_8);
            os.write(input, 0, input.length);
        }
        
        // 读取响应
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
            String line;
            while ((line = br.readLine()) != null) {
                response.append(line);
            }
        }
        
        connection.disconnect();
        return response.toString();
    }
    
    /**
     * 判断是否为顺心捷达快递
     * 根据运单号规则判断：通常以S开头
     */
    public static boolean isSxjdExpress(String waybillId) {
        if (StringUtils.isBlank(waybillId)) {
            return false;
        }
        // 顺心捷达运单号通常以S开头，长度为12位
        return waybillId.startsWith("S") && waybillId.length() >= 10;
    }
    
    /**
     * MD5编码方法（用于测试）
     */
    public static String md5Encode(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes(StandardCharsets.UTF_8));
            byte[] digest = md.digest();
            String r = new String(Base64.encodeBase64URLSafe(digest), StandardCharsets.UTF_8);
            return r;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 测试方法
     */
    public static void main(String[] args) {
        // 测试签名生成
        String data = "{ \"customerOrderNo\":\"QW2315464601\", \"orderChannelNo\":\"SE1231322\", \"orderType\":1,\"whetherEwb\":true,\"senderCompany\":\"测试公司890\", \"senderName\":\"测试收\", \"senderMobile\":\"12345667634\", \"senderTel\":\"0755-8658521\", \"senderProv\":\"广东省\", \"senderCity\":\"广州市\", \"senderArea\":\"越秀区\", \"senderAddress\":\"白云街道102号筒子巷\", \"receiverCompany\":\"绿色公司\", \"receiverName\":\"大师傅\", \"receiverTel\":\"021-85685452\", \"receiverMobile\":\"12313213213\", \"receiverProv\":\"广东省\", \"receiverCity\":\"广州市\", \"receiverArea\":\"海珠区\", \"receiverAddress\":\"华洲街道\", \"cargoName\":\"装修物品\", \"totalPackages\":3, \"totalWeight\":12, \"totalVolume\":15, \"pickupWay\":\"送货（不含上楼）\", \"backSignBill\":\"电子回单\", \"remark\":\"客户接入：sxCustomerCode必填\", \"insuranceValue\":800, \"codAmount\":1024, \"fcodAmount\":620, \"getGoodMode\":\"上门接货\", \"orderSource\":\"PDD\",\"productName\":\"顺心包裹\",\"payType\":\"现付\",\"subMailNos\":\"20220426013,20220426014,20220426015\"}";
        String timestamp = System.currentTimeMillis() + "";
        String app_secret = "773bebe1bd75680a9e03ee579874d5a2";
        String dataDigest = md5Encode(data + timestamp + app_secret);
        System.out.println("测试签名生成：" + dataDigest);
        
        // 测试轨迹查询
        String waybillId = "S60201493742";
        String result = queryRoute(waybillId);
        System.out.println("顺心捷达原始返回：" + result);
        
        OaExpressVo vo = parseData(result);
        if (vo != null) {
            System.out.println("解析后结果：");
            System.out.println("运单号：" + vo.getExpressCode());
            System.out.println("最新状态：" + vo.getLastStatus());
            System.out.println("更新时间：" + vo.getLastUpdateTime());
            System.out.println("描述：" + vo.getRemark());
        } else {
            System.out.println("解析失败或数据为空");
        }
        
        // 测试运单号判断
        System.out.println("\n运单号判断测试：");
        System.out.println("S60201493742 是否为顺心捷达：" + isSxjdExpress("S60201493742"));
        System.out.println("SF1234567890 是否为顺心捷达：" + isSxjdExpress("SF1234567890"));
        System.out.println("1234567890 是否为顺心捷达：" + isSxjdExpress("1234567890"));
    }
}
