package com.erp.logistics.service.adapter;

import com.erp.logistics.entity.LogisticsTrace;
import com.erp.logistics.entity.WaybillStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 顺丰速运适配器
 */
@Slf4j
@Component
public class SfCarrierAdapter extends AbstractCarrierAdapter {

    public static final String CARRIER_CODE = "SF";
    public static final String CARRIER_NAME = "顺丰速运";

    @Value("${logistics.callback.secret-keys.sf:}")
    private String secretKey;

    @Value("${logistics.carriers.sf.api-url:}")
    private String apiUrl;

    @Value("${logistics.carriers.sf.app-id:}")
    private String appId;

    @Value("${logistics.carriers.sf.app-key:}")
    private String appKey;

    @Override
    public String getCarrierCode() {
        return CARRIER_CODE;
    }

    @Override
    public String getCarrierName() {
        return CARRIER_NAME;
    }

    @Override
    public boolean match(String waybillNo) {
        // 顺丰运单号通常以收件人所在城市代码开头，12位数字为主
        return waybillNo != null && waybillNo.matches("^\\d{12,20}$");
    }

    @Override
    protected String getSecretKey() {
        return secretKey;
    }

    @Override
    protected boolean doVerifySign(Map<String, Object> data, String sign) {
        // 顺丰回调签名验证
        return verifyMd5Sign(data, sign, "sign", "timestamp");
    }

    @Override
    public List<LogisticsTrace> queryTraces(String waybillNo) {
        log.info("[顺丰] 查询轨迹, 运单号: {}", waybillNo);
        List<LogisticsTrace> traces = new ArrayList<>();

        try {
            // TODO: 调用顺丰镖局API
            // 这里模拟返回，实际需要对接顺丰开放平台
            // String result = HttpUtil.get(apiUrl + "/trace?waybillNo=" + waybillNo);
            log.warn("[顺丰] API对接待实现，当前返回空轨迹");
        } catch (Exception e) {
            log.error("[顺丰] 查询轨迹异常: {}", waybillNo, e);
        }

        return traces;
    }

    @Override
    public CallbackResult parseCallback(Map<String, Object> rawData) {
        log.info("[顺丰] 解析回调数据: {}", rawData);

        String waybillNo = String.valueOf(rawData.getOrDefault("waybillNo", rawData.getOrDefault("orderId", "")));
        String statusCode = String.valueOf(rawData.getOrDefault("statusCode", ""));
        String statusName = String.valueOf(rawData.getOrDefault("statusName", ""));
        String location = String.valueOf(rawData.getOrDefault("location", ""));
        String description = String.valueOf(rawData.getOrDefault("description", ""));
        String scanTime = String.valueOf(rawData.getOrDefault("scanTime", ""));

        // 状态映射
        String status = mapSfStatus(statusCode);
        String statusLabel = statusName;

        // 构建运单状态
        WaybillStatus waybillStatus = new WaybillStatus()
                .setWaybillNo(waybillNo)
                .setCarrier(CARRIER_CODE)
                .setStatus(status)
                .setStatusLabel(statusLabel)
                .setLocation(location)
                .setDescription(description)
                .setLastTraceTime(parseTime(scanTime))
                .setSyncStatus(2)
                .setSyncRetryCount(0);

        // 已签收
        if ("SIGNED".equals(status)) {
            waybillStatus.setSignedTime(parseTime(scanTime));
        }

        // 构建轨迹
        LogisticsTrace trace = new LogisticsTrace()
                .setWaybillNo(waybillNo)
                .setCarrier(CARRIER_CODE)
                .setStatus(status)
                .setStatusLabel(statusLabel)
                .setLocation(location)
                .setDescription(description)
                .setTraceTime(parseTime(scanTime))
                .setRawStatusCode(statusCode)
                .setRawData(toJson(rawData))
                .setCreatedAt(LocalDateTime.now());

        List<LogisticsTrace> traces = List.of(trace);

        return new CallbackResult(waybillNo, waybillStatus, traces);
    }

    /**
     * 顺丰状态码映射
     * SF状态码参考
     */
    private String mapSfStatus(String statusCode) {
        return switch (statusCode) {
            case "1", "2", "3" -> "IN_TRANSIT";  // 运输中
            case "4" -> "DELIVERING";              // 派送中
            case "5", "6" -> "SIGNED";             // 已签收
            case "7", "8" -> "RETURNING";          // 退回中
            case "9" -> "RETURNED";                // 已退回
            case "10", "11", "12" -> "EXCEPTION";  // 异常
            default -> "IN_TRANSIT";
        };
    }
}
