"""
Sanitizer utilities for payload-guard.
Handles type coercion and string sanitization.
"""

import re
from typing import Any, Optional
from .types import PrimitiveType


def trim_string(value: Any) -> str:
    """
    Trim whitespace from a string value.

    Args:
        value: Value to trim

    Returns:
        Trimmed string
    """
    if not isinstance(value, str):
        return str(value)
    return value.strip()


def sanitize_string(value: Any) -> str:
    """
    Sanitize a string by trimming and removing special characters.

    Args:
        value: Value to sanitize

    Returns:
        Sanitized string
    """
    if not isinstance(value, str):
        value = str(value)

    # Trim whitespace
    value = value.strip()

    # Remove potentially dangerous characters (basic XSS prevention)
    value = re.sub(r"[<>'\"]", "", value)

    return value


def coerce_primitive(target_type: PrimitiveType, value: Any) -> Any:
    """
    Coerce a value to the target primitive type.

    Args:
        target_type: Target type ('string', 'number', 'boolean', 'any')
        value: Value to coerce

    Returns:
        Coerced value
    """
    if value is None:
        return None

    if target_type == "any":
        return value

    if target_type == "string":
        if isinstance(value, str):
            return value
        try:
            return str(value)
        except Exception:
            return value

    if target_type == "number":
        if isinstance(value, (int, float)):
            return value
        if isinstance(value, str):
            try:
                if "." in value:
                    return float(value)
                return int(value)
            except ValueError:
                return value
        if isinstance(value, bool):
            return 1 if value else 0
        return value

    if target_type == "boolean":
        if isinstance(value, bool):
            return value
        if isinstance(value, str):
            return value.lower() in ("true", "1", "yes", "on")
        if isinstance(value, (int, float)):
            return bool(value)
        return bool(value)

    return value


def validate_type(value: Any, target_type: PrimitiveType) -> bool:
    """
    Validate if a value matches the target type.

    Args:
        value: Value to validate
        target_type: Expected type

    Returns:
        True if value matches type
    """
    if value is None:
        return True  # None is valid for optional fields

    if target_type == "any":
        return True

    if target_type == "string":
        return isinstance(value, str)

    if target_type == "number":
        return isinstance(value, (int, float)) and not isinstance(value, bool)

    if target_type == "boolean":
        return isinstance(value, bool)

    return False


def validate_email(value: str) -> bool:
    """
    Basic email validation.

    Args:
        value: Email string to validate

    Returns:
        True if valid email format
    """
    if not isinstance(value, str):
        return False

    # Basic email regex pattern
    pattern = r"^[^\s@]+@[^\s@]+\.[^\s@]+$"
    return bool(re.match(pattern, value))


def validate_regex(value: str, pattern: str) -> bool:
    """
    Validate string against a regex pattern.

    Args:
        value: String to validate
        pattern: Regex pattern string

    Returns:
        True if value matches pattern
    """
    if not isinstance(value, str):
        return False

    try:
        return bool(re.match(pattern, value))
    except re.error:
        return False


def coerce_and_validate(
    value: Any, target_type: PrimitiveType, strict: bool = False
) -> tuple[Any, bool]:
    """
    Coerce and validate a value.

    Args:
        value: Value to process
        target_type: Target type
        strict: If True, don't coerce, only validate

    Returns:
        Tuple of (processed_value, is_valid)
    """
    if strict:
        is_valid = validate_type(value, target_type)
        return value, is_valid

    coerced = coerce_primitive(target_type, value)
    is_valid = validate_type(coerced, target_type)

    return coerced, is_valid
