package com.ruoyi.jarvis.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.jarvis.config.JarvisGoofishProperties;
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLog;
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLogQuery;
import com.ruoyi.jarvis.domain.ErpOpenConfig;
import com.ruoyi.jarvis.dto.GoofishNotifyMessage;
import com.ruoyi.jarvis.mapper.ErpGoofishOrderEventLogMapper;
import com.ruoyi.jarvis.mapper.ErpGoofishOrderMapper;
import com.ruoyi.jarvis.service.IErpGoofishOrderService;
import com.ruoyi.jarvis.service.IErpOpenConfigService;
import com.ruoyi.jarvis.service.goofish.GoofishNotifyAsyncFacade;
import com.ruoyi.jarvis.service.goofish.GoofishOrderChangeLogger;
import com.ruoyi.jarvis.service.goofish.GoofishOrderPipeline;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;

@Service
public class ErpGoofishOrderServiceImpl implements IErpGoofishOrderService {

    @Autowired
    private ObjectProvider<RocketMQTemplate> rocketMQTemplate;

    @Resource
    private JarvisGoofishProperties goofishProperties;

    @Resource
    private GoofishNotifyAsyncFacade goofishNotifyAsyncFacade;

    @Resource
    private GoofishOrderPipeline goofishOrderPipeline;

    @Resource
    private ErpGoofishOrderMapper erpGoofishOrderMapper;

    @Resource
    private ErpGoofishOrderEventLogMapper erpGoofishOrderEventLogMapper;

    @Resource
    private IErpOpenConfigService erpOpenConfigService;

    @Resource
    private GoofishOrderChangeLogger goofishOrderChangeLogger;

    @Override
    public void publishOrProcessNotify(String appid, Long timestamp, JSONObject body) {
        RocketMQTemplate mq = rocketMQTemplate.getIfAvailable();
        if (mq != null) {
            GoofishNotifyMessage m = new GoofishNotifyMessage();
            m.setAppid(appid);
            m.setTimestamp(timestamp);
            m.setBody(body.toJSONString());
            mq.syncSend(goofishProperties.getMqTopic(), JSON.toJSONString(m));
        } else {
            goofishNotifyAsyncFacade.afterNotify(appid, body);
        }
    }

    @Override
    public void asyncPipelineAfterNotify(String appid, JSONObject notifyBody) {
        goofishOrderPipeline.runFullPipeline(appid, notifyBody);
    }

    @Override
    public List<ErpGoofishOrder> selectList(ErpGoofishOrder query) {
        return erpGoofishOrderMapper.selectList(query);
    }

    @Override
    public ErpGoofishOrder selectById(Long id) {
        return erpGoofishOrderMapper.selectById(id);
    }

    @Override
    public int pullOrdersForAppKey(String appKey, int lookbackHours) {
        return goofishOrderPipeline.pullForAppKey(appKey, lookbackHours);
    }

    @Override
    public int pullAllEnabled(int lookbackHours) {
        int total = 0;
        List<ErpOpenConfig> cfgs = erpOpenConfigService.selectEnabledOrderBySort();
        if (cfgs == null) {
            return 0;
        }
        for (ErpOpenConfig c : cfgs) {
            if (c.getAppKey() == null) {
                continue;
            }
            total += goofishOrderPipeline.pullForAppKey(c.getAppKey(), lookbackHours);
        }
        return total;
    }

    @Override
    public int pullOrdersForAppKeyFullHistory(String appKey) {
        return goofishOrderPipeline.pullForAppKeyFullHistory(appKey);
    }

    @Override
    public int pullAllEnabledFullHistory() {
        int total = 0;
        List<ErpOpenConfig> cfgs = erpOpenConfigService.selectEnabledOrderBySort();
        if (cfgs == null) {
            return 0;
        }
        for (ErpOpenConfig c : cfgs) {
            if (c.getAppKey() == null) {
                continue;
            }
            total += goofishOrderPipeline.pullForAppKeyFullHistory(c.getAppKey());
        }
        return total;
    }

