from __future__ import annotations

from dataclasses import dataclass
from decimal import Decimal
from enum import Enum
from typing import Any


class FuturesAction(str, Enum):
    OPEN_LONG = "OPEN_LONG"
    OPEN_SHORT = "OPEN_SHORT"
    CLOSE = "CLOSE"
    HOLD = "HOLD"


class FuturesPositionSide(str, Enum):
    LONG = "LONG"
    SHORT = "SHORT"
    FLAT = "FLAT"


class FuturesOrderSide(str, Enum):
    BUY = "BUY"
    SELL = "SELL"


@dataclass(frozen=True)
class FuturesSymbolMetadata:
    symbol: str
    base_asset: str
    quote_asset: str
    min_qty: Decimal
    step_size: Decimal
    tick_size: Decimal
    min_notional: Decimal

    def __post_init__(self) -> None:
        object.__setattr__(self, "symbol", self.symbol.upper())
        object.__setattr__(self, "base_asset", self.base_asset.upper())
        object.__setattr__(self, "quote_asset", self.quote_asset.upper())


@dataclass(frozen=True)
class FuturesPosition:
    symbol: str
    quantity: Decimal
    entry_price: Decimal
    mark_price: Decimal
    liquidation_price: Decimal
    isolated_margin: Decimal
    unrealized_pnl: Decimal
    leverage: int
    margin_type: str

    def __post_init__(self) -> None:
        object.__setattr__(self, "symbol", self.symbol.upper())
        object.__setattr__(self, "margin_type", self.margin_type.lower())

    @property
    def side(self) -> FuturesPositionSide:
        if self.quantity > 0:
            return FuturesPositionSide.LONG
        if self.quantity < 0:
            return FuturesPositionSide.SHORT
        return FuturesPositionSide.FLAT

    @property
    def absolute_quantity(self) -> Decimal:
        return abs(self.quantity)


@dataclass(frozen=True)
class FuturesPrediction:
    symbol: str
    action: FuturesAction
    confidence: Decimal
    reason: str
    leverage: int | None = None
    stop_loss_price: Decimal | None = None
    take_profit_price: Decimal | None = None
    close_percent: int | None = None

    def __post_init__(self) -> None:
        object.__setattr__(self, "symbol", self.symbol.upper())


@dataclass(frozen=True)
class FuturesRiskDecision:
    approved: bool
    reason: str
    prediction: FuturesPrediction
    leverage: int | None = None
    quantity: Decimal | None = None
    margin_amount: Decimal | None = None
    notional: Decimal | None = None


@dataclass(frozen=True)
class FuturesExecutionResult:
    run_id: int | None
    status: str
    symbol: str
    action: str
    reason: str
    confidence: Decimal | None = None
    leverage: int | None = None
    margin_amount: Decimal | None = None
    close_percent: int | None = None
    raw: dict[str, Any] | None = None

    def __post_init__(self) -> None:
        object.__setattr__(self, "symbol", self.symbol.upper() if self.symbol else "")
