"""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