package com.fs.his.utils;

import com.fs.common.utils.ParseUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

public class PhoneUtil {
    // 中国手机号正则（严谨）
    private static final String PHONE_REGEX = "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$";

    public static String encryptPhone(String text) {
        String encryptedText=null;
        try {
            SecretKeySpec secretKey = new SecretKeySpec("AESAabCdeREssREA".getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            // Encryption
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedBytes = cipher.doFinal(text.getBytes());
            encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedText;
    }
    /**
    * 解密
    */
    public static String decryptPhone(String encryptedText) {
        String text=null;
        try {
            SecretKeySpec secretKey = new SecretKeySpec("AESAabCdeREssREA".getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
            text = new String(decryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return text;
    }
    /**
    * 解密加*
    */
    public static String decryptPhoneMk(String encryptedText) {
        String text=null;
        try {
            SecretKeySpec secretKey = new SecretKeySpec("AESAabCdeREssREA".getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
            text = new String(decryptedBytes);
            text =text.replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return text;
    }

    public static String decryptAutoPhoneMk(String encryptedText) {
        String text=null;
        if (encryptedText!=null&&encryptedText!="") {
            if (encryptedText.length()>11){
                try {
                    SecretKeySpec secretKey = new SecretKeySpec("AESAabCdeREssREA".getBytes(), "AES");
                    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
                    cipher.init(Cipher.DECRYPT_MODE, secretKey);
                    byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
                    text = new String(decryptedBytes);
                    text =text.replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else {
                text =  ParseUtils.parsePhone(encryptedText);
            }
        }

        return text;
    }

    /**
     * 计算字符串的香农熵
     * 熵值高可能表示加密文本
     */
    public static double calculateShannonEntropy(String text) {
        if (text == null || text.isEmpty()) {
            return 0;
        }

        Map<Character, Integer> freqMap = new HashMap<>();
        for (char c : text.toCharArray()) {
            freqMap.put(c, freqMap.getOrDefault(c, 0) + 1);
        }

        double entropy = 0;
        int length = text.length();

        for (int count : freqMap.values()) {
            double probability = (double) count / length;
            entropy -= probability * (Math.log(probability) / Math.log(2));
        }

        return entropy;
    }

    /**
     * 基于熵值判断是否为密文
     */
    public static boolean isLikelyEncryptedByEntropy(String text) {
        double entropy = calculateShannonEntropy(text);

        // 经验阈值：熵值高于3.5可能为密文
        // 这个阈值可以根据实际数据调整
        return entropy > 3.5;
    }

    /**
     * 用于查询 使用老的数据加密
     * @param text
     * @return
     */
    private static String OLD_KEY = "2c8d1a7f4e9b3c6ae6d5c4b3a291f8c9";
    public static String encryptPhoneOldKey(String text) {
        String encryptedText=null;
        try {
            SecretKeySpec secretKey = new SecretKeySpec(OLD_KEY.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            // Encryption
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedBytes = cipher.doFinal(text.getBytes());
            encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedText;
    }

    /**
     * 严格校验手机号
     */
    public static boolean isValidPhone(String phone) {
        if (phone == null || phone.trim().isEmpty()) {
            return false;
        }
        return Pattern.matches(PHONE_REGEX, phone);
    }

    private static final String PUBLIC_KEY_STR = "ylrz112233";

    /**
     * XOR 加密（返回 Base64）（对于解析后的电话明文加密，适用于前端解密）
     * @param data  明文电话
     * @return String 密文
     */
    public static String xorEncrypt(String data) {
        byte[] dataBytes = data.getBytes(java.nio.charset.StandardCharsets.UTF_8);
        byte[] keyBytes = PUBLIC_KEY_STR.getBytes(java.nio.charset.StandardCharsets.UTF_8);
        byte[] result = new byte[dataBytes.length];
        for (int i = 0; i < dataBytes.length; i++) {
            result[i] = (byte) (dataBytes[i] ^ keyBytes[i % keyBytes.length]);
        }
        return Base64.getEncoder().encodeToString(result);
    }



    /**
     * XOR 解密
     * @param base64Str  Base64 编码的密文
     * @param privateKey 私钥字符串（如 "ylrz987654321"）
     * @return 解密后的明文字符串
     */
    public static String xorDecrypt(String base64Str, String privateKey) {
        // 1. Base64 解码为字节数组
        byte[] encryptedBytes = Base64.getDecoder().decode(base64Str);
        // 2. 私钥字符串转字节数组（UTF-8 编码）
        byte[] keyBytes = privateKey.getBytes(java.nio.charset.StandardCharsets.UTF_8);
        // 3. 逐字节异或
        byte[] resultBytes = new byte[encryptedBytes.length];
        for (int i = 0; i < encryptedBytes.length; i++) {
            resultBytes[i] = (byte) (encryptedBytes[i] ^ keyBytes[i % keyBytes.length]);
        }
        // 4. 将字节数组按 UTF-8 解码为字符串
        return new String(resultBytes, java.nio.charset.StandardCharsets.UTF_8);
    }
}
