from __future__ import annotations

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


class CandidateStatus(str, Enum):
    RESEARCH = "research"
    WATCHLIST = "watchlist"
    CANDIDATE = "candidate"
    LIVE_PREVIEW_READY = "live_preview_ready"
    BLOCKED = "blocked"


class SignalDecision(str, Enum):
    ALLOW_SHADOW = "allow_shadow"
    BLOCK = "block"


@dataclass(frozen=True)
class CopyCostInput:
    """Conservative follower cost model inputs.

    Percent fields are human percentages, e.g. Decimal("0.045") means 0.045%.
    """

    notional_usd: Decimal
    gross_pnl_usd: Decimal
    entry_fee_pct: Decimal = Decimal("0.045")
    exit_fee_pct: Decimal = Decimal("0.045")
    spread_pct: Decimal = Decimal("0")
    modeled_slippage_pct: Decimal = Decimal("0")
    funding_usd: Decimal = Decimal("0")
    delay_penalty_usd: Decimal = Decimal("0")


@dataclass(frozen=True)
class CopyCostBreakdown:
    gross_pnl_usd: Decimal
    entry_fee_usd: Decimal
    exit_fee_usd: Decimal
    spread_cost_usd: Decimal
    modeled_slippage_usd: Decimal
    funding_usd: Decimal
    delay_penalty_usd: Decimal
    net_pnl_usd: Decimal


@dataclass(frozen=True)
class LeaderMetrics:
    leader_id: str
    age_days: int
    closed_shadow_trades: int
    shadow_days: int
    realized_pnl_usd: Decimal
    unrealized_pnl_share: Decimal
    max_drawdown_pct: Decimal
    profit_factor_after_costs: Decimal
    net_pnl_after_costs_usd: Decimal
    top_leader_pnl_share: Decimal = Decimal("0")
    top_coin_pnl_share: Decimal = Decimal("0")
    top_trade_pnl_share: Decimal = Decimal("0")
    single_coin_pnl_share: Decimal = Decimal("0")
    avg_liquidation_distance_pct: Decimal = Decimal("999")
    market_phases_observed: int = 0
    leader_correlation: Decimal = Decimal("0")
    coin_overlap: Decimal = Decimal("0")
    direction_overlap: Decimal = Decimal("0")
    regime_overlap: Decimal = Decimal("0")
    drawdown_overlap: Decimal = Decimal("0")
    crowding_score: Decimal = Decimal("0")
    abrupt_style_change: bool = False
    hidden_hedge_risk: bool = False


@dataclass(frozen=True)
class LeaderScorecard:
    leader_id: str
    status: CandidateStatus
    reasons: tuple[str, ...]
    metrics: LeaderMetrics


@dataclass(frozen=True)
class PositionCopySignal:
    leader_id: str
    coin: str
    side: str
    position_age_hours: Decimal
    leader_profit_r: Decimal
    distance_to_leader_entry_pct: Decimal
    spread_pct: Decimal
    depth_ok: bool
    leader_liquidation_distance_pct: Decimal
    funding_rate_hourly_pct: Decimal
    duplicate_exposure: bool = False
    is_position_level: bool = True
    metadata: dict[str, Any] = field(default_factory=dict)


@dataclass(frozen=True)
class CopyGateConfig:
    min_position_age_hours: Decimal = Decimal("6")
    max_leader_profit_r_to_enter: Decimal = Decimal("0.5")
    max_distance_to_leader_entry_pct: Decimal = Decimal("0.75")
    max_spread_pct: Decimal = Decimal("0.08")
    min_liquidation_distance_pct: Decimal = Decimal("8")
    max_abs_funding_rate_hourly_pct: Decimal = Decimal("0.02")


@dataclass(frozen=True)
class CopyGateDecision:
    decision: SignalDecision
    reasons: tuple[str, ...]
    signal: PositionCopySignal


@dataclass(frozen=True)
class VaultSnapshot:
    vault_id: str
    observed_at_ms: int
    source: str
    raw: dict[str, Any]


@dataclass(frozen=True)
class WalletSnapshot:
    wallet_address: str
    observed_at_ms: int
    source: str
    raw: dict[str, Any]
