"""
Experience 모델
Q-Learning을 위한 경험 데이터 (SARS: State, Action, Reward, next_State)
"""

from dataclasses import dataclass
from typing import Optional
from .state import State


@dataclass
class Experience:
    """
    Q-Learning에서 사용하는 경험 데이터

    SARS 형식:
    - State: 현재 상태
    - Action: 선택한 액션 (action_id)
    - Reward: 받은 보상
    - next_State: 다음 상태 (종료 시 None)
    """

    state: State
    action_id: int
    reward: float
    next_state: Optional[State]
    done: bool  # 에피소드 종료 여부

    # 메타데이터 (선택사항)
    episode_id: Optional[str] = None
    step: Optional[int] = None
    timestamp: Optional[str] = None

    def to_dict(self) -> dict:
        """
        Experience를 딕셔너리로 직렬화

        Returns:
            {
                'state': [scenario, price_zone, acceptance_rate],
                'action_id': 5,
                'reward': 1.0,
                'next_state': [scenario, price_zone, acceptance_rate] or None,
                'done': False,
                'episode_id': 'ep_001',
                'step': 3,
                'timestamp': '2025-10-29T16:30:00'
            }
        """
        return {
            "state": self.state.to_array(),
            "action_id": self.action_id,
            "reward": self.reward,
            "next_state": self.next_state.to_array() if self.next_state else None,
            "done": self.done,
            "episode_id": self.episode_id,
            "step": self.step,
            "timestamp": self.timestamp,
        }

    @classmethod
    def from_dict(cls, data: dict) -> "Experience":
        """
        딕셔너리에서 Experience 복원

        Args:
            data: 직렬화된 Experience 데이터

        Returns:
            Experience 인스턴스
        """
        return cls(
            state=State.from_array(data["state"]),
            action_id=data["action_id"],
            reward=data["reward"],
            next_state=(
                State.from_array(data["next_state"]) if data["next_state"] else None
            ),
            done=data["done"],
            episode_id=data.get("episode_id"),
            step=data.get("step"),
            timestamp=data.get("timestamp"),
        )

    def __repr__(self) -> str:
        return (
            f"Experience("
            f"state={self.state.to_array()}, "
            f"action_id={self.action_id}, "
            f"reward={self.reward}, "
            f"next_state={self.next_state.to_array() if self.next_state else None}, "
            f"done={self.done}"
            f")"
        )
