package com.zksy.electricity.utils;

import com.zksy.electricity.domain.MessageParseResult;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DecimalFormat;
import java.util.Date;

@Slf4j
public class DataParser {
    private static Logger logger = LoggerFactory.getLogger(DataParser.class);
    public static MessageParseResult parseMessage(String msgString) {
        MessageParseResult result = new MessageParseResult();
        try {
            String processedResult = msgString.replaceAll("\\s", "");
            result.setLeadingString(processedResult.substring(0, 8));
            result.setFixed1(processedResult.substring(8, 10));
            result.setTableNumber(bigEndianToLittleEndian(processedResult.substring(10, 22)));
            result.setFixed2(processedResult.substring(22, 24));
            result.setCommandCode(processedResult.substring(24, 26));
            result.setDataFieldLength(Integer.parseUnsignedInt(processedResult.substring(26, 28), 16));

            String dataIdentificationString = processedResult.substring(28, 36);
            result.setDataIdentification(bigEndianToLittleEndian(subtractFromHex(dataIdentificationString)));

            String remainingAmountString = processedResult.substring(36, 44);
            result.setRemainingAmount(bigEndianToLittleEndian(subtractFromHex(remainingAmountString)));

            String overdraftAmountString = processedResult.substring(44, 52);
            result.setOverdraftAmount(bigEndianToLittleEndian(subtractFromHex(overdraftAmountString)));

            String AVoltageString = processedResult.substring(52, 56);
            result.setAVoltage(dataFormat(bigEndianToLittleEndian(subtractFromHex(AVoltageString)), 10, "0.0", "V"));

            String BVoltageString = processedResult.substring(56, 60);
            result.setBVoltage(dataFormat(bigEndianToLittleEndian(subtractFromHex(BVoltageString)), 10, "0.0", "V"));

            String CVoltageString = processedResult.substring(60, 64);
            result.setCVoltage(dataFormat(bigEndianToLittleEndian(subtractFromHex(CVoltageString)), 10, "0.0", "V"));

            String ACurrentString = processedResult.substring(64, 70);
            result.setACurrent(dataFormat(bigEndianToLittleEndian(subtractFromHex(ACurrentString)), 1000, "0.000", "A"));

            String BCurrentString = processedResult.substring(70, 76);
            result.setBCurrent(dataFormat(bigEndianToLittleEndian(subtractFromHex(BCurrentString)), 1000, "0.000", "A"));

            String CCurrentString = processedResult.substring(76, 82);
            result.setCCurrent(dataFormat(bigEndianToLittleEndian(subtractFromHex(CCurrentString)), 1000, "0.000", "A"));

            String totalActivePowerString = processedResult.substring(82, 88);
            result.setTotalActivePower(dataFormat(bigEndianToLittleEndian(subtractFromHex(totalActivePowerString)), 1000, "0.000", "KWH"));

            String AActivePowerString = processedResult.substring(88, 94);
            result.setAActivePower(dataFormat(bigEndianToLittleEndian(subtractFromHex(AActivePowerString)), 10000, "0.0000", "KWH"));

            String BActivePowerString = processedResult.substring(94, 100);
            result.setBActivePower(dataFormat(bigEndianToLittleEndian(subtractFromHex(BActivePowerString)), 10000, "0.0000", "KWH"));

            String CActivePowerString = processedResult.substring(100, 106);
            result.setCActivePower(dataFormat(bigEndianToLittleEndian(subtractFromHex(CActivePowerString)), 10000, "0.0000", "KWH"));

            String totalPowerString = processedResult.substring(106, 110);
            result.setTotalPower(dataFormat(bigEndianToLittleEndian(subtractFromHex(totalPowerString)), 1000, "0.000", ""));

            String APowerString = processedResult.substring(110, 114);
            result.setAPower(dataFormat(bigEndianToLittleEndian(subtractFromHex(APowerString)), 1000, "0.000", ""));

            String BPowerString = processedResult.substring(114, 118);
            result.setBPower(dataFormat(bigEndianToLittleEndian(subtractFromHex(BPowerString)), 1000, "0.000", ""));

            String CPowerString = processedResult.substring(118, 122);
            result.setCPower(dataFormat(bigEndianToLittleEndian(subtractFromHex(CPowerString)), 1000, "0.000", ""));

            String totalElectricityString = processedResult.substring(122, 130);
            result.setTotalElectricity(dataFormat(bigEndianToLittleEndian(subtractFromHex(totalElectricityString)), 100, "0.00", "KWH"));

            String sharpActivePowerConsumptionString = processedResult.substring(130, 138);
            result.setSharpActivePowerConsumption(dataFormat(bigEndianToLittleEndian(subtractFromHex(sharpActivePowerConsumptionString)), 100, "0.00", "KWH"));

            String peakActivePowerConsumptionString = processedResult.substring(138, 146);
            result.setPeakActivePowerConsumption(dataFormat(bigEndianToLittleEndian(subtractFromHex(peakActivePowerConsumptionString)), 100, "0.00", "KWH"));

            String averageActivePowerConsumptionString = processedResult.substring(146, 154);
            result.setAverageActivePowerConsumption(dataFormat(bigEndianToLittleEndian(subtractFromHex(averageActivePowerConsumptionString)), 100, "0.00", "KWH"));

            String valleyActivePowerString = processedResult.substring(154, 162);
            result.setValleyActivePower(dataFormat(bigEndianToLittleEndian(subtractFromHex(valleyActivePowerString)), 100, "0.00", "KWH"));

            String stateString = processedResult.substring(162, 166);
            result.setState(bigEndianToLittleEndian(subtractFromHex(stateString)));

            result.setCreateTime(new Date());
        } catch (Exception e) {
            logger.error("解析消息时出错", e);
        }
        return result;
    }
    /**
     * 将大端表示的十六进制字符串转换为小端表示的十六进制字符串。
     *
     * @param bigEndianHexString 大端表示的十六进制字符串（如 "032002250111"）
     * @return 小端表示的十六进制字符串（如 "110125022003"）
     */
    public static String bigEndianToLittleEndian(String bigEndianHexString) {
        // 将十六进制字符串转换为字节数组
        byte[] bigEndianBytes = hexStringToByteArray(bigEndianHexString);

        // 进行大小端转换
        byte[] littleEndianBytes = reverseBytes(bigEndianBytes);

        // 将字节数组转换回十六进制字符串
        return bytesToHex(littleEndianBytes, 0, littleEndianBytes.length);
    }

