"""Micro-trading module for the autonomous trading engine.

Pure computation module for micro-trade evaluation logic. Handles
allocation caps, daily limits, auto-close decisions, and constraint
checking. Actual signal fetching and order submission are deferred
to the engine integration layer.
"""

from __future__ import annotations

from dataclasses import dataclass

# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------


@dataclass
class MicroTradeConfig:
    """Configuration for the micro-trading module."""

    enabled: bool = False
    allocation_cap_pct: float = 0.03
    max_daily: int = 10
    max_hold_minutes: int = 120
    stop_loss_atr_multiplier: float = 1.0
    reward_risk_ratio: float = 1.5


# ---------------------------------------------------------------------------
# Micro-trading module (pure computation)
# ---------------------------------------------------------------------------


class MicroTradingModule:
    """Pure-computation micro-trading evaluator.

    All methods are side-effect-free. The engine integration layer is
    responsible for fetching signals, submitting orders, and persisting
    state.
    """

    def should_evaluate(
        self,
        config: MicroTradeConfig,
        daily_count: int,
    ) -> bool:
        """Check whether micro-trade evaluation should proceed.

        Args:
            config: Current micro-trade configuration.
            daily_count: Number of micro-trades already executed today.

        Returns:
            ``True`` if micro-trading is enabled and the daily limit
            has not been reached.
        """
        if not config.enabled:
            return False
        return daily_count < config.max_daily

    def compute_allocation_cap(
        self,
        config: MicroTradeConfig,
        active_pool: float,
    ) -> float:
        """Compute the maximum dollar allocation for a single micro-trade.

        Args:
            config: Current micro-trade configuration.
            active_pool: Current active pool value.

        Returns:
            Maximum dollar amount for a micro-trade.
        """
        return config.allocation_cap_pct * active_pool

    def should_auto_close(
        self,
        config: MicroTradeConfig,
        hold_minutes: float,
    ) -> bool:
        """Determine whether a micro-trade should be auto-closed.

        Args:
            config: Current micro-trade configuration.
            hold_minutes: How long the position has been held, in minutes.

        Returns:
            ``True`` when the hold duration exceeds the configured maximum.
        """
        return hold_minutes > config.max_hold_minutes

    def check_constraints(
        self,
        config: MicroTradeConfig,
        daily_count: int,
        is_within_window: bool,
        circuit_breaker_active: bool,
        portfolio_heat_pct: float,
        max_heat: float,
    ) -> tuple[bool, str]:
        """Check all constraints for a micro-trade.

        Evaluates trading window, circuit breakers, portfolio heat,
        daily limit, and enabled state.

        Args:
            config: Current micro-trade configuration.
            daily_count: Number of micro-trades already executed today.
            is_within_window: Whether the current time is within the
                trading window.
            circuit_breaker_active: Whether any circuit breaker is active.
            portfolio_heat_pct: Current portfolio heat as a fraction
                (e.g. 0.15 for 15%).
            max_heat: Maximum allowed portfolio heat fraction.

        Returns:
            Tuple of ``(allowed, reason)``. When ``allowed`` is ``False``,
            ``reason`` describes which constraint was violated.
        """
        if not config.enabled:
            return False, "micro_trading_disabled"

        if circuit_breaker_active:
            return False, "circuit_breaker_active"

        if not is_within_window:
            return False, "outside_trading_window"

        if daily_count >= config.max_daily:
            return False, "daily_limit_reached"

        if max_heat > 0 and portfolio_heat_pct >= max_heat:
            return False, "portfolio_heat_exceeded"

        return True, "ok"
