package com.xhpc.evcs.notification;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.xhpc.evcs.domain.AuthSecretToken;
import com.xhpc.evcs.dto.ChargeOrderInfo;
import com.xhpc.evcs.dto.ChargeOrderInfoResponse;
import com.xhpc.evcs.dto.CommonRequest;
import com.xhpc.evcs.dto.DTOJsonHelper;
import com.xhpc.evcs.jpa.AuthSecretTokenRepository;
import com.xhpc.evcs.jpa.XhpcHistoryOrderRepository;
import com.xhpc.evcs.utils.DateUtil;
import com.xhpc.evcs.utils.JSONUtil;
import com.xhpc.order.domain.XhpcHistoryOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.Date;
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/1
 */
@Component
public class NotificationChargeOrderInfoTask extends CoreDispatcher {

    @Autowired
    private XhpcHistoryOrderRepository xhpcHistoryOrderRepository;
    @Autowired
    private AuthSecretTokenRepository authSecretTokenRepository;

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

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

        Collection<String> orderKeys = REDIS.keys("order:*");
        Instant now = Instant.now();
        for (String okey : orderKeys) {
            Date otime = DateUtil.orderNo2Date(okey.substring(6));
            if (Duration.between(otime.toInstant(), now).toHours() > 24 * 3) {
                REDIS.deleteObject(okey);
                REDIS.deleteObject(okey.replace("order", "pushOrder"));
                logger.info("clear cache..{}", okey);
            }
        }
        List<AuthSecretToken> authSecretTokenList = authSecretTokenRepository.findBySecretTokenType(SECRET_TOKEN_TYPE_OUT);
        List<XhpcHistoryOrder> xhpcHistoryOrderList =
                xhpcHistoryOrderRepository.findByConfirmResultNotAndOperatorId3rdptyEvcsIsNotNull(0);
        for (XhpcHistoryOrder horder : xhpcHistoryOrderList) {
            for (AuthSecretToken authSecretToken : authSecretTokenList) {
                String operatorId3rdptyEvcs = horder.getOperatorId3rdptyEvcs();
                if (operatorId3rdptyEvcs == null) {
                    if (horder.getInternetSerialNumber() != null) operatorId3rdptyEvcs =
                            horder.getInternetSerialNumber().substring(0, 9);
                }
                if (authSecretToken.getOperatorId3irdpty().equals(operatorId3rdptyEvcs)) {
                    ChargeOrderInfo chargeOrderInfo = new ChargeOrderInfo(horder);
                    final ChargeOrderInfoResponse pushResp = notify(chargeOrderInfo, authSecretToken);
                    if (pushResp != null) {
                        horder.setConfirmResult(pushResp.getConfirmResult());
                        logger.debug("3rd part order {} push result: {}", horder.getSerialNumber(),
                                pushResp.getConfirmResult());
                        xhpcHistoryOrderRepository.save(horder);
                        REDIS.setCacheMapValue("pushOrder:".concat(horder.getSerialNumber()), "horderpushed", true);
                    } else {
                        logger.error("3dp[{}] order[{}/{}] push fail", operatorId3rdptyEvcs,
                                horder.getSerialNumber(), horder.getInternetSerialNumber());
                    }
                }
            }
        }
    }

    public ChargeOrderInfoResponse notify(ChargeOrderInfo chargeOrderInfo, AuthSecretToken authSecretTokenOut) throws JsonProcessingException {

        String data = JSONUtil.toJSONString(chargeOrderInfo);
        CommonRequest<ChargeOrderInfo> commonRequest = new CommonRequest<>();
        commonRequest.setData(data);
        String responseBody = ok(commonRequest, "/notification_charge_order_info", authSecretTokenOut);
        return DTOJsonHelper.parseResponseData(responseBody,
                ChargeOrderInfoResponse.class, authSecretTokenOut);
    }

}
