package com.xhpc.evcs.notification;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.xhpc.evcs.domain.AuthSecretToken;
import com.xhpc.evcs.dto.CancelOrderRequest;
import com.xhpc.evcs.dto.CancelOrderResponse;
import com.xhpc.evcs.dto.CommonRequest;
import com.xhpc.evcs.dto.DTOJsonHelper;
import com.xhpc.evcs.jpa.AuthSecretTokenRepository;
import com.xhpc.evcs.utils.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;
import static com.xhpc.evcs.domain.AuthSecretToken.SECRET_TOKEN_TYPE_OUT;

/**
 * 推送订单取消，都开放
 * @Author HongYun on 2021/11/8
 */
@Component
public class NotificationCancelOrderTask extends CoreDispatcher {

    @Autowired
    private AuthSecretTokenRepository authSecretTokenRepository;

    //private Logger logger = LoggerFactory.getLogger(NotificationChargeOrderInfoTask.class);

    @Scheduled(fixedRate = 1000 * 30)
    public void run() throws JsonProcessingException {

        //Getting the orders, which need to be notified.
        Collection<String> ordersNotFilter = REDIS.keys("order:*");
        List<String> ordersNeedToNotify = new ArrayList<>();
        for (String order : ordersNotFilter) {
            if (order.length() != 38) continue;
            String startStatus = REDIS.getCacheMapValue(order, "startStatus");
            if ("失败".equals(startStatus)) {
                ordersNeedToNotify.add(order);
            }
        }

        //Getting the internetSerialNumbers, which need to be notified.
        List<String> internetSerialNumbers = new ArrayList<>();
        Collection<String> pushOrders = REDIS.keys("pushOrder:*");
        List<String> orderMaybeNeedToDelete = new ArrayList<>();
        for (String order : ordersNeedToNotify) {
            String tempOrder = "pushOrder:" + order.substring(6);
            if (pushOrders.contains(tempOrder)) {
                String internetSerialNumber = REDIS.getCacheMapValue(tempOrder, "internetSerialNumber");
                if (null != internetSerialNumber) {
                    internetSerialNumbers.add(internetSerialNumber);
                    orderMaybeNeedToDelete.add(order);
                }
            }
        }

        //Making notify.
        for (int i = 0; i < internetSerialNumbers.size(); i++) {
            String internetSerialNumber = internetSerialNumbers.get(i);
            String orderNo = orderMaybeNeedToDelete.get(i);
            String operatorId = internetSerialNumber.substring(0, 9);
            AuthSecretToken authSecretTokenOut = authSecretTokenRepository.findByOperatorId3irdptyAndSecretTokenType(operatorId, SECRET_TOKEN_TYPE_OUT).orElse(null);
            if (null != authSecretTokenOut) {
                CancelOrderRequest cancelOrderRequest = new CancelOrderRequest();
                cancelOrderRequest.setStartChargeSeq(internetSerialNumber);
                notify(cancelOrderRequest, authSecretTokenOut, orderNo);
            }
        }

    }

    public void notify(CancelOrderRequest cancelOrderRequest, AuthSecretToken authSecretTokenOut, String orderNo) throws JsonProcessingException {

        String data = JSONUtil.toJSONString(cancelOrderRequest);
        CommonRequest<CancelOrderRequest> commonRequest = new CommonRequest<>();
        commonRequest.setData(data);
        String responseBody = ok(commonRequest, "/notification_cancel_order", authSecretTokenOut);
        CancelOrderResponse cancelOrderResponse = DTOJsonHelper.parseResponseData(responseBody,
                CancelOrderResponse.class, authSecretTokenOut);
        if (null != cancelOrderResponse) {
            Integer succStat = cancelOrderResponse.getSuccStat();
            if (null != succStat) {
                if (0 == succStat) {
                    REDIS.deleteObject(orderNo);
                } else {
                    throw new RuntimeException(String.format("push 3rd cancel order status [%s] failed: %s",
                            cancelOrderResponse.getSuccStat(), responseBody));
                }
            }
        }
    }
}
