import re
import json

from django import template
from django.urls import reverse
from django.utils.html import format_html
from django.utils.safestring import mark_safe

register = template.Library()

# Syntax: [[type:arg1[:arg2...][|visible text]]]
PATTERN = re.compile(r"\[\[([a-zA-Z_]+):([^\]\|]+)(?:\|([^\]]+))?\]\]")


@register.filter(is_safe=True)
def render_markup(value):
    if not value:
        return ""

    def repl(match):
        typ = match.group(1)
        args_raw = match.group(2)
        text_override = match.group(3)
        args = [a for a in args_raw.split(":") if a != ""]

        # Default display text
        display = text_override or (" ".join([typ.capitalize()] + args))

        # Provide data attributes and render as a non-clickable span badge so
        # client-side JS can upgrade it to an interactive token. Keep
        # `data-args` for backward compatibility.
        data_args = json.dumps(args)
        pk = args[0] if args else ''
        cls = 'markup-token'
        if typ == 'case':
            cls += ' badge bg-primary text-white'
        elif typ == 'displayset':
            cls += ' badge bg-success text-white'
        else:
            cls += ' badge bg-info text-dark'

        return format_html(
            '<span class="{}" data-type="{}" data-args="{}" data-pk="{}" data-label="{}">{}</span>',
            cls,
            typ,
            data_args,
            pk,
            display,
            display,
        )

    replaced = PATTERN.sub(repl, str(value))
    # Preserve newlines
    replaced = replaced.replace("\n", "<br>")
    return mark_safe(replaced)
