package com.xhpc.pp.logic;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.xhpc.common.api.dto.ChargingStationDto;
import com.xhpc.common.data.redis.CacheRateModel;
import com.xhpc.common.enums.StationDeviceEnum;
import com.xhpc.pp.domain.XhpcDeviceMessage;
import com.xhpc.pp.mapper.XhpcDeviceMessageMapper;
import com.xhpc.pp.tx.ServiceParameter;
import com.xhpc.pp.tx.ServiceResult;
import com.xhpc.pp.tx.logic.ServiceLogic;
import com.xhpc.pp.utils.HexUtils;
import com.xhpc.pp.utils.security.CRCCalculator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

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

import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;
import static com.xhpc.common.data.redis.StaticBeanUtil.seqHex;
import static com.xhpc.pp.utils.HexUtils.toHexInt;

@Lazy
@Component("RateModelRequestLogic")
public class RateModelRequestLogic implements ServiceLogic {

    private static final Logger log = LoggerFactory.getLogger(RateModelRequestLogic.class);

    @Resource
    XhpcDeviceMessageMapper deviceMessageMapper;

    @Override
    public ServiceResult service(ServiceParameter sp) throws Exception {

        Map<String, Object> req = sp.getParameters();
        String pileNo = (String) req.get("pileNo");
        Map<String, Object> cachePile = REDIS.getCacheMap("pile:".concat(pileNo));
        Long stationId = (Long) cachePile.get("stationId");
        ChargingStationDto cacheStation = REDIS.getCacheObject("station:".concat(stationId.toString()));
        Long stationRateModelId = cacheStation.getRateModelId();
        if (stationRateModelId == null) {
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode json = mapper.createObjectNode();
            json.put("error", "场站没有设置费率");
            return new ServiceResult(null, ServiceResult.FAIL, json);
        }
        String resultStr = translateYu(pileNo, stationRateModelId, "000A", (String) cachePile.get("version"),req);
        XhpcDeviceMessage deviceMessage = new XhpcDeviceMessage();
        deviceMessage.setType(StationDeviceEnum.PILE.getCode());
        deviceMessage.setSerialNumber(pileNo);
        deviceMessage.setRemark("充电桩计费模型请求");
        deviceMessage.setStatus(0);
        deviceMessage.setContent((String) req.get("hex"));
        deviceMessageMapper.insertByDomain(deviceMessage);

        return new ServiceResult(HexUtils.toBytes(resultStr), ServiceResult.OK);
    }

    public static String translate(String pileNo, Long stationRateModelId, String svc, String version) {

        CacheRateModel cacheRateModel = REDIS.getCacheObject("rateModel:".concat(stationRateModelId.toString()));
        String rateModel = translate(cacheRateModel);
        String skey = "pile:".concat(pileNo).concat(".seqhex");
        String resultStr;
//        if (!"0C".equals(version))
//            resultStr = "685E".concat(seqHex(skey)).concat(svc).concat(pileNo).concat(String.format("%04X",
//                    stationRateModelId)).concat(rateModel);
//        else
//            resultStr =
//                    "6860".concat(seqHex(skey)).concat(svc).concat(pileNo).concat(HexUtils.toHexInt(stationRateModelId)).concat(rateModel);
        if ("0F".equals(version)) {

            resultStr = "685E".concat(seqHex(skey)).concat(svc).concat(pileNo).concat(String.format("%04X",
                    stationRateModelId)).concat(rateModel);
        }else if("0C".equals(version)){
            resultStr =
                    "6860".concat(seqHex(skey)).concat(svc).concat(pileNo).concat(HexUtils.toHexInt(stationRateModelId)).concat(rateModel);
        }else{
            resultStr = "685E".concat(seqHex(skey)).concat(svc).concat(pileNo).concat(String.format("%04X",
                    stationRateModelId)).concat(rateModel);
        }
        resultStr = resultStr.concat(CRCCalculator.calcCrc(resultStr));
        return resultStr;
    }

    public static String translateYu(String pileNo, Long stationRateModelId, String svc, String version,Map<String, Object> req) {

        CacheRateModel cacheRateModel = REDIS.getCacheObject("rateModel:".concat(stationRateModelId.toString()));
        String rateModel = translate(cacheRateModel);
        String skey = "pile:".concat(pileNo).concat(".seqhex");
        String resultStr;
        if ("0F".equals(version)) {
            String seq1 =(String) req.get("hex");
            resultStr = "685E".concat(seq1.substring(4,8)).concat(svc).concat(pileNo).concat(String.format("%04X",
                    stationRateModelId)).concat(rateModel);
        }else if("0C".equals(version)){
            resultStr =
                    "6860".concat(seqHex(skey)).concat(svc).concat(pileNo).concat(HexUtils.toHexInt(stationRateModelId)).concat(rateModel);
        }else{
            String seq1 =(String) req.get("hex");
            resultStr = "685E".concat(seq1.substring(4,8)).concat(svc).concat(pileNo).concat(String.format("%04X",
                    stationRateModelId)).concat(rateModel);
        }
        resultStr = resultStr.concat(CRCCalculator.calcCrc(resultStr));
        return resultStr;
    }


    public static String translate(CacheRateModel cacheRateModel) {

        String rateModel = "";
        rateModel = rateModel.concat(toHexInt(cacheRateModel.getT1Price()))
                .concat(toHexInt(cacheRateModel.getT1SvcPrice()))
                .concat(toHexInt(cacheRateModel.getT2Price()))
                .concat(toHexInt(cacheRateModel.getT2SvcPrice()))
                .concat(toHexInt(cacheRateModel.getT3Price()))
                .concat(toHexInt(cacheRateModel.getT3SvcPrice()))
                .concat(toHexInt(cacheRateModel.getT4Price()))
                .concat(toHexInt(cacheRateModel.getT4SvcPrice()))
                .concat(String.format("%02X", cacheRateModel.getLossRate()))
                .concat(String.join("", cacheRateModel.getTfPricesSeq()));
        return rateModel;
    }


    public static void main(String[] args) {
        String format = String.format("%04X", 11419);
        System.out.println("==="+format);

        String format1 = String.format("%04X", 19);
        System.out.println("==="+format1);
    }
}
