package com.zsElectric.boot.charging.controller;

import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zsElectric.boot.charging.service.ChargingReceptionService;
import com.zsElectric.boot.common.annotation.ApiRateLimit;
import com.zsElectric.boot.common.annotation.Log;
import com.zsElectric.boot.common.constant.ConnectivityConstants;
import com.zsElectric.boot.common.enums.LogModuleEnum;
import com.zsElectric.boot.common.util.AESCryptoUtils;
import com.zsElectric.boot.common.util.HmacMD5Util;
import com.zsElectric.boot.common.util.electric.QueryTokenResponseData;
import com.zsElectric.boot.common.util.electric.RequestParmsEntity;
import com.zsElectric.boot.common.util.electric.ResponseParmsEntity;
import com.zsElectric.boot.common.util.electric.queryToken.JwtTokenUtil;
import com.zsElectric.boot.common.util.electric.queryToken.QueryTokenRequestParms;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequiredArgsConstructor
@Tag(name = "充电业务相关接口_第三方")
@RequestMapping("/charge-business/v1/linkData")
public class LinkDataController {

    private final ChargingReceptionService chargingReceptionService;

    private final JwtTokenUtil jwtTokenUtil;


//    @ApiRateLimit(
//            prefix = "third_party:query_token",  // Redis key前缀
//            limitType = ApiRateLimit.LimitType.IP,  // 限流类型：IP/GLOBAL/USER
//            count = 200,  // 时间窗口内允许的最大请求次数
//            time = 60,    // 时间窗口大小（秒）
//            message = "获取Token请求过于频繁，请稍后再试"  // 限流提示信息
//    )

    /**
     *  获取Token
     *  Token作为全局唯一凭证,调用各接口时均需要使用,该接口作为双方获取Token的接口,双方均需要实现。
     * @author wzq
     * @param request，参数为类则包含{@link RequestParmsEntity}
     * @return ResponseParmsEntity{@link ResponseParmsEntity}
     */
    @Operation(summary = "获取token")
    @PostMapping("/query_token")
    @Log(value = "获取token", module = LogModuleEnum.PARKING, params = true, result = true)
    @ApiRateLimit(prefix = "third_party:query_token", limitType = ApiRateLimit.LimitType.IP, count = 200, time = 60, message = "获取Token请求过于频繁，请稍后再试")
    public ResponseParmsEntity getToken(@RequestBody RequestParmsEntity request) throws Exception {
        ResponseParmsEntity responseParmsEntity = new ResponseParmsEntity();
        try {
            //验证签名
            if (!HmacMD5Util.verify(request.getOperatorID() + request.getData() + request.getTimeStamp() + request.getSeq(),
                    ConnectivityConstants.SIG_SECRET, request.getSig())) {
                 responseParmsEntity.setRet(4001);
                responseParmsEntity.setMsg("签名验证失败");
                responseParmsEntity.setData("");
                responseParmsEntity.setSig(HmacMD5Util.genSign(responseParmsEntity.getRet(), responseParmsEntity.getMsg(), responseParmsEntity.getData(),
                                ConnectivityConstants.SIG_SECRET));
                return responseParmsEntity;
            }

            String data = request.getData();
            String string = AESCryptoUtils.decrypt(data, ConnectivityConstants.DATA_SECRET, ConnectivityConstants.DATA_SECRET_IV);
            ObjectMapper objectMapper = new ObjectMapper();
            QueryTokenRequestParms queryTokenRequestParms = objectMapper.readValue(string, QueryTokenRequestParms.class);
            if (queryTokenRequestParms == null || queryTokenRequestParms.getOperatorID() == null || queryTokenRequestParms.getOperatorSecret() == null) {

                responseParmsEntity.setRet(4003);
                responseParmsEntity.setMsg("参数错误");
                responseParmsEntity.setData("");
                responseParmsEntity.setSig(HmacMD5Util.genSign(responseParmsEntity.getRet(), responseParmsEntity.getMsg(), responseParmsEntity.getData(),
                        ConnectivityConstants.SIG_SECRET));
                return responseParmsEntity;
            }

            //判断运营商ID与密钥是否正确
            if (!queryTokenRequestParms.getOperatorID().equals(ConnectivityConstants.PLATFORM_OPERATOR_ID) && !queryTokenRequestParms.getOperatorSecret().equals(ConnectivityConstants.PLATFORM_OPERATOR_SECRET)) {
                responseParmsEntity .setRet(4004);
                responseParmsEntity.setMsg("OperatorID或OperatorSecret错误！");
                responseParmsEntity .setData("");
                responseParmsEntity.setSig(HmacMD5Util.genSign(responseParmsEntity.getRet(), responseParmsEntity.getMsg(), responseParmsEntity.getData(),
                        ConnectivityConstants.SIG_SECRET));
            }

            //redis获取token,不存在则创建
            String accessToken = jwtTokenUtil.generateToken(queryTokenRequestParms.getOperatorID());
            Integer remainingTTL = jwtTokenUtil.getRemainingTTL(accessToken).intValue();
            //构建Data(token信息)
            QueryTokenResponseData queryTokenResponseData = new QueryTokenResponseData();
            queryTokenResponseData.setOperatorID(queryTokenRequestParms.getOperatorID());
            queryTokenResponseData.setAccessToken(accessToken);
            queryTokenResponseData.setTokenAvailableTime(remainingTTL);
            queryTokenResponseData.setSuccStat(0);
            queryTokenResponseData.setFailReason(0);

            log.info("生成token信息:{}", objectMapper.writeValueAsString(queryTokenResponseData));

            String encodeData = AESCryptoUtils.encrypt(objectMapper.writeValueAsString(queryTokenResponseData), ConnectivityConstants.DATA_SECRET,
                    ConnectivityConstants.DATA_SECRET_IV);

            responseParmsEntity.setRet(0);
            responseParmsEntity.setMsg("成功");
            responseParmsEntity .setData(encodeData);
            responseParmsEntity.setSig(HmacMD5Util.genSign(responseParmsEntity.getRet(), responseParmsEntity.getMsg(), responseParmsEntity.getData(),
                            ConnectivityConstants.SIG_SECRET));
            return responseParmsEntity;
        } catch (Exception e) {
            log.error("系统错误:{}", e.getMessage());
            responseParmsEntity .setRet(500);
            responseParmsEntity.setMsg("系统错误");
            responseParmsEntity.setData("");
            responseParmsEntity.setSig(HmacMD5Util.genSign(responseParmsEntity.getRet(), responseParmsEntity.getMsg(), responseParmsEntity.getData(),
                    ConnectivityConstants.SIG_SECRET));
            return responseParmsEntity;
        }
    }


