"""
HTML sanitization utilities for backend content storage.
Prevents XSS attacks by sanitizing HTML before storing in database.
"""
import bleach
from typing import Optional

# Allowed HTML tags for rich content
ALLOWED_TAGS = [
    'p', 'br', 'strong', 'em', 'u', 'b', 'i', 'span', 'div',
    'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
    'ul', 'ol', 'li',
    'a', 'blockquote', 'pre', 'code',
    'table', 'thead', 'tbody', 'tr', 'th', 'td',
    'img', 'hr', 'section', 'article'
]

# Allowed HTML attributes
ALLOWED_ATTRIBUTES = {
    'a': ['href', 'title', 'target', 'rel'],
    'img': ['src', 'alt', 'title', 'width', 'height', 'class'],
    'div': ['class', 'id', 'style'],
    'span': ['class', 'id', 'style'],
    'p': ['class', 'id', 'style'],
    'h1': ['class', 'id'],
    'h2': ['class', 'id'],
    'h3': ['class', 'id'],
    'h4': ['class', 'id'],
    'h5': ['class', 'id'],
    'h6': ['class', 'id'],
    'table': ['class', 'id'],
    'tr': ['class', 'id'],
    'th': ['class', 'id', 'colspan', 'rowspan'],
    'td': ['class', 'id', 'colspan', 'rowspan'],
}

# Allowed URL schemes
ALLOWED_SCHEMES = ['http', 'https', 'mailto', 'tel']

def sanitize_html(html_content: Optional[str]) -> str:
    """
    Sanitize HTML content to prevent XSS attacks.
    
    Args:
        html_content: HTML string to sanitize (can be None)
    
    Returns:
        Sanitized HTML string safe for storage
    """
    if not html_content:
        return ''
    
    # Clean HTML content
    cleaned = bleach.clean(
        html_content,
        tags=ALLOWED_TAGS,
        attributes=ALLOWED_ATTRIBUTES,
        protocols=ALLOWED_SCHEMES,
        strip=True,  # Strip disallowed tags instead of escaping
        strip_comments=True,  # Remove HTML comments
    )
    
    # Additional link sanitization - ensure external links have rel="noopener"
    if '<a' in cleaned:
        import re
        # Add rel="noopener noreferrer" to external links
        def add_rel(match):
            tag = match.group(0)
            if 'href=' in tag and ('http://' in tag or 'https://' in tag):
                if 'rel=' not in tag:
                    # Insert rel attribute before closing >
                    return tag[:-1] + ' rel="noopener noreferrer">'
                elif 'noopener' not in tag and 'noreferrer' not in tag:
                    # Add to existing rel attribute
                    tag = tag.replace('rel="', 'rel="noopener noreferrer ')
                    tag = tag.replace("rel='", "rel='noopener noreferrer ")
                    return tag
            return tag
        
        cleaned = re.sub(r'<a[^>]*>', add_rel, cleaned)
    
    return cleaned

def sanitize_text_for_html(text: Optional[str]) -> str:
    """
    Escape text content to be safely included in HTML.
    Use this for plain text that should be displayed as-is.
    
    Args:
        text: Plain text string to escape
    
    Returns:
        HTML-escaped string
    """
    if not text:
        return ''
    
    return bleach.clean(text, tags=[], strip=True)

