"""输入验证模块.

提供关键词、URL、内容长度等通用验证函数。
所有验证函数返回 (bool, str) 元组，表示验证结果和错误信息。
"""

from __future__ import annotations

import re
from typing import Any


def validate_keyword(keyword: str, min_length: int = 2, max_length: int = 100) -> tuple[bool, str]:
    """验证关键词有效性.

    Args:
        keyword: 待验证的关键词
        min_length: 最小长度，默认 2
        max_length: 最大长度，默认 100

    Returns:
        (is_valid, error_message) 元组

    Example:
        >>> validate_keyword("digital marketing")
        (True, "")
        >>> validate_keyword("a")
        (False, "关键词长度必须在 2-100 之间")
    """
    if not keyword or not isinstance(keyword, str):
        return False, "关键词不能为空"

    keyword = keyword.strip()

    if len(keyword) < min_length:
        return False, f"关键词长度必须至少 {min_length} 个字符"

    if len(keyword) > max_length:
        return False, f"关键词长度不能超过 {max_length} 个字符"

    # 检查是否包含非法字符 (XSS/SQL注入防护)
    dangerous_chars = r'[<>{}"\';\-]'
    if re.search(dangerous_chars, keyword):
        return False, "关键词包含非法字符"

    # 检查SQL注入关键词
    sql_keywords = ["drop", "delete", "insert", "update", "select", "union", "--"]
    keyword_lower = keyword.lower()
    for sql_kw in sql_keywords:
        if sql_kw in keyword_lower:
            return False, "关键词包含非法字符"

    # 检查路径遍历攻击
    path_traversal_patterns = [
        "..",  # Directory traversal
        "%2e%2e",  # URL-encoded ..
        "%252e%252e",  # Double URL-encoded ..
        ".%00",  # Null byte injection attempt
    ]
    for pattern in path_traversal_patterns:
        if pattern in keyword_lower:
            return False, "关键词包含非法字符"

    return True, ""


def validate_url(url: str, allowed_schemes: list[str] | None = None) -> tuple[bool, str]:
    """验证 URL 有效性.

    Args:
        url: 待验证的 URL
        allowed_schemes: 允许的协议列表，默认 ["http", "https"]

    Returns:
        (is_valid, error_message) 元组

    Example:
        >>> validate_url("https://example.com")
        (True, "")
        >>> validate_url("ftp://example.com")
        (False, "URL 协议必须是: http, https")
    """
    if not url or not isinstance(url, str):
        return False, "URL 不能为空"

    if allowed_schemes is None:
        allowed_schemes = ["http", "https"]

    # 基本 URL 模式匹配
    pattern = r"^(?P<scheme>[^:]+)://(?P<host>[^/]+)(?P<path>/.*)?$"
    match = re.match(pattern, url.strip())

    if not match:
        return False, "URL 格式无效"

    scheme = match.group("scheme").lower()
    if scheme not in allowed_schemes:
        return False, f"URL 协议必须是: {', '.join(allowed_schemes)}"

    return True, ""


def validate_content_length(
    content: Any, min_length: int = 0, max_length: int = 50000
) -> tuple[bool, str]:
    """验证内容长度.

    Args:
        content: 待验证的内容
        min_length: 最小长度，默认 0
        max_length: 最大长度，默认 50000

    Returns:
        (is_valid, error_message) 元组
    """
    # Runtime type check for non-string types
    if not isinstance(content, str):
        return False, "内容必须是字符串"

    length = len(content)

    if length < min_length:
        return False, f"内容长度必须至少 {min_length} 个字符"

    if length > max_length:
        return False, f"内容长度不能超过 {max_length} 个字符"

    return True, ""


def validate_platform(
    platform: str, supported_platforms: list[str] | None = None
) -> tuple[bool, str]:
    """验证平台名称有效性.

    Args:
        platform: 平台名称
        supported_platforms: 支持的平台列表，默认
            ["quora", "medium", "reddit", "linkedin", "twitter"]

    Returns:
        (is_valid, error_message) 元组
    """
    if supported_platforms is None:
        supported_platforms = ["quora", "medium", "reddit", "linkedin", "twitter"]

    if not platform or not isinstance(platform, str):
        return False, "平台名称不能为空"

    platform = platform.lower().strip()

    if platform not in supported_platforms:
        return False, f"不支持的平台: {platform}，支持的平台: {', '.join(supported_platforms)}"

    return True, ""
