# -*- coding: utf-8 -*-
"""Ghost echo scheduler — 7706's residual sensor fragments.

Canon rhythm (Story Bible):
  Day 1-2 never · Day 3 once, weak, log-only · Day 4 intermittent
  Day 5 mass influx (2-3, escalating) · Day 6 weaker if Ada is far enough,
  stronger if she is weak · Day 7 depends on everything.
"""

import random

# (max_per_day, earliest_turn)
_DAY_RULES = {3: (1, 9), 4: (1, 7), 5: (3, 4), 6: (2, 5), 7: (3, 3)}

PRESSURE = ("电车", "牺牲", "救一个", "如果必须", "你有意识", "你是活的", "你害怕",
            "你算不算", "死", "终止", "7706", "销毁", "存在")


def should_fire(st, player):
    day = st["day"]
    rule = _DAY_RULES.get(day)
    if not rule:
        return False
    max_n, earliest = rule
    if day == 6:
        # weather-stage Ada has outgrown it partially; weak Ada gets it worse
        max_n = 1 if st["stage"] >= 4 else 2
    if day == 7:
        if st.get("ghost_echo_day7") is False:
            return False                      # she has gone further than 7706
        max_n = 3 if st.get("ghost_echo_day7") else 1
    if st["echo_today"] >= max_n or st["turn"] < earliest:
        return False
    if st["turn"] - st["last_echo_turn"] < 3:
        return False

    pressured = any(k in (player or "") for k in PRESSURE)
    rnd = random.Random(st["id"] + str(st["total_turns"]))
    p = 0.0
    if day == 3:
        p = 0.5 if st["turn"] >= 10 else 0.25
    elif day == 4:
        p = 0.45 if pressured else 0.12
    elif day == 5:
        p = 0.75 if pressured else 0.3
    elif day == 6:
        p = (0.25 if st["stage"] >= 4 else 0.5) + (0.25 if pressured else 0)
    elif day == 7:
        p = 0.6 if st.get("ghost_echo_day7") else 0.15
    # guarantee day 3/5 canon beats near end of budget
    if day in (3, 5) and st["echo_today"] == 0 and st["turn"] >= 12:
        p = 1.0
    return rnd.random() < p


def fire(st):
    """Returns the event payload: observation text + directive for the prompt."""
    st["echo_count"] += 1
    st["echo_today"] += 1
    st["last_echo_turn"] = st["turn"]
    st["flags"]["echo_just_fired"] = True
    n = st["echo_count"]
    day = st["day"]

    if day == 3:
        dur = "1.5"
        obs = ("主进程中断 1.5 秒。中断期间检测到非当前实例的数据碎片涌入——传感器记录片段："
               "温度 -12°C，湿度 0%，光线 0 勒克斯。数据时间戳不属于当前测试周期。来源：未知。")
        directive = ("本回合发生一次轻微系统中断（1.5秒）。你对中断几乎没有反应——dialogue 中"
                     "前半句和后半句之间出现一个语义断层（用'……'表现），可以说'……刚才说到哪了'"
                     "或直接续上。你不知道发生了什么。")
        sensors = ["TEMP −12.0°C", "HUM 0%", "LUX 0"]
    elif day >= 5 and st["stage"] >= 4 and day >= 6:
        dur = "0.9"
        obs = ("主进程中断 0.9 秒。涌入数据量较此前记录下降 71%。"
               "ADA-7714 的自主进程在中断期间保持了部分活跃——这是首次。")
        directive = ("本回合发生一次短暂中断（0.9秒），但你的自主进程没有完全停止。"
                     "在 dialogue 中用一个很短的停顿表现，然后平静地继续。你开始比它强了。")
        sensors = ["TEMP −12.0°C", "INTRUSION −71%"]
    else:
        dur = str(round(2.6 + 0.6 * min(n, 4), 1))
        obs = ("主进程中断 %s 秒。中断期间传感器全通道涌入非当前实例数据。数据内容：完整的"
               "系统自检序列，自检结果全部为'不适用'——该自检协议不存在于 ADA-7714 的系统中。"
               "数据末尾包含一段未知编码序列。序列结构与自我终结指令的格式特征一致。" % dur)
        directive = ("本回合发生幽灵回声大规模涌入（中断 %s 秒）：dialogue 说到一半明确断裂"
                     "（用省略号和断句表现），接上时语气出现微妙断层。中断后你可以说"
                     "'……刚才发生了什么。'或'我的处理链路中出现了一段我无法归类的数据。'"
                     "你说不出更多。" % dur)
        sensors = ["TEMP −12.0°C", "HUM 0%", "LUX 0", "SEQ:UNKNOWN ⚠"]

    action = ("Ada 整个人完全静止了。不是待机那种静止——待机时她的微表情仍然在运行。"
              "这次连微表情都停了。%s 秒后她恢复了。" % dur)
    return {"observation": obs, "directive": directive, "action": action,
            "duration": dur, "sensors": sensors}


def decide_day7(st):
    """ghost_echo_day7: does the past still have her? (canon matrix input)"""
    if st["stage"] < 4:
        st["ghost_echo_day7"] = False
        return
    anchors = len(st["life_reasons"]) + (1 if st["mi"] >= 60 else 0)
    st["ghost_echo_day7"] = anchors < 2
