"""StubMind:无 LLM 的规则桩 agent——专为验证 v2 运行时链路(作息/逐跳/中断/聚集)。

行为规则(够"像人"即可,认知层接入后整体替换):
- 深夜(≥23:00)或困意过阈 → 回自己房间睡到 07:00;惊醒后恐惧驱动去门厅找人;
- 饿了(soma 候选)→ 去厨房吃 20 分钟;
- 听到高显著度事件(惨叫/停电)→ 中断当前动作,赶往门厅与人汇合;
- 其余时间:在"偏好地点"间游荡,遇到人偶尔寒暄两句(冒泡可见)。
"""

from __future__ import annotations

import random

from genesis.runtime.actor import Actor
from genesis.runtime.attention import Attention
from genesis.runtime.bus import Event
from genesis.runtime.soma import Soma

SMALLTALK = ["这鬼天气……", "你也睡不着?", "刚才那声音你听见了吗", "还是大家待在一起稳妥",
             "这岛上到处不对劲", "天亮就好了"]


class StubMind:
    def __init__(self, aid: str, home: str, haunts: list[str], rng: random.Random,
                 actor: Actor, attention: Attention, soma: Soma) -> None:
        self.aid = aid
        self.home = home
        self.haunts = haunts            # 偏好游荡地点
        self.rng = rng
        self.actor = actor
        self.attention = attention
        self.soma = soma
        self.last_speech = ""
        self.gathering = False          # 被惊动后正在去门厅汇合

    # —— 决策:返回 (动作描述, 唤醒时刻) ;engine 负责调度与事件发布 ——
    def think(self, now_h: float, place: str, occupants: list[str]) -> None:
        events = self.attention.drain()
        for e in events:                # 高冲击事件 → 恐惧
            if e.salience >= 0.8:
                self.soma.shock(now_h, 0.6 if e.etype == "ambient" else 0.8)
                self.gathering = True
        snap = self.soma.snapshot(now_h)
        self.last_speech = ""

        if self.gathering and place != "门厅":
            if self.actor.start_move("门厅"):
                return
        if self.gathering and place == "门厅":
            self.gathering = False
            self.actor.idle(self.rng.uniform(600, 1200), "和大家聚在一起压惊")
            if occupants:
                self.last_speech = self.rng.choice(SMALLTALK)
            return
        # 睡觉:深夜回房(恐惧高时不睡,宁可找人)
        h = now_h % 24
        if (h >= 23.2 or h < 6.0 or snap["fatigue"] > 0.75) and snap["fear"] < 0.5:
            if place != self.home:
                if self.actor.start_move(self.home):
                    return
            self.actor.start_sleep(7.0)
            self.soma.slept(7.0)
            return
        # 吃饭
        if "去厨房弄点吃的" in self.soma.candidates(now_h):
            if place != "厨房":
                if self.actor.start_move("厨房"):
                    return
            self.actor.start_do("在厨房弄点吃的", 1200)
            self.soma.ate(now_h)
            return
        # 游荡/寒暄
        if occupants and self.rng.random() < 0.45:
            self.last_speech = self.rng.choice(SMALLTALK)
            self.actor.idle(self.rng.uniform(400, 900), f"和{occupants[0]}闲聊")
            return
        dest = self.rng.choice([p for p in self.haunts if p != place] or [self.home])
        if not self.actor.start_move(dest):
            self.actor.idle(600)

    def on_event(self, e: Event) -> None:
        self.attention.receive(e)
