package com.ruoyi.jarvis.service;

import com.ruoyi.jarvis.domain.JDOrder;
import com.ruoyi.jarvis.domain.WeComShareLinkLogisticsJob;

import java.util.Map;

/**
 * 物流信息服务接口
 */
public interface ILogisticsService {
    /**
     * 获取物流信息并推送（如果获取到运单号）
     * @param order 订单信息
     * @return 是否成功获取并推送
     */
    boolean fetchLogisticsAndPush(JDOrder order);

    /**
     * 分享类京东物流短链：查运单并通过 wxts 推送到指定 touser（不依赖订单表）
     */
    boolean fetchLogisticsByShareLinkAndPush(String trackingUrl, String remark, String touser);

    /**
     * 企微备注提交后仅入队，由 {@link com.ruoyi.jarvis.task.LogisticsScanTask} 与订单扫描一并拉取物流，避免阻塞 HTTP 回调。
     *
     * @param fromWecomUserId 企微消息 FromUserName，入库监控并在未配 touser 时作为推送目标
     */
    void enqueueShareLinkForScan(String trackingUrl, String remark, String touser, String fromWecomUserId);

    /**
     * 将已落库任务按与 {@link #enqueueShareLinkForScan} 相同的 JSON 格式推入 Redis（补录、手动失败后重入队等）。
     * Redis 项中的 attempts 与定时 drain 重试上限对齐，取自 {@link WeComShareLinkLogisticsJob#getScanAttempts()}（仅由 drain 回写递增；管理端手动拉取失败不会垫高该计数）。
     */
    void pushShareLinkJobToRedis(WeComShareLinkLogisticsJob job);

    /**
     * 扫描落库表中仍待处理的任务（含 {@code ABANDONED}，对账时会重置计数后再入队；仅 {@code create_time} 一个月内），在限频下补入 Redis。
     *
     * @return 本次获得限频锁并成功推入队列的条数
     */
    int reconcileShareLinkJobsIntoPendingQueue();

    /**
     * 定时任务内：依次弹出队列并调用 {@link #fetchLogisticsByShareLinkAndPush}。
     *
     * @return 本轮从 Redis 弹出并尝试处理的条数（与定时任务尾段逻辑一致）
     */
    int drainPendingShareLinkQueue();

    /**
     * 管理端调试：立刻请求物流接口并尝试推送分享链模板，返回字段与订单「手动获取物流」相近（requestUrl、responseRaw、responseData、pushSent 等）。
     */
    Map<String, Object> adminFetchShareLinkLogisticsDebug(String trackingUrl, String remark, String touser);

    /** 测试清理：删除分享链待扫描队列键 */
    void clearAdhocPendingQueue();
    
    /**
     * 检查订单是否已处理过（Redis中是否有运单号）
     * @param orderId 订单ID
     * @return 如果已处理返回true，否则返回false
     */
    boolean isOrderProcessed(Long orderId);
    
    /**
     * 检查物流服务健康状态
     * @return 健康状态信息，包含是否健康、状态描述等
     */
    HealthCheckResult checkHealth();

    /**
     * 构造调用物流解析服务的完整 GET URL（路径与编码与 {@link #fetchLogisticsAndPush} 一致）。
     * 配置多个 {@code jarvis.server.logistics.base-urls} 时按轮询选取 base，便于内网多实例并行。
     *
     * @param logisticsLink 原始物流追踪链接（未编码）
     */
    String buildFetchLogisticsRequestUrl(String logisticsLink);
    
    /**
     * 健康检测结果
     */
    class HealthCheckResult {
        private boolean healthy;
        private String status;
        private String message;
        private String serviceUrl;
        
        public HealthCheckResult(boolean healthy, String status, String message, String serviceUrl) {
            this.healthy = healthy;
            this.status = status;
            this.message = message;
            this.serviceUrl = serviceUrl;
        }
        
        public boolean isHealthy() {
            return healthy;
        }
        
        public void setHealthy(boolean healthy) {
            this.healthy = healthy;
        }
        
        public String getStatus() {
            return status;
        }
        
        public void setStatus(String status) {
            this.status = status;
        }
        
        public String getMessage() {
            return message;
        }
        
        public void setMessage(String message) {
            this.message = message;
        }
        
        public String getServiceUrl() {
            return serviceUrl;
        }
        
        public void setServiceUrl(String serviceUrl) {
            this.serviceUrl = serviceUrl;
        }
    }
}

