from django import template
from django.utils import dateformat, timezone

register = template.Library()


def truncate_email(email):
    local, domain = email.split("@", 1)
    domain_name, domain_tld = domain.rsplit(".", 1)

    def truncate_segment(segment, n=2):
        return segment[:n] + "…" + segment[-n:]

    if len(local) >= 8:
        local = truncate_segment(local)
    if len(domain_name) >= 6:
        domain_name = truncate_segment(domain_name, 1)
    
    return local + "@" + domain_name + "." + domain_tld

@register.filter
def relative_ts(dt):
    """Return a compact relative timestamp string for a datetime value.

    < 24 h  → "3:07 a.m."
    < 7 d   → "Thu"
    < 1 y   → "07 Mar"
    ≥ 1 y   → "07 Mar 2025"
    """
    if dt is None:
        return ""
    local_dt = timezone.localtime(dt)
    diff = timezone.now() - dt
    if diff.total_seconds() < 86400:
        return dateformat.format(local_dt, "g:i a")
    elif diff.days < 7:
        return dateformat.format(local_dt, "D")
    elif diff.days < 365:
        return dateformat.format(local_dt, "d M")
    else:
        return dateformat.format(local_dt, "d M Y")


@register.filter
def display_name(user):
    # `getattr` guards: AnonymousUser has no `.email` attribute and is not
    # None, so `if user is None` doesn't catch it. Render anonymous viewers
    # as empty rather than crashing — the legacy ownerless-post path
    # (Percival ch. 18) shows post detail to anon visitors.
    if user is None or not getattr(user, "is_authenticated", False):
        return ""
    if user.username:
        return user.username
    return truncate_email(user.email)


@register.filter
def truncate_title(text, length=35):
    """`<length>` chars verbatim, or `<length-3>` chars + literal `...`
    past that — mirrors `billboard.views._truncate_post_title` so applet
    list rows + new-Post titling share one truncation rule. Falls back
    to empty string on None for guard-free template use."""
    if text is None:
        return ""
    text = str(text)
    if len(text) <= length:
        return text
    return text[: length - 3] + "..."


@register.filter
def at_handle(user):
    """`@username` when the user has set one; falls back to the truncated
    email otherwise (no `@` prefix on bare emails since the address itself
    already carries the `@`). Used in post.html to colour usernames in the
    --quaUser palette key while leaving emails as-is. Anonymous viewers
    render as empty (legacy ownerless-post path)."""
    if user is None or not getattr(user, "is_authenticated", False):
        return ""
    if user.username:
        return f"@{user.username}"
    return truncate_email(user.email)
