"""
Tradix Signal Event - Trading signal generation from strategy logic.
Tradix 시그널 이벤트 - 전략 로직에서 생성된 매매 신호.

This module defines the SignalEvent class and SignalType enumeration, used
when a strategy generates a trading signal in the Tradix backtesting engine.
Signals carry entry/exit direction, strength for position sizing, optional
target prices, and risk management levels (stop-loss, take-profit).

Features:
    - Entry signals: LONG, SHORT
    - Exit signals: EXIT_LONG, EXIT_SHORT, EXIT_ALL
    - Signal strength (0.0 to 1.0) for position sizing
    - Optional target price, stop-loss, and take-profit levels
    - Logging-friendly reason field

Usage:
    >>> from tradix.events.signal import SignalEvent, SignalType
    >>> from datetime import datetime
    >>> signal = SignalEvent(
    ...     timestamp=datetime.now(),
    ...     symbol="AAPL",
    ...     signalType=SignalType.LONG,
    ...     strength=0.8,
    ...     reason="Golden cross detected"
    ... )
    >>> signal.isEntry
    True
"""

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Optional

from tradix.events.base import Event, EventType


class SignalType(Enum):
    """Trading signal type enumeration. 매매 신호 유형 열거형."""
    LONG = "long"
    SHORT = "short"
    EXIT_LONG = "exitLong"
    EXIT_SHORT = "exitShort"
    EXIT_ALL = "exitAll"


@dataclass
class SignalEvent(Event):
    """
    Trading signal event generated by strategy logic.
    전략 로직에서 생성한 매매 신호 이벤트.

    Carries a trading signal from strategy evaluation to order generation.
    Includes signal direction, strength for position sizing, optional price
    targets, and risk management levels. Signal strength is automatically
    clamped to [0.0, 1.0] range.

    전략 평가에서 주문 생성으로의 매매 신호를 전달합니다.
    신호 방향, 포지션 사이징을 위한 강도, 선택적 목표 가격,
    리스크 관리 수준을 포함합니다.

    Attributes:
        symbol (str): Ticker symbol identifier. 종목 코드.
        signalType (SignalType): Signal direction/action type.
            신호 유형 (long, short, exit 등).
        strength (float): Signal strength between 0.0 and 1.0 for position sizing.
            신호 강도 (0.0~1.0, 포지션 사이징에 활용).
        price (Optional[float]): Target price for limit orders.
            목표 가격 (지정가 주문용).
        stopLoss (Optional[float]): Stop-loss price level. 손절가.
        takeProfit (Optional[float]): Take-profit price level. 익절가.
        reason (str): Human-readable signal rationale for logging. 신호 발생 사유.

    Example:
        >>> signal = SignalEvent(
        ...     timestamp=datetime.now(), symbol="AAPL",
        ...     signalType=SignalType.LONG, strength=0.8,
        ...     stopLoss=145.0, takeProfit=165.0
        ... )
        >>> signal.isEntry
        True
    """
    symbol: str = ""
    signalType: SignalType = SignalType.LONG
    strength: float = 1.0
    price: Optional[float] = None
    stopLoss: Optional[float] = None
    takeProfit: Optional[float] = None
    reason: str = ""
    eventType: EventType = field(default=EventType.SIGNAL, init=False)

    def __post_init__(self):
        if isinstance(self.signalType, str):
            self.signalType = SignalType(self.signalType)

        self.strength = max(0.0, min(1.0, self.strength))

    @property
    def isEntry(self) -> bool:
        """Check if this is an entry signal (LONG or SHORT). 진입 신호 여부."""
        return self.signalType in (SignalType.LONG, SignalType.SHORT)

    @property
    def isExit(self) -> bool:
        """Check if this is an exit signal. 청산 신호 여부."""
        return self.signalType in (SignalType.EXIT_LONG, SignalType.EXIT_SHORT, SignalType.EXIT_ALL)

    @property
    def isLong(self) -> bool:
        """Check if this is a long entry signal. 롱 신호 여부."""
        return self.signalType == SignalType.LONG

    @property
    def isShort(self) -> bool:
        """Check if this is a short entry signal. 숏 신호 여부."""
        return self.signalType == SignalType.SHORT

    def __repr__(self) -> str:
        priceStr = f" @ {self.price:,.0f}" if self.price else ""
        reasonStr = f" ({self.reason})" if self.reason else ""
        return (
            f"SignalEvent({self.symbol} {self.signalType.value.upper()} "
            f"strength={self.strength:.2f}{priceStr}{reasonStr})"
        )
