package com.xhpc.evcs.notification;

import com.xhpc.evcs.domain.*;
import com.xhpc.evcs.dto.CDChargeOrder4BonusInfoRes;
import com.xhpc.evcs.dto.CDChargeOrderInfo4BonusReq;
import com.xhpc.evcs.dto.CommonRequest;
import com.xhpc.evcs.dto.DTOJsonHelper;
import com.xhpc.evcs.jpa.*;
import com.xhpc.evcs.utils.DateUtil;
import com.xhpc.evcs.utils.JSONUtil;
import com.xhpc.order.domain.XhpcHistoryOrder;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

import static com.xhpc.evcs.domain.AuthSecretToken.SECRET_TOKEN_TYPE_OUT;

@Component
@Slf4j
public class NotificationChargeOrderInfo4BonusTask extends CoreDispatcher {

    @Autowired
    private XhpcHistoryOrderRepository xhpcHistoryOrderRepository;
    @Autowired
    private EtPushFailedOrderRepository etPushFailedOrderRepository;
    @Autowired
    private AuthSecretTokenRepository authSecretTokenRepository;
    @Autowired
    private StatisticTimeIntervalRepository statisticTimeIntervalRepository;
    @Autowired
    private OrderMappingRepository orderMappingRepository;
    @Autowired
    private XhpcChargingStationRepository chargingStationRepo;
    @Autowired
    private XhpcStationInternetBlacklistRepository xhpcStationInternetBlacklistRepo;
    private final Logger logger = LoggerFactory.getLogger(NotificationChargeOrderInfo4BonusTask.class);

    /**
     * 推送充电订单信息（运营奖补）(老平台已停止推送）
     * @throws IOException
     */
    //不开放，已停止推送
    //@Scheduled(fixedRate = 1000 * 180)
    public void run() throws IOException {

        AuthSecretToken authSecretTokenOut =
                authSecretTokenRepository.findByOperatorId3irdptyAndOperatorIdAndSecretTokenType(
                        "765367656", "MA6DFCTD5", SECRET_TOKEN_TYPE_OUT).orElse(null); //todo

        // maybe对接第三方
        if (authSecretTokenOut != null) {
            final List<XhpcHistoryOrder> notYetPushOrder =
                    xhpcHistoryOrderRepository.findTop100ByHistoryOrderIdGreaterThanAndStateGreaterThanOrderByHistoryOrderIdAsc(authSecretTokenOut.getLastPushOrder(), 0);
            for (XhpcHistoryOrder xhpcHistoryOrder : notYetPushOrder) {
                XhpcStationInternetBlacklist xhpcStationInternetBlacklist =
                        xhpcStationInternetBlacklistRepo.findByChargingStationIdAndInternetUserId(xhpcHistoryOrder.getChargingStationId(),
                                5L).orElse(null);
                if (xhpcStationInternetBlacklist != null) continue;
                List<XhpcStatisticsTimeInterval> statisticTimeIntervalList =
                        statisticTimeIntervalRepository.findByHistoryOrderId(xhpcHistoryOrder.getHistoryOrderId());
                xhpcHistoryOrder.setXhpcStatisticsTimeIntervalList(statisticTimeIntervalList);
                notify(xhpcHistoryOrder, authSecretTokenOut, false);
            }
            final List<XhpcHistoryOrder> pushFailedOrders =
                    xhpcHistoryOrderRepository.findTop10JoinPushFailedOrders(authSecretTokenOut.getOperatorId3irdpty());
            for (XhpcHistoryOrder xhpcHistoryOrder : pushFailedOrders) {
                XhpcStationInternetBlacklist xhpcStationInternetBlacklist =
                        xhpcStationInternetBlacklistRepo.findByChargingStationIdAndInternetUserId(xhpcHistoryOrder.getChargingStationId(),
                                5L).orElse(null);
                if (xhpcStationInternetBlacklist != null) continue;
                List<XhpcStatisticsTimeInterval> statisticTimeIntervalList =
                        statisticTimeIntervalRepository.findByHistoryOrderId(xhpcHistoryOrder.getHistoryOrderId());
                xhpcHistoryOrder.setXhpcStatisticsTimeIntervalList(statisticTimeIntervalList);
                final boolean notify = notify(xhpcHistoryOrder, authSecretTokenOut, true);
                if (notify) {
                    etPushFailedOrderRepository.deleteById(xhpcHistoryOrder.getHistoryOrderId());
                }
            }
        }
    }

