package com.xhpc.evcs.ykc.api;

/**
 * 云快充
 *
 * @author yuyang
 * @Date 2026-03-17 13:42
 */

import com.fasterxml.jackson.core.JsonProcessingException;
import com.xhpc.common.api.PowerPileService;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.data.redis.CacheOrderData;
import com.xhpc.evcs.api.QueryStopChargeController;
import com.xhpc.evcs.domain.AuthSecretToken;
import com.xhpc.evcs.domain.EtOrderMapping;
import com.xhpc.evcs.domain.XhpcChargingPile;
import com.xhpc.evcs.dto.*;
import com.xhpc.evcs.encryption.EvcsConst;
import com.xhpc.evcs.jpa.AuthSecretTokenRepository;
import com.xhpc.evcs.jpa.OrderMappingRepository;
import com.xhpc.evcs.jpa.XhpcChargingPileRepository;
import com.xhpc.evcs.notification.CoreDispatcher;
import com.xhpc.evcs.utils.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

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

@Slf4j
@RestController
public class YKCQueryStopChargeController extends CoreDispatcher {
    @Autowired
    PowerPileService powerPileService;
    //三方订单与redis内部订单映射表
    @Autowired
    private OrderMappingRepository etOrderMappingRepo;
    @Autowired
    private com.xhpc.evcs.jpa.XhpcChargingPileRepository XhpcChargingPileRepository;
    @Autowired
    AuthSecretTokenRepository authSecretTokenRepository;

    private final Logger logger = LoggerFactory.getLogger(QueryStopChargeController.class);
    private final ExecutorService asyncExecutor = Executors.newFixedThreadPool(40);
    /**
     * 请求停止充电
     * @param commonRequest
     * @return
     * @throws IOException
     */
    @PostMapping("/v50/query_stop_charge")
    public CommonResponse queryStopCharge(@RequestBody CommonRequest<QueryStopChargeRequest> commonRequest) throws IOException {

        CommonResponse commonResponse = new CommonResponse();
        commonResponse.setRet(EvcsConst.RET_FAIL);
        QueryStopChargeRequest queryStopChargeRequest = JSONUtil.readParams(commonRequest.getData(),
                QueryStopChargeRequest.class);
        String orderNo="";
        if (queryStopChargeRequest == null) {

            commonResponse.setMsg("Request or token params validation failed");
        } else {
            // evcs电订单号(27位)
            String startChargeSeq = queryStopChargeRequest.getStartChargeSeq();
            QueryStopChargeResponse queryStopChargeResponse = new QueryStopChargeResponse();
            queryStopChargeResponse.setStartChargeSeq(startChargeSeq);
            //判断三方的订单号是否存在
            EtOrderMapping etOrderMapping = etOrderMappingRepo.findByEvcsOrderNo(startChargeSeq).orElse(null);
            if (etOrderMapping == null) {
                return failCommonResponse(queryStopChargeResponse, "错误的充电订单号");
            }
            String xhOrderNo = etOrderMapping.getXhOrderNo();
            orderNo = xhOrderNo;
            String pushOrderkey = "pushOrder:".concat(xhOrderNo);
            Map<String, Object> pushOrder = REDIS.getCacheMap(pushOrderkey);
            if (pushOrder == null || (pushOrder.get("isStopNotified") != null && (Boolean) pushOrder.get("isStopNotified"))) {
                return failCommonResponse(queryStopChargeResponse, "已下发停止充电指令");
            }
            //充电设备接口编码（枪编码）
            String connectorId = queryStopChargeRequest.getConnectorId();
            String pileNum = connectorId.substring(0, connectorId.length() - 2);
            //从数据库中查询对应的桩的版本信息
            XhpcChargingPile pileInfo = XhpcChargingPileRepository.findBySerialNumber(pileNum).orElse(null);
            String versionNum = pileInfo.getCommunicationProtocolVersion() != null ?
                    pileInfo.getCommunicationProtocolVersion() :
                    "0C";
            //给对应的枪发送停止充电指令

            R r = powerPileService.stopCharging(xhOrderNo, pileNum, connectorId, versionNum);
            // 判断停止指令发送是否成功
            if (r.getCode() != 200) {
                //向redis中放入停止充电指令没有下发成功的标识
                REDIS.setCacheMap(pushOrderkey, pushOrder);
                //充电订单状态
                queryStopChargeResponse.setStartChargeSeqStat(5);
                //操作结果
                queryStopChargeResponse.setSuccStat(1);
                //失败原因
                String errorMsg = r.getMsg();
                if (errorMsg.contains("未注册")) {
                    queryStopChargeResponse.setFailReason(1);
                }
                if (errorMsg.contains("离线")) {
                    queryStopChargeResponse.setFailReason(2);
                }
                if (errorMsg.contains("订单号")) {
                    //4 means error orderNumber
                    queryStopChargeResponse.setFailReason(4);
                }
                if (errorMsg.contains("端口")) {
                    //5 means port is not charging
                    queryStopChargeResponse.setFailReason(5);
                }
                queryStopChargeResponse.setStartChargeSeqStat(4);
                queryStopChargeResponse.setSuccStat(1);
                String data = JSONUtil.toJSONString(queryStopChargeResponse);
                commonResponse.setMsg("请求停止充电失败");
                commonResponse.setData(data);
                return commonResponse;
            }
            //设置该订单已经被停止的标识
            Map<String, Object> order = REDIS.getCacheMap("order:" + xhOrderNo);
            order.replace("status", "已结束");
            REDIS.setCacheMap("order:".concat(xhOrderNo), order);
            REDIS.setCacheMap(pushOrderkey, pushOrder);
            queryStopChargeResponse.setStartChargeSeqStat(4);
            queryStopChargeResponse.setSuccStat(0);
            queryStopChargeResponse.setFailReason(0);
            String data = JSONUtil.toJSONString(queryStopChargeResponse);
            System.out.println("=====请求停止充电==query_stop_charge========="+data);
            commonResponse.setRet("0");
            commonResponse.setMsg("请求停止充电成功");
            commonResponse.setData(data);
        }

//        if("0".equals(commonResponse.getRet())){
//            String finalOrderNo = orderNo;
//            CompletableFuture.runAsync(()->{
//                processRequest(finalOrderNo);
//            },asyncExecutor);
//        }
//        System.out.println(">>> 回复停止结果 <<<");

        return commonResponse;
    }

