from pathlib import Path
import sys

import numpy as np


PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))

from guidance import ScreenGuidanceController


def test_guidance_reset_reinitializes_smoothed_point():
    ctrl = ScreenGuidanceController()
    ctrl.smoothed_point = np.array([100.0, 200.0], dtype=np.float32)
    ctrl.smoothed_cmd = np.array([0.7, -0.4], dtype=np.float32)

    ctrl.reset_for_target_switch(np.array([500.0, 300.0], dtype=np.float32))

    assert np.allclose(ctrl.smoothed_point, np.array([500.0, 300.0], dtype=np.float32))
    assert np.allclose(ctrl.smoothed_cmd, np.zeros(2, dtype=np.float32))


def test_guidance_reset_can_damp_instead_of_zero_when_requested():
    ctrl = ScreenGuidanceController()
    ctrl.smoothed_cmd = np.array([0.8, -0.6], dtype=np.float32)

    ctrl.reset_for_target_switch(np.array([10.0, 20.0], dtype=np.float32), cmd_damp=0.25)

    assert np.allclose(ctrl.smoothed_cmd, np.array([0.2, -0.15], dtype=np.float32))


def test_guidance_override_box_takes_priority_over_stale_locked_box():
    ctrl = ScreenGuidanceController()

    state = ctrl.update(
        frame_id=1,
        frame_w=1000,
        frame_h=600,
        confirmed=True,
        locked_box=np.array([50.0, 50.0, 150.0, 150.0], dtype=np.float32),
        pred_box=np.array([60.0, 60.0, 160.0, 160.0], dtype=np.float32),
        override_box=np.array([800.0, 100.0, 900.0, 200.0], dtype=np.float32),
        target_id=1,
        target_track_score=0.55,
        klt_valid=True,
        klt_quality=0.9,
        miss_streak=5,
        vx=0.0,
        vy=0.0,
    )

    assert state["status"] == "REACQ"
    assert 845.0 <= state["aim_x"] <= 855.0
    assert 145.0 <= state["aim_y"] <= 155.0
    assert state["box_w"] == 100.0
    assert state["box_h"] == 100.0
