"""
PDF-specific template tags and filters
"""

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

register = template.Library()


@register.filter
def lookup(obj, field_name):
    """
    Template filter to dynamically access object attributes or dict keys
    Usage: {{ object|lookup:"field_name" }}
    """
    if obj is None:
        return None

    # Handle dict-like objects
    if hasattr(obj, "__getitem__") and not isinstance(obj, str):
        try:
            return obj[field_name]
        except (KeyError, TypeError):
            pass

    # Handle objects with attributes
    if hasattr(obj, field_name):
        attr = getattr(obj, field_name)
        # If it's a callable (method), call it
        if callable(attr):
            try:
                return attr()
            except TypeError:
                # Method requires arguments, return as is
                return attr
        return attr

    # Try to handle nested field access (e.g., "person.name")
    if "." in field_name:
        parts = field_name.split(".")
        current = obj
        for part in parts:
            if current is None:
                return None
            current = lookup(current, part)
        return current

    return None


@register.filter
def get_display_value(obj, field_name):
    """
    Get the display value for a field, including choices
    Usage: {{ object|get_display_value:"field_name" }}
    """
    value = lookup(obj, field_name)

    # Try to get display value for choice fields
    display_method = f"get_{field_name}_display"
    if hasattr(obj, display_method):
        display_value = getattr(obj, display_method)()
        if display_value:
            return display_value

    return value


@register.filter
def format_currency(value):
    """
    Format a number as currency
    Usage: {{ value|format_currency }}
    """
    if value is None:
        return "-"
    try:
        return f"€{float(value):,.2f}".replace(",", " ")
    except (ValueError, TypeError):
        return str(value)


@register.filter
def format_status_badge(status):
    """
    Format status as HTML badge
    Usage: {{ status|format_status_badge }}
    """
    if not status:
        return "-"

    status_lower = str(status).lower()
    css_class = f"status-{status_lower}"

    return mark_safe(f'<span class="status-badge {css_class}">{status}</span>')


@register.filter
def truncate_field(value, max_length=50):
    """
    Truncate field value for display
    Usage: {{ value|truncate_field:30 }}
    """
    if value is None:
        return "-"

    str_value = str(value)
    if len(str_value) <= max_length:
        return str_value

    return str_value[: max_length - 3] + "..."


@register.simple_tag
def get_field_value(obj, field_config):
    """
    Get formatted field value based on field configuration
    Usage: {% get_field_value object field_config %}
    """
    field_name = field_config.get("field_name")
    field_type = field_config.get("field_type", "text")

    value = lookup(obj, field_name)

    if value is None:
        return "-"

    if field_type == "currency":
        return format_currency(value)
    elif field_type == "date":
        try:
            return value.strftime("%d.%m.%Y")
        except (AttributeError, ValueError):
            return str(value)
    elif field_type == "datetime":
        try:
            return value.strftime("%d.%m.%Y %H:%M")
        except (AttributeError, ValueError):
            return str(value)
    elif field_type == "status":
        return format_status_badge(value)
    elif field_type == "boolean":
        return "Ja" if value else "Nein"
    else:
        return truncate_field(value)
