import os
import uuid
from werkzeug.utils import secure_filename
from flask import current_app
import bleach


ALLOWED_TAGS = [
    'a', 'abbr', 'acronym', 'address', 'b', 'blockquote', 'br', 'code',
    'div', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img',
    'li', 'ol', 'p', 'pre', 'q', 's', 'span', 'strong', 'sub', 'sup',
    'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'u', 'ul',
    'figure', 'figcaption', 'iframe', 'video', 'audio', 'source',
]

ALLOWED_ATTRS = {
    '*': ['class', 'id', 'style', 'dir', 'lang'],
    'a': ['href', 'title', 'target', 'rel'],
    'img': ['src', 'alt', 'width', 'height', 'loading'],
    'iframe': ['src', 'width', 'height', 'frameborder', 'allowfullscreen', 'allow'],
    'video': ['src', 'controls', 'width', 'height', 'poster', 'preload'],
    'audio': ['src', 'controls', 'preload'],
    'source': ['src', 'type'],
    'td': ['colspan', 'rowspan'],
    'th': ['colspan', 'rowspan'],
}


def sanitize_html(html_content):
    """Sanitize HTML content to prevent XSS."""
    return bleach.clean(
        html_content,
        tags=ALLOWED_TAGS,
        attributes=ALLOWED_ATTRS,
        strip=True,
    )


def save_file(file, subfolder='images'):
    """Save uploaded file and return the relative path."""
    if not file or not hasattr(file, 'filename') or not file.filename:
        return None

    filename = secure_filename(file.filename)
    # Add UUID to prevent filename collisions
    ext = filename.rsplit('.', 1)[-1].lower() if '.' in filename else ''
    unique_name = f"{uuid.uuid4().hex}.{ext}"

    upload_dir = os.path.join(current_app.config['UPLOAD_FOLDER'], subfolder)
    os.makedirs(upload_dir, exist_ok=True)

    filepath = os.path.join(upload_dir, unique_name)
    file.save(filepath)

    return f"uploads/{subfolder}/{unique_name}"


def delete_file(filepath):
    """Delete an uploaded file."""
    if not filepath:
        return
    full_path = os.path.join(current_app.root_path, 'static', filepath)
    if os.path.exists(full_path):
        os.remove(full_path)
