package com.xhpc.evcs.notification;

import com.xhpc.common.api.dto.ChargingStationDto;
import com.xhpc.common.domain.XhpcTerminal;
import com.xhpc.evcs.domain.AuthSecretToken;
import com.xhpc.evcs.domain.XhpcInternetUser;
import com.xhpc.evcs.domain.XhpcStationInternetBlacklist;
import com.xhpc.evcs.dto.CommonRequest;
import com.xhpc.evcs.dto.ConnectorStatusInfo;
import com.xhpc.evcs.dto.ConnectorStatusInfoReq;
import com.xhpc.evcs.jpa.AuthSecretTokenRepository;
import com.xhpc.evcs.jpa.XhpcInternetUserRepository;
import com.xhpc.evcs.jpa.XhpcStationInternetBlacklistRepository;
import com.xhpc.evcs.jpa.XhpcTerminalRepository;
import com.xhpc.evcs.utils.ChangePoleStatus;
import com.xhpc.evcs.utils.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.Instant;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

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

@Component
@Slf4j
public class NotificationStationStatusTask extends CoreDispatcher {

    @Autowired
    private AuthSecretTokenRepository authSecretTokenRepository;
    @Autowired
    private XhpcInternetUserRepository xhpcInternetUserRepository;
    @Autowired
    private XhpcStationInternetBlacklistRepository xhpcStationInternetBlacklistRepo;
    @Resource
    private XhpcTerminalRepository terminalRepository;

    //都开放
    @Scheduled(cron = "0/30 * * * * ? ")
    protected void run() throws IOException {

        Collection<String> stationTerminalKeys = REDIS.keys("stationTerminalStatus:*");

        List<XhpcTerminal> terminalList = terminalRepository.selectStatusBySql();
        Map<String,Integer> terminalDBMap = terminalList.stream().collect(Collectors.toMap(XhpcTerminal::getSerialNumber,XhpcTerminal::getStatus));

        Instant now = Instant.now();
        List<XhpcInternetUser> xhpcInternetUserList =
                xhpcInternetUserRepository.findByCooperationStartTimeBeforeAndCooperationEndTimeAfter(now, now);
        for (String stationTerminalKey : stationTerminalKeys) {
            ChargingStationDto chargingStationDto = REDIS.getCacheObject(stationTerminalKey.replace("stationTerminalStatus",
                    "station"));
            String operatorId = chargingStationDto.getOperatorId();
            Map<String, String> terminalStatusMap = REDIS.getCacheMap(stationTerminalKey);
            Set<ConnectorStatusInfo> connectorStatusInfos = translateStatus(operatorId, terminalStatusMap, terminalDBMap);
            Set<ConnectorStatusInfo> changeStatus = ChangePoleStatus.getChangeStatus(connectorStatusInfos);
            if (!changeStatus.isEmpty()) {
                for (XhpcInternetUser xhpcInternetUser : xhpcInternetUserList) {
                    //车为家单独推送
                    if("5".equals(xhpcInternetUser.getInternetUserId().toString()) || "6".equals(xhpcInternetUser.getInternetUserId().toString())|| "7".equals(xhpcInternetUser.getInternetUserId().toString())){
                        continue;
                    }
                    XhpcStationInternetBlacklist xhpcStationInternetBlacklist =
                            xhpcStationInternetBlacklistRepo.findByChargingStationIdAndInternetUserId(Long.valueOf(stationTerminalKey.split(":")[1]),
                                    xhpcInternetUser.getInternetUserId()).orElse(null);
                    if (xhpcStationInternetBlacklist != null) continue;

                    AuthSecretToken authSecretTokenOut =
                            authSecretTokenRepository.findByOperatorId3irdptyAndSecretTokenType(xhpcInternetUser.getOperatorIdEvcs(), SECRET_TOKEN_TYPE_OUT).orElse(null);
                    if(authSecretTokenOut !=null){
                        log.debug("nss pushing to: {}", authSecretTokenOut.getOperatorId3irdpty());
                        if (authSecretTokenOut != null) {
                            for (ConnectorStatusInfo statusInfo : changeStatus) {
                                notify(statusInfo, authSecretTokenOut);
                            }
                        }
                    }
                }
            }
        }
    }

    private Set<ConnectorStatusInfo> translateStatus(String operatorId, Map<String, String> terminalStatusMap, Map<String, Integer> terminalDBMap) {

        Set<ConnectorStatusInfo> connectorStatusInfoList = new HashSet<>();
        final Set<String> connectorIds = terminalStatusMap.keySet();
        for (String gunId : connectorIds) {
            ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
            connectorStatusInfo.setConnectorID(gunId);
            connectorStatusInfo.setOperatorID(operatorId);
            Integer dbStatus = terminalDBMap.get(gunId);
            if(dbStatus !=null && dbStatus == 0){
                connectorStatusInfo.setStatus(translateStatus(terminalStatusMap.get(gunId)));
            } else {
                connectorStatusInfo.setStatus(0);
            }
            connectorStatusInfoList.add(connectorStatusInfo);
        }
        return connectorStatusInfoList;
    }

    private Integer translateStatus(String statusStr) {

        switch (statusStr) {
            case "空闲":
                return FREE;
            case "离线":
                return OFF_LINE;
            case "插枪":
                return CONNECTED;
            case "故障":
                return ERROR;
            default:
                return CHARGING;
        }
    }

    public void notify(ConnectorStatusInfo connectorStatusInfo, AuthSecretToken authSecretTokenOut) throws IOException {
        try{
            ConnectorStatusInfoReq connectorStatusInfoReq = new ConnectorStatusInfoReq();
            connectorStatusInfoReq.setConnectorStatusInfo(connectorStatusInfo);
            String data = JSONUtil.toJSONString(connectorStatusInfoReq);
            CommonRequest<ConnectorStatusInfoReq> commonRequest = new CommonRequest<>();
            commonRequest.setData(data);
            String ok = ok(commonRequest, "/notification_stationStatus", authSecretTokenOut);
        }catch (Exception e){

        }

    }

}
