package com.ghy.order.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ghy.order.domain.LogisticsInfo;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.request.LogisticsQueryRequest;
import com.ghy.order.service.LogisticsService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.order.utils.HttpUtils;
import com.ghy.order.utils.LogisticsUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.HashMap;
import java.util.Map;

/**
 * 物流服务实现类
 *
 * @author clunt
 */
@Slf4j
@Service
public class LogisticsServiceImpl implements LogisticsService {
    
    @Autowired
    private OrderMasterService orderMasterService;
    
    /**
     * 阿里云快递查询 API配置
     */
    @Value("${logistics.aliyun.appCode:}")
    private String appCode;
    
    @Value("${logistics.aliyun.host:https://kzexpress.market.alicloudapi.com}")
    private String host;
    
    @Value("${logistics.aliyun.path:/api-mall/api/express/query}")
    private String path;
    
    @Override
    public LogisticsInfo queryLogistics(LogisticsQueryRequest request) {
        return queryLogistics(request.getTrackingNumber(), request.getExpressCode(), request.getMobile());
    }
    
    @Override
    public LogisticsInfo queryLogistics(String trackingNumber) {
        return queryLogistics(trackingNumber, null, null);
    }
    
    @Override
    public LogisticsInfo queryLogistics(String trackingNumber, String expressCode) {
        return queryLogistics(trackingNumber, expressCode, null);
    }
    
    /**
     * 根据快递单号查询物流信息（阿里云API）
     *
     * @param trackingNumber 快递单号
     * @param expressCode    快递公司编码
     * @param mobile         手机号
     * @return 物流信息
     */
    public LogisticsInfo queryLogistics(String trackingNumber, String expressCode, String mobile) {
        LogisticsInfo logisticsInfo = new LogisticsInfo();
        logisticsInfo.setTrackingNumber(trackingNumber);
        logisticsInfo.setQueryTime(new Date());
        
        try {
            // 验证快递单号格式
            if (!LogisticsUtils.isValidTrackingNumber(trackingNumber)) {
                logisticsInfo.setSuccess(false);
                logisticsInfo.setErrorMsg("快递单号格式不正确");
                return logisticsInfo;
            }
            
            // 调用阿里云快递查询 API
            JSONObject result = callAliyunAPI(trackingNumber, mobile);
            
            if (result.getBool("success", false)) {
                // 查询成功
                logisticsInfo.setSuccess(true);
                
                // 解析快递公司信息
                JSONObject data = result.getJSONObject("data");
                if (data != null) {
                    logisticsInfo.setExpressCode(data.getStr("cpCode"));
                    logisticsInfo.setExpressName(data.getStr("logisticsCompanyName"));
                    logisticsInfo.setStatus(getAliyunStatus(data.getStr("logisticsStatusDesc")));
                    logisticsInfo.setStatusDesc(data.getStr("logisticsStatusDesc"));
                    
                    // 解析物流轨迹
                    List<LogisticsInfo.LogisticsTrace> traces = new ArrayList<>();
                    JSONArray tracesArray = data.getJSONArray("logisticsTraceDetailList");
                    if (tracesArray != null) {
                        for (int i = 0; i < tracesArray.size(); i++) {
                            JSONObject trace = tracesArray.getJSONObject(i);
                            LogisticsInfo.LogisticsTrace logisticsTrace = new LogisticsInfo.LogisticsTrace();
                            
                            // 处理时间戳
                            Long timeStamp = trace.getLong("time");
                            if (timeStamp != null) {
                                logisticsTrace.setTime(new Date(timeStamp));
                            }
                            
                            logisticsTrace.setLocation(trace.getStr("areaName"));
                            logisticsTrace.setDescription(trace.getStr("desc"));
                            logisticsTrace.setStatus(trace.getStr("logisticsStatus"));
                            traces.add(logisticsTrace);
                        }
                    }
                    logisticsInfo.setTraces(traces);
                }
            } else {
                // 查询失败
                logisticsInfo.setSuccess(false);
                logisticsInfo.setErrorMsg(result.getStr("msg", "查询失败"));
            }
            
        } catch (Exception e) {
            log.error("查询物流信息失败，快递单号：{}，错误：{}", trackingNumber, e.getMessage(), e);
            logisticsInfo.setSuccess(false);
            logisticsInfo.setErrorMsg("查询物流信息失败：" + e.getMessage());
        }
        
        return logisticsInfo;
    }
    
