package com.xhpc.evcs.cdjgpc.api;

import com.xhpc.common.api.PileOrderService;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.core.utils.DateUtils;
import com.xhpc.evcs.domain.EtOrderMapping;
import com.xhpc.evcs.domain.XhpcChargingStation;
import com.xhpc.evcs.dto.CommonRequest;
import com.xhpc.evcs.dto.CommonResponse;
import com.xhpc.evcs.dto.StartChargeRequest;
import com.xhpc.evcs.dto.StartChargeResponse;
import com.xhpc.evcs.encryption.EvcsConst;
import com.xhpc.evcs.jpa.*;
import com.xhpc.evcs.utils.JSONUtil;
import com.xhpc.order.domain.XhpcHistoryOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;
import static com.xhpc.common.data.redis.StaticBeanUtil.genOrder;

/**
 * @author yuyang
 * @date 2023-09-20 15:38
 */
public class CDQueryStartChargeController {

    @Resource
    AuthSecretTokenRepository authSecretTokenRepository;
    @Resource
    private OrderMappingRepository etOrderMappingRepo;
    @Resource
    private XhpcHistoryOrderRepository xhpcHistoryOrderRepository;
    @Resource
    private XhpcTerminalRepository xhpcTerminalRepository;
    @Resource
    private PileOrderService pileOrderService;
    @Resource
    private XhpcInternetUserRepository xhpcInternetUserRepository;
    @Resource
    private XhpcChargingStationRepository xhpcChargingStationRepository;

    /**
     * 请求启动充电
     * @param commonRequest
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/v10/query_start_charge")
    public CommonResponse queryStartCharge(@RequestBody CommonRequest<StartChargeRequest> commonRequest) throws Exception {

        CommonResponse resp = new CommonResponse();
        resp.setRet(EvcsConst.RET_FAIL);
        StartChargeRequest startChargeRequest = JSONUtil.readParams(commonRequest.getData(), StartChargeRequest.class);
        if (startChargeRequest == null) {
            resp.setMsg("Request or token params validation failed");
        } else {
            String startChargeSeq = startChargeRequest.getStartChargeSeq();
            EtOrderMapping orderMapping = etOrderMappingRepo.findByEvcsOrderNo(startChargeSeq).orElse(null);
            if (orderMapping != null) {
                resp.setMsg("Duplicated StartChargeSeq");
            } else {
                StartChargeResponse startChargeResponse = new StartChargeResponse();
                startChargeResponse.setFailReason(0);
                startChargeResponse.setSuccStat(1);
                startChargeResponse.setStartChargeSeqStat(4);
                String connectorId = startChargeRequest.getConnectorId();
                Map<String, Object> cacheGun = REDIS.getCacheMap("gun:".concat(connectorId));
                String terminalStatus = (String) cacheGun.get("vehicleGunStatus");
                String status = (String) cacheGun.get("status");
                EtOrderMapping etOrderMapping = new EtOrderMapping();
                Date now = DateUtils.getNowDate();
                etOrderMapping.setCreateTime(now);
                etOrderMapping.setEvcsOrderNo(startChargeSeq);
                if (!"空闲".equals(status)) {
                    resp.setMsg("终端状态异常:[".concat(status == null ? "未注册" : status).concat("]"));
                    emptyHorder(startChargeSeq, connectorId, etOrderMapping);
                } else if ("否".equals(terminalStatus)) {
                    resp.setMsg("未插枪");
                    emptyHorder(startChargeSeq, connectorId, etOrderMapping);
                } else {
                    String plateNum = startChargeRequest.getPlateNum();
                    plateNum = plateNum == null ? startChargeRequest.getPlateNum2() : plateNum;
                    R res = pileOrderService.pileStartUpBy3rd(startChargeSeq, startChargeRequest.getDriverId(),
                            startChargeRequest.getChargingAmt(), plateNum, -1, connectorId);
                    startChargeResponse.setStartChargeSeq(startChargeSeq);
                    startChargeResponse.setConnectorID(connectorId);
                    resp.setMsg(res.getMsg());
                    if (res.getCode() != 200) {
                        if (res.getCode() != 500) {
                            startChargeResponse.setFailReason(res.getCode());
                        } else {
                            startChargeResponse.setFailReason(3);
                        }
                        startChargeResponse.setFailReasonMsg(res.getMsg());
                        startChargeResponse.setSuccStat(1);
                        startChargeResponse.setStartChargeSeqStat(4);
                        emptyHorder(startChargeSeq, connectorId, etOrderMapping);
                    } else {
                        Map<String, Object> etOrderData = (Map<String, Object>) res.getData();
                        if (etOrderData != null) {
                            resp.setRet(EvcsConst.RET_SUCC);
                            startChargeResponse.setStartChargeSeqStat(1);
                            startChargeResponse.setSuccStat(0);
                            startChargeResponse.setFailReason(0);
                            Map<String, Object> pushOrder = new HashMap<>();
                            pushOrder.put("startChargeSeqStat", 1);
                            pushOrder.put("internetSerialNumber", startChargeRequest.getStartChargeSeq());
                            pushOrder.put("connectorID", connectorId);
                            pushOrder.put("startChargeNotificationStat", 0);
                            pushOrder.put("chargeOrderInfoNotificationStat", 0);
                            pushOrder.put("operatorId3rdpty", startChargeSeq.substring(0, 9));
                            pushOrder.put("startTime", etOrderData.get("startTime"));
                            String orderNo = (String) etOrderData.get("orderNo");
                            etOrderMapping.setXhOrderNo(orderNo);
                            REDIS.setCacheMap("pushOrder:".concat(orderNo), pushOrder);
                        } else {
                            emptyHorder(startChargeSeq, connectorId, etOrderMapping);
                        }
                    }
                }
                etOrderMappingRepo.save(etOrderMapping);
                resp.setData(JSONUtil.toJSONString(startChargeResponse));
            }
        }
        return resp;
    }

    private void emptyHorder(String startChargeSeq, String connectorId, EtOrderMapping etOrderMapping) {

        final Long stationId = REDIS.getCacheMapValue("pile:".concat(connectorId.substring(0, 14)), "stationId");
        XhpcChargingStation xhpcChargingStation = xhpcChargingStationRepository.findById(stationId).orElse(null);
        if (xhpcChargingStation != null) {
            XhpcHistoryOrder emptyHorder = new XhpcHistoryOrder();
            emptyHorder.setTenantId(xhpcChargingStation.getTenantId());
            Date now = DateUtils.getNowDate();
            emptyHorder.setStartTime(now);
            emptyHorder.setEndTime(now);
            emptyHorder.setCreateTime(now);
            emptyHorder.setUpdateTime(now);
            emptyHorder.setStopReasonEvcs("平台停止");
            String sn = genOrder(connectorId);
            etOrderMapping.setXhOrderNo(sn);
            emptyHorder.setSerialNumber(sn);
            emptyHorder.setInternetSerialNumber(startChargeSeq);
            String operatorId3rdpty = startChargeSeq.substring(0, 9);
            emptyHorder.setOperatorId3rdptyEvcs(operatorId3rdpty);
            emptyHorder.setUserId(xhpcInternetUserRepository.queryDbId(operatorId3rdpty));
            emptyHorder.setType(1);
            emptyHorder.setSource(1);
            emptyHorder.setState(-1);
            emptyHorder.setChargingStationId(stationId);
            emptyHorder.setTerminalId(xhpcTerminalRepository.queryDbId(connectorId));
            emptyHorder.setConfirmResult(-1);
            xhpcHistoryOrderRepository.save(emptyHorder);
        }
    }
}
