"""Reserve Pool Controller — pure computation module.

Manages the untouchable cash reserve that grows from realized profits.
All methods are pure computations; persistence is handled by the caller.
"""

from __future__ import annotations

from services.trading.models import ReservePoolState  # noqa: F401 — re-export for convenience


class ReservePoolController:
    """Compute reserve-pool operations without touching the database.

    Parameters
    ----------
    siphon_pct:
        Fraction of realized profit transferred to the reserve on each
        profitable position close (default 20 %).
    high_water_pct:
        When the reserve exceeds this fraction of total portfolio value
        the risk-tier controller should consider upgrading (default 30 %).
    """

    def __init__(
        self,
        siphon_pct: float = 0.20,
        high_water_pct: float = 0.30,
    ) -> None:
        self.siphon_pct = siphon_pct
        self.high_water_pct = high_water_pct

    # ------------------------------------------------------------------
    # Profit siphoning
    # ------------------------------------------------------------------

    def siphon_profit(
        self,
        realized_profit: float,
        current_balance: float,
    ) -> tuple[float, float]:
        """Compute the amount to transfer into the reserve pool.

        Only positive profits are siphoned.

        Returns
        -------
        (transfer_amount, new_balance)
            *transfer_amount* is ``realized_profit * siphon_pct`` when
            the profit is positive, otherwise ``0.0``.
            *new_balance* is ``current_balance + transfer_amount``.
        """
        if realized_profit <= 0:
            return 0.0, current_balance

        transfer = realized_profit * self.siphon_pct
        return transfer, current_balance + transfer

    # ------------------------------------------------------------------
    # Emergency liquidation
    # ------------------------------------------------------------------

    def emergency_liquidate(self, current_balance: float) -> float:
        """Return the full reserve balance to be released into the active pool.

        The caller is responsible for zeroing the persisted balance and
        recording the ledger entry.

        Returns
        -------
        float
            The amount to release (equal to *current_balance*).
        """
        return current_balance

    # ------------------------------------------------------------------
    # Active pool computation
    # ------------------------------------------------------------------

    def compute_active_pool(
        self,
        total_portfolio_value: float,
        reserve_balance: float,
    ) -> float:
        """Active Pool = total portfolio value − reserve balance."""
        return total_portfolio_value - reserve_balance

    # ------------------------------------------------------------------
    # High-water mark detection
    # ------------------------------------------------------------------

    def is_high_water(
        self,
        reserve_balance: float,
        total_portfolio_value: float,
    ) -> bool:
        """Return ``True`` when the reserve exceeds *high_water_pct* of total portfolio."""
        if total_portfolio_value <= 0:
            return False
        return reserve_balance > self.high_water_pct * total_portfolio_value

    # ------------------------------------------------------------------
    # Emergency liquidation trigger check
    # ------------------------------------------------------------------

    def should_emergency_liquidate(
        self,
        current_drawdown_pct: float,
        emergency_threshold_pct: float,
    ) -> bool:
        """Return ``True`` when drawdown exceeds the emergency threshold."""
        return current_drawdown_pct > emergency_threshold_pct