    @Override
    public LogisticsInfo queryLogisticsByOrderId(Long orderId) {
        OrderMaster orderMaster = orderMasterService.selectById(orderId);
        if (orderMaster == null || StrUtil.isBlank(orderMaster.getTrackingNumber())) {
            LogisticsInfo logisticsInfo = new LogisticsInfo();
            logisticsInfo.setSuccess(false);
            logisticsInfo.setErrorMsg("订单不存在或没有快递单号");
            return logisticsInfo;
        }
        
        return queryLogistics(orderMaster.getTrackingNumber());
    }
    
    /**
     * 调用阿里云快递查询 API
     *
     * @param trackingNumber 快递单号
     * @param mobile         手机号
     * @return API返回结果
     */
    private JSONObject callAliyunAPI(String trackingNumber, String mobile) {
        try {
            String method = "GET";
            
            // 构建请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Authorization", "APPCODE " + appCode);
            
            // 构建查询参数
            Map<String, String> querys = new HashMap<>();
            querys.put("expressNo", trackingNumber);
            if (StrUtil.isNotBlank(mobile)) {
                querys.put("mobile", mobile);
            }
            
            log.info("阿里云快递查询API请求参数: expressNo={}, mobile={}", trackingNumber, mobile);
            
            // 调用API
            HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
            String result = EntityUtils.toString(response.getEntity());
            log.info("阿里云快递查询API响应结果: {}", result);
            
            // 检查响应状态码
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                log.error("阿里云API返回错误状态码: {}", statusCode);
                JSONObject errorResult = new JSONObject();
                errorResult.set("success", false);
                errorResult.set("message", "API返回错误状态码: " + statusCode);
                return errorResult;
            }
            
            // 检查响应内容是否为空
            if (StrUtil.isBlank(result)) {
                log.error("阿里云API返回空响应");
                JSONObject errorResult = new JSONObject();
                errorResult.set("success", false);
                errorResult.set("message", "API返回空响应");
                return errorResult;
            }
            
            // 检查响应内容是否以{开头（JSON格式）
            if (!result.trim().startsWith("{")) {
                log.error("阿里云API返回非JSON格式响应: {}", result.substring(0, Math.min(100, result.length())));
                JSONObject errorResult = new JSONObject();
                errorResult.set("success", false);
                errorResult.set("message", "API返回非JSON格式响应");
                return errorResult;
            }
            
            // 尝试解析JSON
            try {
                return JSONUtil.parseObj(result);
            } catch (Exception jsonException) {
                log.error("解析阿里云API响应JSON失败: {}", jsonException.getMessage());
                JSONObject errorResult = new JSONObject();
                errorResult.set("success", false);
                errorResult.set("message", "解析API响应失败: " + jsonException.getMessage());
                return errorResult;
            }
            
        } catch (Exception e) {
            log.error("调用阿里云快递查询API失败: {}", e.getMessage(), e);
            JSONObject errorResult = new JSONObject();
            errorResult.set("success", false);
            errorResult.set("message", "API调用失败: " + e.getMessage());
            return errorResult;
        }
    }
    
    /**
     * 将阿里云状态转换为系统状态码
     *
     * @param aliyunStatus 阿里云状态
     * @return 系统状态码
     */
    private Integer getAliyunStatus(String aliyunStatus) {
        if (StrUtil.isBlank(aliyunStatus)) {
            return 0;
        }
        
        switch (aliyunStatus) {
            case "在途":
            case "运输中":
            case "TRANSPORT":
                return 0;
            case "揽收":
            case "已揽收":
            case "ACCEPT":
                return 1;
            case "疑难":
            case "异常":
            case "EXCEPTION":
                return 2;
            case "签收":
            case "已签收":
            case "SIGN":
                return 3;
            case "退签":
            case "已退签":
            case "REJECT":
                return 4;
            case "派件":
            case "派送中":
            case "DELIVERING":
                return 5;
            case "退回":
            case "已退回":
            case "RETURN":
                return 6;
            case "到达驿站":
            case "STA_INBOUND":
                return 5; // 到达驿站也算派件状态
            default:
                return 0;
        }
    }
    
    /**
     * 获取状态描述
     *
     * @param status 状态码
     * @return 状态描述
     */
    private String getStatusDesc(Integer status) {
        switch (status) {
            case 0:
                return "在途";
            case 1:
                return "揽收";
            case 2:
                return "疑难";
            case 3:
                return "签收";
            case 4:
                return "退签";
            case 5:
                return "派件";
            case 6:
                return "退回";
            default:
                return "未知";
        }
    }
} 