"""Trade guardrails: max order size and daily loss tracking."""

from __future__ import annotations

import threading
from datetime import UTC, datetime


class DailyLossTracker:
    """Tracks cumulative realized losses per UTC day.

    Thread-safe: all state mutations are protected by a lock to handle
    concurrent MCP tool calls safely.
    """

    def __init__(self, daily_limit: float) -> None:
        self._daily_limit = daily_limit
        self._date: str = ""
        self._cumulative_loss: float = 0.0
        self._lock = threading.Lock()

    @property
    def cumulative_loss(self) -> float:
        with self._lock:
            self._maybe_reset()
            return self._cumulative_loss

    @property
    def remaining(self) -> float:
        with self._lock:
            self._maybe_reset()
            return self._daily_limit - self._cumulative_loss

    def record_loss(self, amount: float) -> None:
        """Record a realized loss (positive value = loss)."""
        with self._lock:
            self._maybe_reset()
            if amount > 0:
                self._cumulative_loss += amount

    def check(self) -> str | None:
        """Return an error message if daily loss limit is breached, else None."""
        with self._lock:
            self._maybe_reset()
            if self._cumulative_loss >= self._daily_limit:
                return (
                    f"Daily loss limit reached: "
                    f"${self._cumulative_loss:.2f} / ${self._daily_limit:.2f}"
                )
            return None

    def _maybe_reset(self) -> None:
        """Reset if the UTC date has changed. Must be called under lock."""
        today = datetime.now(UTC).strftime("%Y-%m-%d")
        if self._date != today:
            self._date = today
            self._cumulative_loss = 0.0


MIN_ORDER_USD = 10.0  # Hyperliquid platform minimum


def min_token_amount(mark_price: float) -> float:
    """Minimum token quantity based on current price and $10 USD floor."""
    if mark_price <= 0:
        return 0.0
    return MIN_ORDER_USD / mark_price


def min_order_info(mark_price: float) -> dict:
    """Return min order constraints for a given mark price."""
    return {
        "min_order_usd": MIN_ORDER_USD,
        "min_token_amount": min_token_amount(mark_price),
        "mark_price": mark_price,
    }


_loss_tracker: DailyLossTracker | None = None


def get_loss_tracker(daily_limit: float) -> DailyLossTracker:
    """Return the shared DailyLossTracker, creating it on first call."""
    global _loss_tracker
    if _loss_tracker is None:
        _loss_tracker = DailyLossTracker(daily_limit)
    return _loss_tracker


def reset_loss_tracker() -> None:
    """Reset the shared loss tracker (for testing)."""
    global _loss_tracker
    _loss_tracker = None


def check_max_order(size: float, max_order_usd: float) -> str | None:
    """Return an error message if size is outside bounds, else None."""
    if size < MIN_ORDER_USD:
        return f"Order size ${size:.2f} below Hyperliquid minimum ${MIN_ORDER_USD:.2f}"
    if size > max_order_usd:
        return f"Order size ${size:.2f} exceeds max ${max_order_usd:.2f}"
    return None
