package com.xhpc.evcs.notification;

import com.xhpc.common.api.dto.ChargingStationDto;
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.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 java.io.IOException;
import java.time.Instant;
import java.util.*;

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;

    @Scheduled(fixedRate = 1000 * 45)
    protected void run() throws IOException {

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

        List<XhpcInternetUser> xhpcInternetUserList =
                xhpcInternetUserRepository.findByCooperationStartTimeBeforeAndCooperationEndTimeAfter(Instant.now(),
                        Instant.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);
            Set<ConnectorStatusInfo> changeStatus = ChangePoleStatus.getChangeStatus(connectorStatusInfos);
            if (!changeStatus.isEmpty()) {
                for (XhpcInternetUser xhpcInternetUser : xhpcInternetUserList) {
                    XhpcStationInternetBlacklist xhpcStationInternetBlacklist =
                            xhpcStationInternetBlacklistRepo.findByChargingStationIdAndInternetUserId(Long.valueOf(stationTerminalKey.split(":")[1]),
                                    xhpcInternetUser.getId()).orElse(null);
                    if (xhpcStationInternetBlacklist != null) continue;
                    AuthSecretToken authSecretTokenOut =
                            authSecretTokenRepository.findByOperatorId3irdptyAndSecretTokenType(xhpcInternetUser.getOperatorIdEvcs(), SECRET_TOKEN_TYPE_OUT).orElse(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) {

        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);
            connectorStatusInfo.setStatus(translateStatus(terminalStatusMap.get(gunId)));
            connectorStatusInfoList.add(connectorStatusInfo);
        }
        return connectorStatusInfoList;
    }

    private Integer translateStatus(String statusStr) {

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

    public void notify(ConnectorStatusInfo connectorStatusInfo, AuthSecretToken authSecretTokenOut) throws IOException {

        ConnectorStatusInfoReq connectorStatusInfoReq = new ConnectorStatusInfoReq();
        connectorStatusInfoReq.setConnectorStatusInfo(connectorStatusInfo);
        String data = JSONUtil.toJSONString(connectorStatusInfoReq);
        CommonRequest<ConnectorStatusInfoReq> commonRequest = new CommonRequest<>();
        commonRequest.setData(data);
        ok(commonRequest, "/notification_stationStatus", authSecretTokenOut);
    }

}