    @Override
    public void refreshDetail(Long id) {
        ErpGoofishOrder row = erpGoofishOrderMapper.selectById(id);
        if (row != null) {
            goofishOrderPipeline.refreshDetail(row);
        }
    }

    @Override
    public void retryShip(Long id) {
        erpGoofishOrderMapper.resetShipForRetry(id);
        ErpGoofishOrder row = erpGoofishOrderMapper.selectById(id);
        if (row != null) {
            goofishOrderPipeline.syncWaybillFromRedis(row);
            goofishOrderPipeline.tryAutoShip(row);
        }
    }

    @Override
    public int syncWaybillAndTryShipBatch(int limit) {
        return goofishOrderPipeline.syncWaybillAndTryShipBatch(limit);
    }

    @Override
    public void applyListOrNotifyItem(String appKey, JSONObject item, String lastNotifyJson) {
        goofishOrderPipeline.applyListOrNotifyItem(appKey, item, lastNotifyJson);
    }

    @Override
    public void notifyJdWaybillReady(Long jdOrderId) {
        if (jdOrderId == null) {
            return;
        }
        ErpGoofishOrder query = new ErpGoofishOrder();
        query.setJdOrderId(jdOrderId);
        List<ErpGoofishOrder> list = erpGoofishOrderMapper.selectList(query);
        if (list == null || list.isEmpty()) {
            return;
        }
        for (ErpGoofishOrder ref : list) {
            ErpGoofishOrder full = erpGoofishOrderMapper.selectById(ref.getId());
            if (full == null) {
                continue;
            }
            goofishOrderPipeline.syncWaybillFromRedis(full);
            goofishOrderPipeline.tryAutoShip(full);
        }
    }

    @Override
    public boolean hasLinkedGoofishOrder(Long jdOrderId) {
        if (jdOrderId == null) {
            return false;
        }
        ErpGoofishOrder query = new ErpGoofishOrder();
        query.setJdOrderId(jdOrderId);
        List<ErpGoofishOrder> list = erpGoofishOrderMapper.selectList(query);
        return list != null && !list.isEmpty();
    }

    @Override
    public void traceJdLogisticsPushForGoofish(Long jdOrderId, String waybillNo, String summary) {
        if (jdOrderId == null || goofishOrderChangeLogger == null) {
            return;
        }
        ErpGoofishOrder query = new ErpGoofishOrder();
        query.setJdOrderId(jdOrderId);
        List<ErpGoofishOrder> list = erpGoofishOrderMapper.selectList(query);
        if (list == null || list.isEmpty()) {
            return;
        }
        String wb = waybillNo != null ? waybillNo.trim() : "";
        String sum = summary != null ? summary : "";
        String msg = "jdOrderId=" + jdOrderId + " waybill=" + wb + "；" + sum;
        if (msg.length() > 1000) {
            msg = msg.substring(0, 999) + "…";
        }
        for (ErpGoofishOrder row : list) {
            if (row.getId() == null) {
                continue;
            }
            goofishOrderChangeLogger.append(row.getId(), row.getAppKey(), row.getOrderNo(),
                GoofishOrderChangeLogger.TYPE_LOGISTICS, GoofishOrderChangeLogger.SOURCE_JD_LOGISTICS_PUSH, msg);
        }
    }

    @Override
    public List<ErpGoofishOrderEventLog> listEventLogsByOrderId(Long orderId) {
        if (orderId == null) {
            return Collections.emptyList();
        }
        List<ErpGoofishOrderEventLog> list = erpGoofishOrderEventLogMapper.selectByOrderId(orderId);
        return list != null ? list : Collections.emptyList();
    }

    @Override
    public List<ErpGoofishOrderEventLog> selectEventLogList(ErpGoofishOrderEventLogQuery query) {
        if (query == null) {
            query = new ErpGoofishOrderEventLogQuery();
        }
        List<ErpGoofishOrderEventLog> list = erpGoofishOrderEventLogMapper.selectLogList(query);
        return list != null ? list : Collections.emptyList();
    }
}
