package com.erp.logistics.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;

/**
 * 物流服务幂等性工具
 * 使用Redis实现物流回调的幂等性
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LogisticsIdempotencyService {

    private final RedisTemplate<String, Object> redisTemplate;

    private static final String IDEMPOTENT_KEY_PREFIX = "logistics:idempotent:";
    private static final Duration DEFAULT_TTL = Duration.ofHours(24);

    /**
     * 检查是否重复请求
     */
    public boolean isDuplicate(String key) {
        String redisKey = IDEMPOTENT_KEY_PREFIX + key;
        return Boolean.TRUE.equals(redisTemplate.hasKey(redisKey));
    }

    /**
     * 标记请求已处理
     */
    public void markProcessed(String key, Object value) {
        String redisKey = IDEMPOTENT_KEY_PREFIX + key;
        redisTemplate.opsForValue().set(redisKey, value, DEFAULT_TTL);
    }

    /**
     * 获取已处理结果
     */
    public Object getProcessedResult(String key) {
        String redisKey = IDEMPOTENT_KEY_PREFIX + key;
        return redisTemplate.opsForValue().get(redisKey);
    }

    /**
     * 物流回调幂等键：carrierCode + waybillNo + status + traceTime
     * 同一运单同状态同时间的回调视为重复
     */
    public String buildCallbackKey(String carrierCode, String waybillNo, String status, String traceTime) {
        return carrierCode + ":" + waybillNo + ":" + status + ":" + traceTime;
    }

    /**
     * 运单状态更新幂等键：waybillNo + status
     */
    public String buildWaybillStatusKey(String waybillNo, String status) {
        return "status:" + waybillNo + ":" + status;
    }
}
