"""
API 요청/응답 데이터 모델
"""
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field
from enum import Enum


class CardType(str, Enum):
    """협상 카드 타입"""
    C1 = "C1"
    C2 = "C2" 
    C3 = "C3"
    C4 = "C4"


class ScenarioType(str, Enum):
    """시나리오 타입"""
    A = "A"  # S_1
    B = "B"  # S_4
    C = "C"  # S_3
    D = "D"  # S_2


class PriceZoneType(str, Enum):
    """가격 구간 타입"""
    PZ1 = "PZ1"  # P < A
    PZ2 = "PZ2"  # A < P < T
    PZ3 = "PZ3"  # T < P


class ExperienceData(BaseModel):
    """경험 데이터 모델"""
    state: str = Field(..., description="현재 상태")
    action: CardType = Field(..., description="선택한 행동")
    reward: float = Field(..., description="받은 보상")
    next_state: str = Field(..., description="다음 상태")
    done: bool = Field(..., description="에피소드 종료 여부")
    timestamp: float = Field(..., description="타임스탬프")
    metadata: Optional[Dict[str, Any]] = Field(default=None, description="추가 메타데이터")


class NegotiationState(BaseModel):
    """협상 상태 모델"""
    current_card: CardType = Field(..., description="현재 카드")
    scenario: ScenarioType = Field(..., description="시나리오")
    price_zone: PriceZoneType = Field(..., description="가격 구간")

    @property
    def state_id(self) -> str:
        """상태 ID 생성"""
        return f"{self.current_card.value}{self.scenario.value}{self.price_zone.value}"


class RewardCalculationRequest(BaseModel):
    """보상 계산 요청 모델"""
    scenario: ScenarioType = Field(..., description="시나리오")
    price_zone: PriceZoneType = Field(..., description="가격 구간")
    anchor_price: float = Field(..., gt=0, description="목표가 (A)")
    proposed_price: float = Field(..., gt=0, description="제안가 (P)")
    is_end: bool = Field(..., description="협상 종료 여부")


class RewardCalculationResponse(BaseModel):
    """보상 계산 응답 모델"""
    reward: float = Field(..., description="계산된 보상")
    weight: float = Field(..., description="가중치 W")
    scenario_weight: float = Field(..., description="시나리오 가중치 S_n")
    price_zone_weight: float = Field(..., description="가격구간 가중치 PZ_n")
    price_ratio: float = Field(..., description="가격 비율 A/P")
    formula_breakdown: str = Field(..., description="공식 분해")


class QTableState(BaseModel):
    """Q-Table 상태 모델"""
    q_table: Dict[str, Dict[str, float]] = Field(..., description="Q-Table 데이터")
    update_count: int = Field(..., description="업데이트 횟수")
    learning_rate: float = Field(..., description="학습률")
    discount_factor: float = Field(..., description="할인율")


class EpisodeGenerationRequest(BaseModel):
    """에피소드 생성 요청 모델"""
    num_episodes: int = Field(..., ge=1, le=100, description="생성할 에피소드 수")
    max_steps: int = Field(..., ge=1, le=20, description="에피소드당 최대 스텝")
    anchor_price: float = Field(..., gt=0, description="목표가")
    exploration_rate: float = Field(default=0.4, ge=0, le=1, description="탐험율")


class LearningUpdateRequest(BaseModel):
    """학습 업데이트 요청 모델"""
    learning_rate: float = Field(..., ge=0.001, le=1.0, description="학습률")
    discount_factor: float = Field(..., ge=0.1, le=0.99, description="할인율")
    batch_size: int = Field(default=32, ge=1, le=1000, description="배치 크기")


class FQICQLRequest(BaseModel):
    """FQI+CQL 학습 요청 모델"""
    alpha: float = Field(default=1.0, ge=0, description="CQL 보수성 파라미터")
    gamma: float = Field(default=0.95, ge=0.1, le=0.99, description="할인율")
    batch_size: int = Field(default=32, ge=1, le=1000, description="배치 크기")
    num_iterations: int = Field(default=10, ge=1, le=100, description="반복 횟수")


class ActionRecommendationRequest(BaseModel):
    """행동 추천 요청 모델"""
    current_state: str = Field(..., description="현재 상태")
    use_epsilon_greedy: bool = Field(default=False, description="엡실론 그리디 사용")
    epsilon: float = Field(default=0.1, ge=0, le=1, description="엡실론 값")


class ActionRecommendationResponse(BaseModel):
    """행동 추천 응답 모델"""
    recommended_action: CardType = Field(..., description="추천 행동")
    q_values: Dict[str, float] = Field(..., description="현재 상태의 Q값들")
    confidence: float = Field(..., description="추천 신뢰도")
    exploration: bool = Field(..., description="탐험 행동 여부")


class SystemStatus(BaseModel):
    """시스템 상태 모델"""
    total_experiences: int = Field(..., description="총 경험 데이터 수")
    q_table_updates: int = Field(..., description="Q-Table 업데이트 횟수")
    unique_states: int = Field(..., description="고유 상태 수")
    average_reward: float = Field(..., description="평균 보상")
    success_rate: float = Field(..., description="성공률")
    last_update: Optional[float] = Field(default=None, description="마지막 업데이트 시간")
