package com.xhpc.evcs.api;

import com.xhpc.common.api.dto.ChargingStationDto;
import com.xhpc.common.domain.XhpcTerminal;
import com.xhpc.evcs.dto.CommonRequest;
import com.xhpc.evcs.dto.CommonResponse;
import com.xhpc.evcs.dto.ConnectorStatusInfo;
import com.xhpc.evcs.dto.StationStatusInfo;
import com.xhpc.evcs.dto.StationStatusInfoWrapper;
import com.xhpc.evcs.dto.StationStatusRequest;
import com.xhpc.evcs.encryption.EvcsConst;
import com.xhpc.evcs.jpa.XhpcTerminalRepository;
import com.xhpc.evcs.utils.JSONUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.hutool.core.util.NumberUtil.isInteger;
import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;

@RestController
public class QueryStationStatusController {

    @Resource
    XhpcTerminalRepository terminalRepository;

    /**
     * 设备接口状态查询
     * @param commonRequest
     * @return
     * @throws Exception
     */
    @PostMapping("/v1/query_station_status")
    public CommonResponse queryStationsInfo(@RequestBody CommonRequest<StationStatusRequest> commonRequest) throws Exception {

        CommonResponse resp = new CommonResponse();
        resp.setRet(EvcsConst.RET_FAIL);
        StationStatusRequest stationStatusRequest = JSONUtil.readParams(commonRequest.getData(), StationStatusRequest.class);
        if (stationStatusRequest == null) {
            resp.setMsg("Request or token params validation failed");
        } else {
            String[] stationIDs = stationStatusRequest.getStationIds();
            List<StationStatusInfo> stationStatusInfos = new ArrayList<>();
            //Loading data through redis at first.
            Collection<String> guns = REDIS.keys("gun:*");
            List<String> gunsNewList = new ArrayList<>();
            for (String value : guns) {
                gunsNewList.add(value.substring(4));
            }
            List<String> gunsIds = new ArrayList<>();
            for (String value : gunsNewList) {
                if (value.length() == 16) {
                    gunsIds.add(value);
                }
            }
            Map<String, Integer> statusMap = new HashMap<>();
            String[] keys = {"离线", "空闲", "故障"};
            Integer[] values = {0, 1, 255};
            for (int i = 0; i < keys.length; i++) {
                statusMap.put(keys[i], values[i]);
            }

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

            for (String stationID : stationIDs) {
                ChargingStationDto chargingStationDto = REDIS.getCacheObject("station:" + stationID);
                Set<String> pileIds = new HashSet<>();
                if (null != chargingStationDto) {
                    pileIds = chargingStationDto.getPiles();
                }
                boolean existsGun = false;
                List<ConnectorStatusInfo> connectorStatusInfos = new ArrayList<>();
                for (String pileId : pileIds) {
                    for (String value : gunsIds) {
                        if (pileId.equals(value.substring(0, 14))) {
                            existsGun = true;
                            ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
                            Integer gunStatus = terminalDBMap.get(value);
                            if (gunStatus == null){
                                existsGun = false;
                            } else {
                                if (gunStatus == 0){
                                    Object status = REDIS.getCacheMapValue("gun:" + value, "status");
                                    if (isInteger(status.toString())) {
                                        connectorStatusInfo.setStatus(3);
                                    } else {
                                        connectorStatusInfo.setStatus(statusMap.get(status));
                                    }
                                } else {
                                    connectorStatusInfo.setStatus(0);
                                }
                            }
                            connectorStatusInfo.setConnectorID(value);
                            connectorStatusInfos.add(connectorStatusInfo);
                        }
                    }
                }
                if (existsGun) {
                    StationStatusInfo stationStatusInfo = new StationStatusInfo();
                    stationStatusInfo.setStationID(stationID);
                    stationStatusInfo.setConnectorStatusInfos(connectorStatusInfos);
                    stationStatusInfos.add(stationStatusInfo);
                }
            }

            StationStatusInfoWrapper stationStatusInfoWrappers = new StationStatusInfoWrapper();
            stationStatusInfoWrappers.setTotal(stationStatusInfos.size());
            if (stationStatusInfos.size() != 0) {
                stationStatusInfoWrappers.setStationStatusInfos(stationStatusInfos);
            }
            resp.setRet("0");
            resp.setMsg("Query station status success");
            resp.setData(JSONUtil.toJSONString(stationStatusInfoWrappers));
        }
        return resp;
    }

}
