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 ZtoCarrierAdapter extends AbstractCarrierAdapter {

    public static final String CARRIER_CODE = "ZTO";
    public static final String CARRIER_NAME = "中通快递";

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

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

    @Value("${logistics.carriers.zto.customer-code:}")
    private String customerCode;

    @Value("${logistics.carriers.zto.api-key:}")
    private String apiKey;

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

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

    @Override
    public boolean match(String waybillNo) {
        // 中通运单号通常以71开头，12-15位数字
        return waybillNo != null && waybillNo.matches("^(71\\d{11,14}|\\d{12,15})$");
    }

    @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
            log.warn("[中通] API对接待实现，当前返回空轨迹");
        } catch (Exception e) {
            log.error("[中通] 查询轨迹异常: {}", waybillNo, e);
        }

        return traces;
    }

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

        String waybillNo = String.valueOf(rawData.getOrDefault("waybillNo", rawData.getOrDefault("billCode", "")));
        String statusCode = String.valueOf(rawData.getOrDefault("statusCode", rawData.getOrDefault("opCode", "")));
        String statusName = String.valueOf(rawData.getOrDefault("statusName", rawData.getOrDefault("opName", "")));
        String location = String.valueOf(rawData.getOrDefault("city", rawData.getOrDefault("opCity", "")));
        String description = String.valueOf(rawData.getOrDefault("remark", ""));
        String scanTime = String.valueOf(rawData.getOrDefault("scanTime", rawData.getOrDefault("opTime", "")));

        String status = mapZtoStatus(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);
    }

    /**
     * 中通状态码映射
     */
    private String mapZtoStatus(String statusCode) {
        return switch (statusCode) {
            case "BILL_CREATE", "COLLECT", "TRANSPORT", "ARRIVE", "LOADING", "UNLOADING" -> "IN_TRANSIT";
            case "SEND" -> "DELIVERING";
            case "SIGN" -> "SIGNED";
            case "RETURN", "RETURN_TRANSPORT" -> "RETURNING";
            case "RETURN_SIGN" -> "RETURNED";
            case "EXCEPTION" -> "EXCEPTION";
            default -> "IN_TRANSIT";
        };
    }
}
