"""CommonGround:共识层——所有 agent 共享的世界常识(docs/agent-runtime-v2.md §1.4)。

- 静态共识:全岛拓扑摘要 + 人物名册 + 硬规则,**全员一字不差**(走 LLM prompt 缓存);
- 动态公告:时刻/天气/电力/公开死讯,每次思考注入;
- 私有知识不在这里(persona/记忆层负责)。
"""

from __future__ import annotations

AREAS = [
    ("鸦堡一层", ["门厅", "大客厅", "书房", "放映室", "道具间", "琴房", "餐厅", "厨房"]),
    ("鸦堡二层", ["二层走廊", "顾长风的房间", "邵铭轩的房间", "程亦深的房间", "唐曼的房间",
               "白聿的房间", "温言的房间", "江离的房间", "青之房", "露台", "阁楼"]),
    ("地下层", ["酒窖", "发电机房", "储藏室", "暗房", "冰窖", "密道"]),
    ("室外", ["前院", "码头", "船屋", "沙滩", "花园", "温室", "后山墓园", "荒废教堂", "断崖", "风暴林", "灯塔"]),
]

HARD_RULES = (
    "你们在与世隔绝的雾鸦岛上,暴风雨封海;天亮后约 07:00 才会有第一班渡船靠岸。"
    "船缆已断、备用小艇被凿穿、卫星电话无信号——天亮前没有人能离开,也叫不来救援。"
    "厨房有充足食材;岛上停电时,总电闸在地下的发电机房。"
)


SURVIVAL_GOALS = (
    "【今夜你们共同的处境与求生关切】放映机替『长夜影业』宣告了一场『杀青宴』——邀请者知道十年前的一切。"
    "除了各自的盘算,你和其他人都会本能地惦记这几件事,它们会把你们带去岛上不同的角落、而不是挤在一处:"
    "①弄清今晚到底是谁设的局、为什么偏偏是你们这七个;"
    "②找离岛或求救的法子——去码头看那条船、查船屋被凿穿的小艇、上灯塔点火向海面求救、翻找还能用的信号或电话;"
    "③自保——是结伴抱团,还是独自把要紧事办完;"
    "④一旦有人出事,凶手到底是谁、怎么不让自己成为下一个。"
    "你按自己的性格与隐情,在『办自己的事』和『这些共同的关切』之间权衡取舍。"
)


KEY_MECHANICS = (
    "【这座岛上几处要紧的机关(谁都看得出、可以利用)】"
    "①灯塔:储油罐被人提前搬空了,得先把散落的灯油(船屋、储藏室、温室一带能翻到)集齐加满,才能点亮塔灯向大陆求救——这是今夜唯一靠谱的求救指望;但灯一亮,渡船会提前出发。"
    "②发电机房总电闸:一旦被砸,全堡顿时漆黑、伸手不见五指(黑暗里最容易出事);有人下去合闸才能复电。"
    "③青之房:二层走廊正中那扇双开门锁了整整十年,是当年阮青住的房,据说原样封存——要黄铜钥匙才能开,钥匙下落不明;硬撬也能进,但动静极大、全堡可闻。里头未必空着。"
    "④餐厅那七个胶片盒:像一座倒计时——每死一个人,就有一盒『第N幕』被烧成灰。"
    "⑤厨房刀架空了一格;码头的缆绳是被利刃割断的——有人早有预谋。"
    "想搜出藏着的东西,就在那个地点 search;想动机关(砸电闸/点灯塔/撬门/敲钟等)就用对应的动作。"
)


# 雾鸦岛默认设定(缺 lore 配置时回退,保证向前兼容)。任何世界可在 world.json 的 "lore" 覆盖。
DEFAULT_LORE = {
    "island_name": "雾鸦岛",
    "areas": [[a, ns] for a, ns in AREAS],
    "roster_line": "十年前《雾鸦》剧组的旧人,彼此认识。",
    "topology_note": "(各地点之间按常理连通:堡内经门厅/走廊/楼梯通行,室外沿小径往来,地下层从厨房后梯或门厅主梯下。)",
    "hard_rules": HARD_RULES,
    "key_mechanics": KEY_MECHANICS,
    "survival_goals": SURVIVAL_GOALS,
}


def static_common_ground(roster: list[str], lore: dict | None = None) -> str:
    """开局即知、人人相同的世界常识(嵌入 system prompt,可被缓存)。
    设定文本(岛名/分区/处境/机关/求生关切)= 数据(world.json 的 lore);缺则回退雾鸦岛默认(向前兼容)。"""
    lore = lore or DEFAULT_LORE
    name = lore.get("island_name", DEFAULT_LORE["island_name"])
    lines = [f"【{name}地图常识】"]
    for area, names in lore.get("areas", DEFAULT_LORE["areas"]):
        lines.append(f"◆ {area}:{'、'.join(names)}")
    if lore.get("topology_note"):
        lines.append(lore["topology_note"])
    lines.append("【在岛人员】" + "、".join(roster) + "——" + lore.get("roster_line", DEFAULT_LORE["roster_line"]))
    lines.append("【处境】" + lore.get("hard_rules", DEFAULT_LORE["hard_rules"]))
    if lore.get("key_mechanics"):
        lines.append(lore["key_mechanics"])
    if lore.get("survival_goals"):
        lines.append(lore["survival_goals"])
    return "\n".join(lines)


def social_rhythm(hour: float) -> str:
    """社会性时刻表引力(G16):弱约定进共识,不强制——集体节律由此涌现。"""
    h = hour % 24
    if 6.5 <= h < 9.0:
        return "【惯例】清晨时分,大家通常会到餐厅碰头吃早饭、相互清点人数。"
    if 12.0 <= h < 13.5:
        return "【惯例】晌午,该到餐厅垫垫肚子了,顺便看看谁没露面。"
    if 18.0 <= h < 19.5:
        return "【惯例】晚饭时分,众人多半会聚到餐厅。"
    if h >= 23.5 or h < 5.0:
        return ("【惯例】夜已深了,常人此刻早该锁好房门睡下;无要紧事还在外面游荡或长谈,"
                "在别人眼里非常反常,会被记住并起疑。困意是真实的——要么抓紧办完要紧的事,"
                "要么回房休息;若是害怕独处,结伴待在房间附近也好过在外面耗着。")
    return ""


def dynamic_bulletin(time_label: str, weather: str, power_on: bool,
                     public_deaths: list[str]) -> str:
    """实时公告:每次思考的 prompt 头部,全员一致。"""
    lines = [f"现在是{time_label},窗外{weather}。"]
    if not power_on:
        lines.append("全岛停电中——室内一片漆黑,伸手不见五指,黑暗里谁靠近都看不清,这种时候最容易出事。"
                     "想让灯重新亮起来,就摸去地下发电机房合闸(用『修复电闸』);"
                     "黑暗里看不清身边的人,各自当心——但也别都挤成一团干等,要紧的事还得有人去办。")
    if public_deaths:
        lines.append(f"已确认遇害/失踪:{('、'.join(public_deaths))}。凶手很可能就在你们中间。")
    return "\n".join(lines)