    private CommonResponse failCommonResponse(QueryStopChargeResponse queryStopChargeResponse, String msg) throws JsonProcessingException {

        queryStopChargeResponse.setStartChargeSeqStat(5);
        queryStopChargeResponse.setSuccStat(1);
        queryStopChargeResponse.setFailReason(0);
        String data = JSONUtil.toJSONString(queryStopChargeResponse);
        CommonResponse commonResponse = new CommonResponse();
        commonResponse.setRet("500");
        commonResponse.setMsg(msg);
        commonResponse.setData(data);
        return commonResponse;
    }


    @Async
    public void processRequest(String orderNo){
        System.out.println(">>> 开始执行后续操作 <<<");
        try{
            //推送停止成功数据
            String pushOrderKey ="pushOrder:"+orderNo;
            String orderkey = "order:".concat(orderNo);
            CacheOrderData orderData = REDIS.getCacheMapValue(orderkey, "orderData");
            Map<String, Object> pushOrder = REDIS.getCacheMap(pushOrderKey);
            if (orderData != null || (pushOrder != null && pushOrder.get("startChargeSeqStat") != null && (Integer) pushOrder.get("startChargeSeqStat") > 3)) {
                Boolean isStopNotified = (Boolean) pushOrder.get("isStopNotified");
                if (isStopNotified == null || !isStopNotified) {
                    String internetSerialNumber = (String) pushOrder.get("internetSerialNumber");
                    if (internetSerialNumber != null) {
                        String operatorId3rdpty = internetSerialNumber.substring(0, 9);
                        AuthSecretToken authSecretTokenOut =authSecretTokenRepository.findByOperatorId3irdptyAndSecretTokenType(operatorId3rdpty,SECRET_TOKEN_TYPE_OUT).orElse(null);
                        CommonRequest<ChargeResultRequest> commonRequest = new CommonRequest<>();
                        ChargeResultRequest chargeResultRequest = new ChargeResultRequest();
                        chargeResultRequest.setStartChargeSeq(internetSerialNumber);
                        //使用指定包装类封装数据
                        chargeResultRequest.setConnectorID(orderkey.substring(0, 16));
                        chargeResultRequest.setStartChargeSeqStat(4);
                        chargeResultRequest.setSuccStat(0);
                        chargeResultRequest.setFailReason(0);
                        //将其转换为json
                        String jsonData = JSONUtil.toJSONString(chargeResultRequest);
                        commonRequest.setData(jsonData);
                        String result = ok(commonRequest, "/notification_stop_charge_result", authSecretTokenOut);
                        System.out.println("===充电结束=停止推送结果=======notification_stop_charge_result========="+result+"============orderNo========"+orderNo);
                        pushOrder.put("isStopNotified", true);
                        REDIS.setCacheMap(pushOrderKey, pushOrder);
                    }
                }
            }
        }catch (Exception e){
            logger.info("==========第三方调用停止充电接口=====停止推送失败=====responseBody=======================");
        }
    }
}
