package com.hotent.util;

public class AreaCodeUtil {

    /**
     * 区域级别枚举
     */
    public enum AreaLevel {
        PROVINCE("0"),
        CITY("1"),
        DISTRICT("2"),
        UNKNOWN("未知");

        private final String description;

        AreaLevel(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 区域编码信息
     */
    public static class AreaCodeInfo {
        private String code;
        private AreaLevel level;
        private String levelDescription;

        public AreaCodeInfo(String code, AreaLevel level) {
            this.code = code;
            this.level = level;
            this.levelDescription = level.getDescription();
        }

        // Getters and Setters
        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }

        public AreaLevel getLevel() {
            return level;
        }

        public void setLevel(AreaLevel level) {
            this.level = level;
        }

        public String getLevelDescription() {
            return levelDescription;
        }

        public void setLevelDescription(String levelDescription) {
            this.levelDescription = levelDescription;
        }

        @Override
        public String toString() {
            return "AreaCodeInfo{" +
                    "code='" + code + '\'' +
                    ", level=" + level +
                    ", levelDescription='" + levelDescription + '\'' +
                    '}';
        }
    }

    /**
     * 根据区域编码判断级别
     * @param areaCode 区域编码
     * @return 区域编码信息
     */
    public static AreaCodeInfo getAreaLevel(String areaCode) {
        if (!isValidAreaCode(areaCode)) {
            return new AreaCodeInfo(areaCode, AreaLevel.UNKNOWN);
        }

        // 标准化编码为6位
        String normalizedCode = normalizeAreaCode(areaCode);

        // 判断级别
        if (isProvinceLevel(normalizedCode)) {
            return new AreaCodeInfo(normalizedCode, AreaLevel.PROVINCE);
        } else if (isCityLevel(normalizedCode)) {
            return new AreaCodeInfo(normalizedCode, AreaLevel.CITY);
        } else {
            return new AreaCodeInfo(normalizedCode, AreaLevel.DISTRICT);
        }
    }

    /**
     * 判断是否为省级编码
     * 省级编码：前2位为有效编码，后4位为0000
     * @param areaCode 区域编码
     * @return 是否为省级编码
     */
    public static boolean isProvinceLevel(String areaCode) {
        if (!isValidAreaCode(areaCode)) {
            return false;
        }

        String normalizedCode = normalizeAreaCode(areaCode);
        return normalizedCode.endsWith("0000") &&
                !normalizedCode.startsWith("00") &&
                isValidProvinceCode(normalizedCode.substring(0, 2));
    }

    /**
     * 判断是否为市级编码
     * 市级编码：前4位为有效编码，后2位为00，且不是省级编码
     * @param areaCode 区域编码
     * @return 是否为市级编码
     */
    public static boolean isCityLevel(String areaCode) {
        if (!isValidAreaCode(areaCode)) {
            return false;
        }

        String normalizedCode = normalizeAreaCode(areaCode);
        // 不是省级编码，且后两位为00
        return !isProvinceLevel(normalizedCode) &&
                normalizedCode.endsWith("00") &&
                !normalizedCode.endsWith("0000");
    }

    /**
     * 判断是否为区县级编码
     * 区县级编码：6位完整编码，且不是省级和市级编码
     * @param areaCode 区域编码
     * @return 是否为区县级编码
     */
    public static boolean isDistrictLevel(String areaCode) {
        if (!isValidAreaCode(areaCode)) {
            return false;
        }

        String normalizedCode = normalizeAreaCode(areaCode);
        // 不是省级编码，也不是市级编码
        return !isProvinceLevel(normalizedCode) && !isCityLevel(normalizedCode);
    }

