///|
/// 角色投影策略。语义树里没有「这个容器有没有边框」这种视觉事实,
/// 所以画不画框必须由投影器决定,而不是由控件决定。类分五档:
/// - `Region` 区域容器:画边框盒,自己不写字(命名区域的框就是它的表达)
/// - `Item` 结构条目(List/Tree 的一行):自己不写字,内容归子节点,
///   焦点/选中由整行高亮带表达
/// - `Label` 自带文本的条目(Tab/Option/Cell/Link):写字,不画框
/// - `Content` 叶子内容:把自己的文本写进量化盒
/// - `Placeholder` 不可投影控件:固定占位文本并写诊断,不允许静默消失
///
/// 放弃的方案:每个容器都画「带标题的盒」。实测证明它把
/// `Selectable list`、`Entry 0, row 0` 这类聚合名字画在条目同一行上,
/// 被更深一层的文本打断成 `e list`、`EnEntry 0row 0` 这种残字 ——
/// 半截标题比没有标题更难读。
pub(all) enum RoleKind {
  Region
  Item
  Label
  Content
  Placeholder
} derive(Eq, Debug)

///|
pub extend RoleKind with Debug::{to_repr}

///|
pub extend RoleKind with Eq::{not_equal, equal}

///|
/// 绘制优先级:边框 1 < 标题 2 < 叶子内容 3。同优先级先到先得。
/// `Item` 不写字,拿边框档,免得它的占位符挤掉真正的叶子。
pub fn role_priority(kind : RoleKind) -> Int {
  match kind {
    Region | Item => 1
    Label => 2
    Content | Placeholder => 3
  }
}

///|
pub fn role_tag(role : @core.SemanticsRole) -> String {
  match role {
    @core.Text => "Text"
    @core.Link => "Link"
    @core.Heading => "Heading"
    @core.Navigation => "Navigation"
    @core.Main => "Main"
    @core.Button => "Button"
    @core.Checkbox => "Checkbox"
    @core.TextField => "TextField"
    @core.List => "List"
    @core.ListItem => "ListItem"
    @core.Grid => "Grid"
    @core.ScrollView => "ScrollView"
    @core.Switch => "Switch"
    @core.Radio => "Radio"
    @core.Slider => "Slider"
    @core.Progress => "Progress"
    @core.Tab => "Tab"
    @core.Dialog => "Dialog"
    @core.Tooltip => "Tooltip"
    @core.Menu => "Menu"
    @core.ButtonGroup => "ButtonGroup"
    @core.Form => "Form"
    @core.FormField => "FormField"
    @core.Tree => "Tree"
    @core.TreeItem => "TreeItem"
    @core.Group => "Group"
    @core.WebView => "WebView"
    @core.Image => "Image"
    @core.Alert => "Alert"
    @core.Status => "Status"
    @core.ComboBox => "ComboBox"
    @core.Option => "Option"
    @core.Table => "Table"
    @core.Row => "Row"
    @core.Cell => "Cell"
    @core.Separator => "Separator"
    @core.None => "None"
  }
}

///|
/// 全匹配 `SemanticsRole`,新增角色会让这里编译失败,而不是静默降级。
pub fn role_kind(role : @core.SemanticsRole) -> RoleKind {
  match role {
    @core.Group
    | @core.List
    | @core.Grid
    | @core.Main
    | @core.Navigation
    | @core.Form
    | @core.FormField
    | @core.Table
    | @core.Menu
    | @core.Tree
    | @core.ScrollView
    | @core.Dialog
    | @core.ButtonGroup => Region
    @core.Row | @core.ListItem | @core.TreeItem | @core.Separator => Item
    @core.Tab | @core.Option | @core.Cell | @core.Link | @core.Tooltip => Label
    @core.Image | @core.WebView => Placeholder
    @core.Text
    | @core.Status
    | @core.Alert
    | @core.Heading
    | @core.Button
    | @core.Checkbox
    | @core.Switch
    | @core.Radio
    | @core.TextField
    | @core.ComboBox
    | @core.Slider
    | @core.Progress
    | @core.None => Content
  }
}

///|
/// 默认调色板的角色 → 样式入口;渲染器持有 `TuiPalette` 并显式调用
/// `palette.attrs_for`。这里保留的默认版是给测试与「无宿主注入主题」
/// 场景的便捷门面(也是两条 golden 帧锁定的颜色路径)。
pub fn attrs_for(
  role : @core.SemanticsRole,
  state : @core.SemanticsState,
) -> @tui.CellAttrs {
  TuiPalette::default().attrs_for(role, state)
}