import time
from dataclasses import dataclass, field
from enum import IntEnum
from typing import Optional


class State(IntEnum):
    UNKNOWN = 0
    APPROACHING = 1
    ENGAGED = 2
    TALKING = 3
    LEAVING = 4
    ABSENT = 5


@dataclass
class PersonTrack:
    person_id: int
    face_id: int = -1
    speaker_id: str = ''
    uwb_anchor_id: str = ''
    name: str = 'unknown'
    state: State = State.UNKNOWN
    position: Optional[tuple] = None   # (x, y, z) in base_link
    distance: float = 0.0
    bearing_deg: float = 0.0
    engagement_score: float = 0.0
    camera_id: int = -1
    last_seen: float = field(default_factory=time.monotonic)
    last_face_seen: float = 0.0
    history_distances: list = field(default_factory=list)  # last N distances for trend

    def update_state(self, now: float, engagement_distance: float = 2.0,
                     absent_timeout: float = 5.0):
        """Transition state machine based on distance trend and time."""
        age = now - self.last_seen
        if age > absent_timeout:
            self.state = State.ABSENT
            return
        if self.speaker_id:
            self.state = State.TALKING
            return
        if len(self.history_distances) >= 3:
            trend = self.history_distances[-1] - self.history_distances[-3]
            if self.distance < engagement_distance:
                self.state = State.ENGAGED
            elif trend < -0.2:  # moving closer
                self.state = State.APPROACHING
            elif trend > 0.3:   # moving away
                self.state = State.LEAVING
            else:
                self.state = State.ENGAGED if self.distance < engagement_distance else State.UNKNOWN
        elif self.distance > 0:
            self.state = State.ENGAGED if self.distance < engagement_distance else State.APPROACHING