    /**
     * 验证区域编码是否有效
     * @param areaCode 区域编码
     * @return 是否有效
     */
    public static boolean isValidAreaCode(String areaCode) {
        if (areaCode == null || areaCode.trim().isEmpty()) {
            return false;
        }

        // 去除空格
        String trimmedCode = areaCode.trim();

        // 检查是否为纯数字
        if (!trimmedCode.matches("\\d+")) {
            return false;
        }

        // 检查长度（通常为6位，但也可能是其他长度）
        // 这里支持4位、6位等常见长度
        return trimmedCode.length() <= 12; // 最大支持12位编码
    }

    /**
     * 标准化区域编码为6位格式
     * @param areaCode 区域编码
     * @return 标准化后的编码
     */
    public static String normalizeAreaCode(String areaCode) {
        if (areaCode == null) {
            return "000000";
        }

        String trimmedCode = areaCode.trim();

        // 如果不足6位，右侧补0
        if (trimmedCode.length() < 6) {
            return String.format("%-6s", trimmedCode).replace(' ', '0');
        }
        // 如果超过6位，取前6位
        else if (trimmedCode.length() > 6) {
            return trimmedCode.substring(0, 6);
        }
        // 正好6位
        else {
            return trimmedCode;
        }
    }

    /**
     * 验证前两位是否为有效的省级编码
     * @param provinceCode 省级编码（前两位）
     * @return 是否有效
     */
    private static boolean isValidProvinceCode(String provinceCode) {
        if (provinceCode == null || provinceCode.length() != 2) {
            return false;
        }

        try {
            int code = Integer.parseInt(provinceCode);
            // 省级编码范围一般在01-99之间，但不是所有数字都有效
            // 这里简化处理，实际应用中可以根据具体省份编码列表验证
            return code >= 1 && code <= 99;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 获取省级编码（从任意级别编码中提取）
     * @param areaCode 区域编码
     * @return 省级编码
     */
    public static String getProvinceCode(String areaCode) {
        if (!isValidAreaCode(areaCode)) {
            return null;
        }

        String normalizedCode = normalizeAreaCode(areaCode);
        return normalizedCode.substring(0, 2) + "0000";
    }

    /**
     * 获取市级编码（从区县级编码中提取）
     * @param areaCode 区域编码
     * @return 市级编码
     */
    public static String getCityCode(String areaCode) {
        if (!isValidAreaCode(areaCode)) {
            return null;
        }

        String normalizedCode = normalizeAreaCode(areaCode);
        if (isProvinceLevel(normalizedCode) || normalizedCode.length() < 4) {
            return normalizedCode;
        }

        return normalizedCode.substring(0, 4) + "00";
    }

    /**
     * 根据编码获取所属上级编码
     * @param areaCode 区域编码
     * @return 上级编码
     */
    public static String getParentCode(String areaCode) {
        AreaCodeInfo info = getAreaLevel(areaCode);

        switch (info.getLevel()) {
            case PROVINCE:
                return null; // 省级没有上级
            case CITY:
                return getProvinceCode(areaCode);
            case DISTRICT:
                return getCityCode(areaCode);
            default:
                return null;
        }
    }


    public static void main(String[] args) {
        // 测试不同级别的编码
        String[] testCodes = {"110000", "110100", "110101", "310000", "310100", "310105"};

        for (String code : testCodes) {
            AreaCodeUtil.AreaCodeInfo info = AreaCodeUtil.getAreaLevel(code);
            System.out.println("编码: " + code + " -> 级别: " + info.getLevel());
            System.out.println("  上级编码: " + AreaCodeUtil.getParentCode(code));
            System.out.println("  省级编码: " + AreaCodeUtil.getProvinceCode(code));
            System.out.println("  市级编码: " + AreaCodeUtil.getCityCode(code));
            System.out.println();
        }

        // 测试判断方法
        System.out.println("110000 是省级编码: " + AreaCodeUtil.isProvinceLevel("110000"));
        System.out.println("110100 是市级编码: " + AreaCodeUtil.isCityLevel("110100"));
        System.out.println("110101 是区级编码: " + AreaCodeUtil.isDistrictLevel("110101"));
    }
}
