"""Shared Jinja2 environment and page rendering for pygitweb templates."""

from collections.abc import Iterable

from fastapi.responses import HTMLResponse
from jinja2 import Environment, PackageLoader, select_autoescape
from markupsafe import Markup

env = Environment(
    loader=PackageLoader("pygitweb", "templates"),
    autoescape=select_autoescape(enabled_extensions=("html", "xml"), default_for_string=True),
    trim_blocks=True,
    lstrip_blocks=True,
)

# A table cell is plain text, which the template escapes, or Markup, which it does not.
Cell = str | Markup

_ESCAPE_TEMPLATE = env.from_string("{{ value|e }}")


def render_page(name: str, /, **ctx: object) -> HTMLResponse:
    """Render a page template. Templates extend base.html; site_name defaults from settings."""
    from pygitweb.config import settings

    page_ctx = dict(ctx)
    page_ctx.setdefault("site_name", settings.SITE_NAME)
    return HTMLResponse(env.get_template(name).render(**page_ctx))


def jinja_escape(value: str | None) -> str | None:
    if value is None:
        return None
    return _ESCAPE_TEMPLATE.render(value=value)


def html_link(href: str, text: str, **attrs: str) -> Markup:
    """Anchor tag. href, text, and attribute values are escaped."""
    attr_html = Markup("").join(
        Markup(' {}="{}"').format(name.replace("_", "-"), value) for name, value in attrs.items()
    )
    return Markup('<a href="{}"{}>{}</a>').format(href, attr_html, text)


def html_format(template: str, /, *args: object, **kwargs: object) -> Markup:
    """Format an HTML snippet, escaping interpolated values. The template itself is trusted."""
    return Markup(template).format(*args, **kwargs)


def html_join(parts: Iterable[str | Markup], sep: str = "") -> Markup:
    """Join fragments. Plain strings are escaped; Markup is inserted as-is."""
    return Markup(sep).join(parts)


def trusted_html(value: str) -> Markup:
    """Mark HTML that a template or plugin already escaped. Do not pass raw text."""
    return Markup(value)


def initials(name: str) -> str:
    parts = [part for part in name.replace("_", " ").split() if part]
    if len(parts) >= 2:
        return (parts[0][0] + parts[-1][0]).upper()
    if parts:
        return parts[0][:2].upper()
    return "?"


_STATUS_BADGE = {
    "TODO": "secondary",
    "IN_PROGRESS": "blue",
    "IN_REVIEW": "yellow",
    "DONE": "green",
    "CANCELLED": "red",
}
_PRIORITY_BADGE = {
    "LOW": "secondary",
    "MEDIUM": "azure",
    "HIGH": "orange",
    "CRITICAL": "red",
}


def status_badge(status: str) -> Markup:
    key = (status or "TODO").upper()
    color = _STATUS_BADGE.get(key, "secondary")
    label = key.replace("_", " ").title()
    return html_format('<span class="badge bg-{}-lt">{}</span>', color, label)


def priority_badge(priority: str) -> Markup:
    key = (priority or "LOW").upper()
    color = _PRIORITY_BADGE.get(key, "secondary")
    label = key.replace("_", " ").title()
    return html_format('<span class="badge bg-{}-lt">{}</span>', color, label)


def person_label(name: str) -> Markup:
    label = (name or "").strip() or "Unassigned"
    return html_format(
        '<span class="d-inline-flex align-items-center gap-1"><span class="avatar avatar-xs">{}</span>{}</span>',
        initials(label),
        label,
    )


env.filters["initials"] = initials