"""把选中实体渲染成「角色/设定卡」文本块（ARCH §3.4 渲染为卡片）。

卡片含 latest_state（易变态）——故渲染产物归入 volatile，不进缓存前缀。
确定性：按 SelectionTrace 既定顺序渲染；字段缺省则略过该行。
"""

from __future__ import annotations

import json
from typing import Any

from ww_core.domain.repositories import CharacterView, WorldEntityView

from .types import SelectionTrace


def _serialize(value: Any) -> str:
    return json.dumps(value, ensure_ascii=False, sort_keys=True)


def _line(label: str, value: str | None) -> str | None:
    if value is None or value == "":
        return None
    return f"- {label}：{value}"


def _character_card(c: CharacterView) -> str:
    head = f"【角色】{c.name}｜定位：{c.role or '未定'}"
    lines = [
        _line("外貌", c.appearance),
        _line("动机", c.motive),
        _line("说话习惯", _serialize(c.speech_tics) if c.speech_tics else None),
        _line("当前状态", c.latest_state),
    ]
    return "\n".join([head, *[ln for ln in lines if ln]])


def _world_card(w: WorldEntityView) -> str:
    head = f"【设定·{w.type}】{w.name}"
    lines = [
        _line("规则", _serialize(w.rules) if w.rules else None),
        _line("当前状态", w.latest_state),
    ]
    return "\n".join([head, *[ln for ln in lines if ln]])


def render_cards(
    selection: SelectionTrace,
    characters: list[CharacterView],
    world_entities: list[WorldEntityView],
) -> str:
    """按选择顺序渲染卡片；找不到底层行的选中项跳过。"""
    char_by_name = {c.name: c for c in characters}
    world_by_name = {w.name: w for w in world_entities}

    cards: list[str] = []
    for e in sorted(selection.selected, key=lambda e: (e.kind, e.name)):
        if e.kind == "character" and e.name in char_by_name:
            cards.append(_character_card(char_by_name[e.name]))
        elif e.kind == "world_entity" and e.name in world_by_name:
            cards.append(_world_card(world_by_name[e.name]))
    return "\n\n".join(cards)