    public boolean notify(XhpcHistoryOrder xhpcHistoryOrder, AuthSecretToken authSecretTokenOut, boolean isRepush) throws IOException {
        String operatorIdEvcs = xhpcHistoryOrder.getOperatorIdEvcs();
        if (operatorIdEvcs == null) {
            Long chargingStationId = xhpcHistoryOrder.getChargingStationId();
            XhpcChargingStation station = chargingStationRepo.findById(chargingStationId).orElse(null);
            if(station == null){
                logger.error("station[{}] is not exits", chargingStationId);
                return false;
            }

            String stationOperatorIdEvcs = station.getOperatorIdEvcs();
            if (stationOperatorIdEvcs == null) {
                logger.error("station[{}] operator id evcs not set", chargingStationId);
                return false;
            }
            if (stationOperatorIdEvcs.length() == 18) {
                operatorIdEvcs = stationOperatorIdEvcs.substring(8, 17);
            } else {
                operatorIdEvcs = stationOperatorIdEvcs;
            }
        }
        EtOrderMapping etOrderMapping = saveOrderMapping(xhpcHistoryOrder, orderMappingRepository, operatorIdEvcs);
        CDChargeOrderInfo4BonusReq cdChargeOrderInfo4BonusReq = new CDChargeOrderInfo4BonusReq(xhpcHistoryOrder,
                etOrderMapping);
        operatorIdEvcs = operatorIdEvcs == null ? "MA6DFCTD5" : operatorIdEvcs;
        String data = JSONUtil.toJSONString(cdChargeOrderInfo4BonusReq);
        CommonRequest<CDChargeOrderInfo4BonusReq> commonRequest = new CommonRequest<>();
        commonRequest.setData(data);
        String responseBody = ok(commonRequest, "/notification_charge_order_info_for_bonus", authSecretTokenOut,
                operatorIdEvcs);
        //logger.info("========老平台推送=======operatorIdEvcs============================="+operatorIdEvcs);
        //logger.info("========老平台推送=======responseBody============================="+cdChargeOrderInfo4BonusReq.getStartChargeSeq());

        CDChargeOrder4BonusInfoRes cdChargeOrder4BonusInfoRes = DTOJsonHelper.parseResponseData(responseBody,
                CDChargeOrder4BonusInfoRes.class, authSecretTokenOut);
        if (!isRepush) {
            authSecretTokenOut.setLastPushOrder(xhpcHistoryOrder.getHistoryOrderId());
            authSecretTokenRepository.save(authSecretTokenOut);
        }
        if (cdChargeOrder4BonusInfoRes != null && cdChargeOrder4BonusInfoRes.getConfirmResult() == 0) {
            return true;
        } else {
            if (!isRepush) {
                EtPushFailedOrder etPushFailedOrder = new EtPushFailedOrder();
                etPushFailedOrder.setId(xhpcHistoryOrder.getHistoryOrderId());
                etPushFailedOrder.setOperatorId3rdpty(authSecretTokenOut.getOperatorId3irdpty());
                etPushFailedOrderRepository.save(etPushFailedOrder);
            }
            logger.error(String.format("push CD notification order[%s] failed: %s", xhpcHistoryOrder.getSerialNumber(),
                    responseBody));
            return false;
        }
    }

    private EtOrderMapping saveOrderMapping(XhpcHistoryOrder xhpcHistoryOrder,
                                            OrderMappingRepository orderMappingRepository, String operatorId) {

        String internetSerialNumber = xhpcHistoryOrder.getInternetSerialNumber();
        String xhOrderNo = xhpcHistoryOrder.getSerialNumber();
        return saveOrderMapping(xhOrderNo, internetSerialNumber, orderMappingRepository, operatorId);
    }

    public static String transferInternetOrderNo(String orderKeyOrNo, String operatorId) {
        //80836000010001012110191723410021
        //MA6DFCTD5202201111742100140
        String orderNo = orderKeyOrNo.replace("order:", "");
        if (operatorId.length() > 9) {
            operatorId = operatorId.substring(0, 9);
        }
        return operatorId.concat(DateUtil.getYYYY()).concat(orderNo.substring(18));
    }

    public static EtOrderMapping saveOrderMapping(String xhOrderNo, String internetSerialNumber,
                                                  OrderMappingRepository orderMappingRepository, String operatorId) {

        EtOrderMapping etOrderMapping;
        EtOrderMapping om;
        if (internetSerialNumber != null) {
            om = new EtOrderMapping();
            om.setEvcsOrderNo(internetSerialNumber);
            Example<EtOrderMapping> example = Example.of(om);
            etOrderMapping = orderMappingRepository.findOne(example).orElse(null);
            if (etOrderMapping == null) {
                om.setXhOrderNo(xhOrderNo);
                etOrderMapping = orderMappingRepository.save(om);
            }
        } else {
            om = new EtOrderMapping();
            om.setXhOrderNo(xhOrderNo);
            Example<EtOrderMapping> example = Example.of(om);
            etOrderMapping = orderMappingRepository.findOne(example).orElse(null);
            if (etOrderMapping == null) {
                etOrderMapping = new EtOrderMapping();
                etOrderMapping.setXhOrderNo(xhOrderNo);
                etOrderMapping.setEvcsOrderNo(transferInternetOrderNo(xhOrderNo, operatorId));
                etOrderMapping = orderMappingRepository.save(etOrderMapping);
            }
        }
        return etOrderMapping;
    }

}
