import math
import time
import random
import pydirectinput

class StuckHandler:
    # 针对 0.xxxx 坐标系优化
    DEFAULT_MIN_MOVE = 0.002  # 极其微小的位移也算移动
    DEFAULT_STUCK_DURATION = 2.5 # 减少等待时间，提高效率
    TURN_GRACE_SEC = 1.0      # 缩短宽限期，边走边转不需要 5 秒

    def __init__(self, min_move_threshold=None, stuck_duration_sec=None):
        self.last_pos = None
        self.stuck_start_time = 0
        self.min_move = min_move_threshold or self.DEFAULT_MIN_MOVE
        self.stuck_duration = stuck_duration_sec or self.DEFAULT_STUCK_DURATION

    def check_stuck(self, state, last_turn_time):
        """
        检测卡死：
        只有在正在前进（按住W）且坐标长时间不刷新时触发。
        """
        current_pos = (state['x'], state['y'])
        now = time.time()

        # 1. 初始化
        if self.last_pos is None:
            self.last_pos = current_pos
            return False

        # 2. 计算位移
        dist = math.sqrt(
            (current_pos[0] - self.last_pos[0]) ** 2 + 
            (current_pos[1] - self.last_pos[1]) ** 2
        )

        # 3. 核心判定：
        # 如果位移足够大，重置所有计数
        if dist > self.min_move:
            self.stuck_start_time = 0
            self.last_pos = current_pos
            return False

        # 4. 位移不足时的处理
        # 宽限期优化：只有在非频繁转向时才开始计时
        # (避免边走边转的短脉冲把卡死计时器刷掉)
        if last_turn_time and (now - last_turn_time) < 0.2: 
             # 如果刚刚那一瞬间正在转向脉冲中，本帧跳过，不重置计数也不判定
             return False

        if self.stuck_start_time == 0:
            self.stuck_start_time = now
        elif (now - self.stuck_start_time) >= self.stuck_duration:
            return True

        return False

    def resolve_stuck(self):
        """增强版脱困：针对血DK挂机环境"""
        print(">>> [警告] 检测到撞墙，正在执行脱困动作...")
        
        # 1. 全停
        for k in ("w", "a", "d", "s"):
            pydirectinput.keyUp(k)
        
        # 2. 倒车并转向（组合动作更有效）
        pydirectinput.keyDown("s")
        turn_key = random.choice(["a", "d"])
        pydirectinput.keyDown(turn_key)
        
        # 倒车时间稍长一点，离开障碍物
        time.sleep(0.5)
        
        # 3. 尝试跳跃脱离地形卡位
        pydirectinput.press("space")
        time.sleep(0.5)
        
        pydirectinput.keyUp(turn_key)
        pydirectinput.keyUp("s")
        
        # 4. 往前稍微走一步，重新锁定坐标
        pydirectinput.keyDown("w")
        time.sleep(0.5)
        pydirectinput.keyUp("w")

        self.reset()
        print(">>> 脱困尝试结束")

    def reset(self):
        self.last_pos = None
        self.stuck_start_time = 0