"""Text interpolation for headlines/details.

{{var}} comes from the item's resolved variables; {{fields.<step>.<key>}} from
values captured earlier in the same item. email_list values render as prose
("a and b" / "a, b and c") because they appear inside human sentences.
Unknown tokens pass through literally — the spec validator already guarantees
they can't exist in library specs; passing through beats crashing a render.
"""

import re

_TOKEN = re.compile(r"\{\{\s*([a-zA-Z0-9_.]+)\s*\}\}")


def humanize(value) -> str:
    if isinstance(value, list):
        vals = [str(v) for v in value]
        if not vals:
            return ""
        if len(vals) == 1:
            return vals[0]
        return ", ".join(vals[:-1]) + " and " + vals[-1]
    return str(value)


def render_text(text: str, variables: dict, field_values: dict) -> str:
    """field_values: {step_id: {field_key: value}} accumulated from events."""

    def sub(m):
        tok = m.group(1)
        if tok in variables:
            return humanize(variables[tok])
        parts = tok.split(".")
        if len(parts) == 3 and parts[0] == "fields":
            return humanize(field_values.get(parts[1], {}).get(parts[2], m.group(0)))
        return m.group(0)

    return _TOKEN.sub(sub, text or "")
