package com.ruoyi.database.util;

/**
 * 车牌验证工具类（完整版）
 * 来源：多个开源项目整合优化
 */
public class LicensePlateValidator {

    /**
     * 中国车牌正则表达式集合
     */
    public static class Patterns {
        // 普通民用车牌
        public static final String COMMON_PLATE = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-Z0-9]{4,5}[A-Z0-9挂学警港澳]$";

        // 新能源车牌
        public static final String NEW_ENERGY_PLATE = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[DF])|([DF][A-HJ-NP-Z0-9][0-9]{4}))$";

        // 警车车牌
        public static final String POLICE_PLATE = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][0-9]{4}警$";

        // 武警车牌
        public static final String ARMED_POLICE_PLATE = "^WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][0-9]{4}[TD]$";

        // 使馆车牌
        public static final String EMBASSY_PLATE = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][0-9]{4}使$";

        // 教练车牌
        public static final String COACH_PLATE = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][0-9]{4}学$";
    }

    /**
     * 车牌类型枚举
     */
    public enum PlateType {
        COMMON(1, "普通蓝牌"),
        YELLOW(2, "黄牌"),
        NEW_ENERGY(3, "新能源"),
        POLICE(4, "警车"),
        ARMED_POLICE(5, "武警"),
        EMBASSY(6, "使馆"),
        COACH(7, "教练"),
        UNKNOWN(0, "未知");

        private final int code;
        private final String desc;

        PlateType(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }

        public int getCode() { return code; }
        public String getDesc() { return desc; }
    }

    /**
     * 验证车牌号是否有效
     * @param plateNo 车牌号
     * @return 是否有效
     */
    public static boolean isValid(String plateNo) {
        if (plateNo == null || plateNo.trim().isEmpty()) {
            return false;
        }

        String formatted = formatPlateNo(plateNo);

        // 检查所有可能的车牌类型
        return isCommonPlate(formatted) ||
                isNewEnergyPlate(formatted) ||
                isPolicePlate(formatted) ||
                isArmedPolicePlate(formatted) ||
                isEmbassyPlate(formatted) ||
                isCoachPlate(formatted);
    }

    /**
     * 检测车牌类型
     * @param plateNo 车牌号
     * @return 车牌类型
     */
    public static PlateType detectType(String plateNo) {
        if (plateNo == null || plateNo.trim().isEmpty()) {
            return PlateType.UNKNOWN;
        }

        String formatted = formatPlateNo(plateNo);

        if (isNewEnergyPlate(formatted)) {
            return PlateType.NEW_ENERGY;
        } else if (isCommonPlate(formatted)) {
            // 区分蓝牌和黄牌（通过长度和内容判断）
            if (formatted.length() >= 7 && formatted.matches(".*[0-9]{6}.*")) {
                return PlateType.YELLOW;
            }
            return PlateType.COMMON;
        } else if (isPolicePlate(formatted)) {
            return PlateType.POLICE;
        } else if (isArmedPolicePlate(formatted)) {
            return PlateType.ARMED_POLICE;
        } else if (isEmbassyPlate(formatted)) {
            return PlateType.EMBASSY;
        } else if (isCoachPlate(formatted)) {
            return PlateType.COACH;
        }

        return PlateType.UNKNOWN;
    }

    /**
     * 格式化车牌号（统一格式）
     */
    public static String formatPlateNo(String plateNo) {
        if (plateNo == null) return null;
        // 去除所有空白字符，转为大写
        return plateNo.replaceAll("\\s+", "").toUpperCase();
    }

    // 各个类型的验证方法
    private static boolean isCommonPlate(String plateNo) {
        return plateNo.matches(Patterns.COMMON_PLATE);
    }

    private static boolean isNewEnergyPlate(String plateNo) {
        return plateNo.matches(Patterns.NEW_ENERGY_PLATE);
    }

    private static boolean isPolicePlate(String plateNo) {
        return plateNo.matches(Patterns.POLICE_PLATE);
    }

    private static boolean isArmedPolicePlate(String plateNo) {
        return plateNo.matches(Patterns.ARMED_POLICE_PLATE);
    }

    private static boolean isEmbassyPlate(String plateNo) {
        return plateNo.matches(Patterns.EMBASSY_PLATE);
    }

    private static boolean isCoachPlate(String plateNo) {
        return plateNo.matches(Patterns.COACH_PLATE);
    }

    /**
     * 获取省份简称
     */
    public static String getProvince(String plateNo) {
        if (plateNo == null || plateNo.length() < 1) {
            return null;
        }
        return formatPlateNo(plateNo).substring(0, 1);
    }

    /**
     * 测试用例
     */
    public static void main(String[] args) {
        String[] testPlates = {
                "京A12345",
                "沪AD12345",
                "粤B88888",
                "京A1234警",
                "WJ京1234T",
                "使A1234使",
                "invalid"
        };

        for (String plate : testPlates) {
            System.out.println("车牌: " + plate);
            System.out.println("是否有效: " + isValid(plate));
            System.out.println("类型: " + detectType(plate));
            System.out.println("省份: " + getProvince(plate));
            System.out.println("格式化: " + formatPlateNo(plate));
            System.out.println("---");
        }
    }
}
