package com.jsowell.common.util;

import com.google.common.primitives.Bytes;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.Arrays;

@Slf4j
public class YKCUtils {

	private static final BigDecimal multiple = new BigDecimal("100000");

	/**
	 * 校验云快充请求数据格式
	 *
	 * @param msg 请求报文
	 * @return
	 */
	public static boolean checkMsg(byte[] msg) {
		// 起始标志
		byte[] head = BytesUtil.copyBytes(msg, 0, 1);
		// 数据长度
		byte[] length = BytesUtil.copyBytes(msg, 1, 1);
		// 序列号域
		byte[] serialNumber = BytesUtil.copyBytes(msg, 2, 2);
		// 加密标志
		byte[] encryptFlag = BytesUtil.copyBytes(msg, 4, 1);
		// 帧类型标志
		byte[] frameType = BytesUtil.copyBytes(msg, 5, 1);
		// 消息体
		byte[] msgBody = BytesUtil.copyBytes(msg, 6, msg.length - 8);
		// 帧校验域
		byte[] crcByte = new byte[]{msg[msg.length - 2], msg[msg.length - 1]};

		//起始位必须是0x68
		if (0x68 != head[0]) {
			log.error("起始位必须是0x68");
			return false;
		}
		// 序列号域+加密标志+帧类型标志+消息体
		byte[] data = Bytes.concat(serialNumber, encryptFlag, frameType, msgBody);
		// 校验长度
		if (data.length != BytesUtil.bytesToIntLittle(length)) {
			log.error("数据长度不正确");
			return false;
		}
		// CRC校验 source target
		String sourceCRC = String.format("%04x", BytesUtil.bytesToInt(crcByte, 0));
		String targetCRC = String.format("%04x", CRC16Util.calcCrc16(data));
		String oldTargetCRC = String.format("%04x", CRC16Util.calcCrc16Old(data));
		if (!sourceCRC.equalsIgnoreCase(targetCRC)) {
			log.error("CRC校验不通过, 源crc:{}, 计算得出crc:{}, 老crc计算:{}, 帧类型:{}, 报文：{}, msg:{}"
					, sourceCRC, targetCRC, oldTargetCRC, YKCUtils.frameType2Str(frameType), BytesUtil.binary(msg, 16), Arrays.toString(msg));
			return false;
		}
		return true;
	}

	/**
	 * 转换电压电流以及起始soc
	 * 精确到小数点后一位；待机置零
	 *
	 * @param bytes
	 * @return
	 */
	public static String convertVoltageCurrent(byte[] bytes) {
		// 转换为int 最后一位是小数位
		int i = BytesUtil.bytesToIntLittle(bytes);
		// 使用BigDecimal
		BigDecimal bigDecimal = new BigDecimal(i);
		BigDecimal divide = bigDecimal.divide(new BigDecimal(10), 1, BigDecimal.ROUND_UP);
		return divide.toString();
	}

	/**
	 * 转换小数点
	 *
	 * @param bytes
	 * @param scale 小数位
	 * @return
	 */
	public static String convertDecimalPoint(byte[] bytes, int scale) {
		// 转换为int 
		int i = BytesUtil.bytesToIntLittle(bytes);
		// 使用BigDecimal
		BigDecimal bigDecimal = new BigDecimal(i);
		BigDecimal divide = bigDecimal.divide(BigDecimal.valueOf(Math.pow(10d, scale)), scale, BigDecimal.ROUND_UP);
		return divide.toString();
	}

	/**
	 * 获取价格byte数组
	 * 价格转换为byte数组
	 * @param price 实际价格，单位元
	 * @param scale 保留小数位
	 * @return
	 */
	public static byte[] getPriceByte(String price, int scale) {
		// 保留小数位 例:保留5位小数，需要乘以10的5次方
		BigDecimal value = BigDecimal.valueOf(Math.pow(10d, scale));
		int i = new BigDecimal(price).multiply(value).intValue();
		return BytesUtil.intToBytesLittle(i, 4);
	}

	/**
	 * byte转帧类型字符串
	 * @param bytes
	 * @return
	 */
	public static String frameType2Str(byte[] bytes) {
		String s = BytesUtil.bin2HexStr(bytes);
		return "0x" + s;
	}

	public static void main(String[] args) {
		// String hexString = "681E0000003388000000000027012302081602434533880000000000270101008361";
		// byte[] byteArray = new byte[hexString.length() / 2];
		// for (int i = 0; i < byteArray.length; i++) {
		// 	int index = i * 2;
		// 	int j = Integer.parseInt(hexString.substring(index, index + 2), 16);
		// 	byteArray[i] = (byte) j;
		// }
		// System.out.println(byteArray);
		// String binary = BytesUtil.binary(byteArray, 16);
		// String aaa = DatatypeConverter.printHexBinary(byteArray);
		// System.out.println(binary);
		// System.out.println(aaa);

		String hexString = "4f";
		byte[] bytes = new byte[]{0x4f};

		String s = transitionTemperature(bytes);
		System.out.println(s);

		byte[] bytess = new byte[]{(byte) 0x80, (byte) 0x1A, 0x06, 0x00};
		String s1 = convertDecimalPoint(bytess, 5);
		System.out.println(s1);

		String amount = "1000";
		byte[] priceByte = getPriceByte(amount, 2);
		System.out.println(BytesUtil.bin2HexStr(priceByte));
	}

	/**
	 * 转换温度
	 * BIN 码	1	整形，偏移量-50；待机置零
	 */
	public static String transitionTemperature(byte[] bytes) {
		String s = BytesUtil.binary(bytes, 10);
		int i = Integer.parseInt(s);
		if (i > 0) {
			return String.valueOf(i - 50);
		}
		return "一";
	}
}
