"""
数据验证工具类

提供数据验证相关的工具方法

作者: 张翔
日期: 2026-04-01
"""

import re
from typing import Optional


class Validator:
    """数据验证工具类"""
    
    EMAIL_PATTERN = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
    PHONE_PATTERN = r'^1[3-9]\d{9}$'
    USERNAME_PATTERN = r'^[a-zA-Z0-9_-]{3,50}$'
    ID_CARD_PATTERN = r'^\d{17}[\dXx]$'
    
    @staticmethod
    def is_valid_email(email: str) -> bool:
        """验证邮箱格式"""
        if not email:
            return False
        return bool(re.match(Validator.EMAIL_PATTERN, email))
    
    @staticmethod
    def is_valid_phone(phone: str) -> bool:
        """验证手机号格式"""
        if not phone:
            return False
        return bool(re.match(Validator.PHONE_PATTERN, phone))
    
    @staticmethod
    def is_valid_username(username: str) -> bool:
        """验证用户名格式"""
        if not username:
            return False
        return bool(re.match(Validator.USERNAME_PATTERN, username))
    
    @staticmethod
    def is_strong_password(password: str) -> bool:
        """验证密码强度"""
        if not password or len(password) < 8:
            return False
        
        has_upper = bool(re.search(r'[A-Z]', password))
        has_lower = bool(re.search(r'[a-z]', password))
        has_digit = bool(re.search(r'\d', password))
        has_special = bool(re.search(r'[!@#$%^&*(),.?":{}|<>]', password))
        
        return has_upper and has_lower and has_digit and has_special
    
    @staticmethod
    def is_valid_id_card(id_card: str) -> bool:
        """
        验证身份证号格式
        
        Args:
            id_card: 身份证号
            
        Returns:
            是否有效
        """
        if not id_card:
            return False
        
        if not re.match(Validator.ID_CARD_PATTERN, id_card):
            return False
        
        if id_card[:6] == "123456":
            return False
        
        return True
    
    @staticmethod
    def sanitize(text: str) -> str:
        """清洗输入,移除危险字符"""
        if not text:
            return ""
        
        sanitized = text
        sanitized = re.sub(r'<script[^>]*>.*?</script>', '', sanitized, flags=re.IGNORECASE | re.DOTALL)
        sanitized = re.sub(r'<[^>]+>', '', sanitized)
        sanitized = re.sub(r"[';\"\\]", '', sanitized)
        
        return sanitized.strip()