    /**
     * 将十六进制字符串转换为字节数组。
     *
     * @param s 十六进制字符串
     * @return 字节数组
     */
    private static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }

    /**
     * 将字节数组转换为十六进制字符串。
     *
     * @param bytes 字节数组
     * @param offset 偏移量
     * @param length 长度
     * @return 十六进制字符串
     */
    private static String bytesToHex(byte[] bytes, int offset, int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(String.format("%02X", bytes[offset + i]));
        }
        return sb.toString();
    }

    /**
     * 反转字节数组以进行大小端转换。
     *
     * @param bytes 字节数组
     * @return 转换后的字节数组
     */
    private static byte[] reverseBytes(byte[] bytes) {
        byte[] reversedBytes = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            reversedBytes[i] = bytes[bytes.length - 1 - i];
        }
        return reversedBytes;
    }
    /**
     * 将十六进制字符串中的每个字节减去指定的十进制数值，并返回新的十六进制字符串。
     *
     * @param hexStr 十六进制字符串（例如 "3244B335"）
     * @return 新的十六进制字符串
     */
    public static String subtractFromHex(String hexStr) {
        StringBuilder result = new StringBuilder();
        // 将十六进制减数转换为十进制整数
        int subValue = Integer.parseInt("33", 16);

        // 按两位一组遍历十六进制字符串
        for (int i = 0; i < hexStr.length(); i += 2) {
            // 提取两位十六进制数
            String pair = hexStr.substring(i, Math.min(i + 2, hexStr.length()));
            // 将提取的两位十六进制数转换为十进制整数
            int pairValue = Integer.parseInt(pair, 16);
            // 进行减法运算
            int newVal = pairValue - subValue;
            // 处理负数情况，保留最后两位十六进制表示
            newVal = newVal & 0xFF;
            // 将结果转换为两位十六进制字符串
            String newHex = String.format("%02X", newVal);
            // 将结果添加到结果字符串中
            result.append(newHex);
        }
        return result.toString();
    }
    public static String dataFormat(String input,int size,String decimalPlaces,String unit) {
        // 将输入的字符串转换为浮点数
        double voltage = Double.parseDouble(input) / + size;
        // 使用DecimalFormat来格式化数字，保留小数
        DecimalFormat df = new DecimalFormat(decimalPlaces);
        String formattedVoltage = df.format(voltage);
        // 添加单位V
        return formattedVoltage + unit;
    }
}