    /**
     * <p>2.4 推送启动充电结果</p>
     * @author SheepHy
     * @param requestDTO，参数为类则包含{@link RequestParmsEntity}
     * @return 推送启动充电结果VO
     */
    @Operation(summary = "推送启动充电结果")
    @PostMapping("/notification_start_charge_result")
    @Log(value = "推送启动充电结果", module = LogModuleEnum.PARKING, params = true, result = true)
    @ApiRateLimit(prefix = "third_party:start_charge", limitType = ApiRateLimit.LimitType.IP, count = 300, time = 60, message = "启动充电请求过于频繁，请稍后再试")
    public ResponseParmsEntity chargeResponse(@RequestBody RequestParmsEntity requestDTO){
        return chargingReceptionService.chargeResponse(requestDTO);
    }

    /**
     * 2.6 推送充电状态
     * */
    @Operation(summary = "推送充电状态")
    @PostMapping("/notification_equip_charge_status")
    @Log(value = "推送充电状态", module = LogModuleEnum.PARKING, params = true, result = true)
    @ApiRateLimit(prefix = "third_party:charge_status", limitType = ApiRateLimit.LimitType.IP, count = 500, time = 60, message = "充电状态推送过于频繁，请稍后再试")
    public ResponseParmsEntity chargeStatusResponse(@RequestBody RequestParmsEntity requestDTO){
        return chargingReceptionService.chargeStatusResponse(requestDTO);
    }

    /**
     * 2.8 推送停止充电结果
     * */
    @Operation(summary = "推送停止充电结果")
    @PostMapping("/notification_stop_charge_result")
    @Log(value = "推送停止充电结果", module = LogModuleEnum.PARKING, params = true, result = true)
    @ApiRateLimit(prefix = "third_party:stop_charge", limitType = ApiRateLimit.LimitType.IP, count = 300, time = 60, message = "停止充电请求过于频繁，请稍后再试")
    public ResponseParmsEntity stopChargeResponse(@RequestBody RequestParmsEntity requestDTO){
        return chargingReceptionService.stopChargeResponse(requestDTO);
    }

    /**
     * 2.9 推送充电订单信息
     * */
    @Operation(summary = "推送充电订单信息")
    @PostMapping("/notification_charge_order_info")
    @Log(value = "推送充电订单信息", module = LogModuleEnum.PARKING, params = true, result = true)
    @ApiRateLimit(prefix = "third_party:charge_order", limitType = ApiRateLimit.LimitType.IP, count = 200, time = 60, message = "订单信息推送过于频繁，请稍后再试")
    public ResponseParmsEntity chargeOrderResponse(@RequestBody RequestParmsEntity requestDTO){
        return chargingReceptionService.chargeOrderResponse(requestDTO);
    }

    /**
     * 3.2 设备状态变化推送
     * @param requestDTO
     * @return
     */
    @Operation(summary = "设备状态变化推送")
    @PostMapping("/notification_stationStatus")
    @Log(value = "设备状态变化推送", module = LogModuleEnum.PARKING, params = true, result = true)
    @ApiRateLimit(prefix = "third_party:station_status", limitType = ApiRateLimit.LimitType.IP, count = 500, time = 60, message = "设备状态推送过于频繁，请稍后再试")
    public ResponseParmsEntity stationStatus(@RequestBody RequestParmsEntity requestDTO){
        return chargingReceptionService.stationStatus(requestDTO);
    }
}
