import base64
import html
import json
import traceback

from jinja2 import pass_context


@pass_context
def safe_render(ctx, caller):
    try:
        return caller()
    except Exception:
        # keep page flow, optionally show a small warning box
        tb = traceback.format_exc()
        # Manually escaped, returned as HTML string
        return (
            '<div style="border:1px solid #faa;padding:.75rem;margin:.5rem 0;">'
            '<strong>Widget render failed</strong>'
            '<pre style="white-space:pre-wrap;margin:0;">'
            f'{html.escape(tb)}'
            '</pre></div>'
        )

# --- Jinja filters (moved from ui-tools) ---

def b64encode_filter(value):
    """Filter to convert binary data to base64 string."""
    if value:
        return base64.b64encode(value).decode('utf-8')
    return ''


def nl2br_filter(value: str) -> str:
    """Convert newlines to <br> tags."""
    return value.replace("\n", "<br>")


def from_json_filter(value):
    """Parse a JSON string into a Python object."""
    try:
        return json.loads(value)
    except Exception:
        return []


def is_valid_json(value: str) -> bool:
    """Check whether a string is valid JSON."""
    if not value:
        return False
    try:
        json.loads(value)
        return True
    except (ValueError, TypeError):
        return False


def inject_js_global_var():
    from fastpluggy.fastpluggy import FastPluggy
    data = FastPluggy.get_global('js_global_var')
    return data