from __future__ import annotations

import html
import re

import markdown
from django import template
from django.utils.safestring import mark_safe

from django_anyllm.settings import get_setting

register = template.Library()


_TABLE_SEPARATOR_RE = re.compile(r"\|:[-:]+:?\|")
_TABLE_SEPARATOR_LINE_RE = re.compile(r"\n\s*\|:[-:]+:?\|")


def _fix_single_line_tables(text: str) -> str:
    """Fix tables where rows are on a single line instead of separate lines."""
    if not _TABLE_SEPARATOR_RE.search(text):
        return text
    if _TABLE_SEPARATOR_LINE_RE.search(text):
        return text
    # Match "| |" (pipe-space-pipe) which is the boundary between rows
    # in a single-line table and replace with a newline between rows.
    return text.replace("| |", "|\n|")


@register.filter
def anyllm_markdown(value: str) -> str:
    """Render markdown text to safe HTML."""
    if not value:
        return ""
    fixed = _fix_single_line_tables(value)
    # Escape raw HTML in the source to prevent XSS, then let markdown
    # convert its own syntax (bold, lists, code, etc.) to HTML.
    safe_value = html.escape(fixed)
    md = markdown.Markdown(extensions=["nl2br", "tables"])
    return mark_safe(md.convert(safe_value))


@register.simple_tag
def show_internal() -> bool:
    """Return whether internal messages (reasoning, tool calls) should be shown."""
    return bool(get_setting("SHOW_INTERNAL"))
