"""Market resolution detection and settlement processing."""

from __future__ import annotations

import logging
import time
from collections import deque
from typing import Any

from horizon.fund._types import SettlementEvent

logger = logging.getLogger("horizon.fund.settlement")


class SettlementMonitor:
    """Detects market resolutions and records settlement events.

    Polls engine positions to detect markets that have resolved.
    When a market resolves, records the settlement event and signals
    the controller to clean up the position.
    """

    def __init__(self) -> None:
        self._events: deque[SettlementEvent] = deque(maxlen=10_000)
        self._resolved_markets: set[str] = set()
        self._settled_positions: dict[str, SettlementEvent] = {}  # "strategy:market" -> event

    def check_settlements(
        self,
        strategy_name: str,
        engine: Any,
    ) -> list[SettlementEvent]:
        """Check for resolved markets in a strategy's engine.

        Uses engine.check_resolutions() if available, otherwise
        checks positions for zero-value indicators.

        Returns:
            List of new settlement events detected.
        """
        new_events: list[SettlementEvent] = []
        now = time.time()

        try:
            positions = engine.positions()
        except Exception:
            return new_events

        for pos in positions:
            market_id = pos.market_id
            key = f"{strategy_name}:{market_id}"

            if key in self._resolved_markets:
                continue

            # Check if market has resolved via engine
            try:
                if hasattr(engine, "is_market_resolved"):
                    if not engine.is_market_resolved(market_id):
                        continue
                else:
                    continue
            except Exception:
                continue

            # Market resolved - determine outcome from position side + realized PnL
            realized = pos.realized_pnl if hasattr(pos, "realized_pnl") else 0.0
            # Positive size = long/YES side, negative size = short/NO side
            is_long = pos.size > 0
            side_str = "buy" if is_long else "sell"
            # Outcome: if realized > 0 we profited, meaning market resolved in our favor
            if realized > 0:
                outcome = "yes" if is_long else "no"
            elif realized < 0:
                outcome = "no" if is_long else "yes"
            else:
                outcome = "unknown"

            event = SettlementEvent(
                market_id=market_id,
                strategy_name=strategy_name,
                timestamp=now,
                outcome=outcome,
                pnl=realized,
                position_size=abs(pos.size),
                side=side_str,
            )
            new_events.append(event)
            self._resolved_markets.add(key)
            self._settled_positions[key] = event
            logger.info(
                "Settlement: %s/%s resolved=%s pnl=%.2f",
                strategy_name, market_id, outcome, realized,
            )

        self._events.extend(new_events)
        return new_events

    def recent_events(self, limit: int = 50) -> list[SettlementEvent]:
        """Return recent settlement events."""
        return list(self._events)[-limit:]

    @property
    def total_settlements(self) -> int:
        return len(self._events)

    @property
    def total_pnl(self) -> float:
        return sum(e.pnl for e in self._events)

    @property
    def settled_positions(self) -> list[tuple[str, str]]:
        """Return list of (strategy_name, market_id) pairs needing cleanup."""
        return [(e.strategy_name, e.market_id) for e in self._settled_positions.values()]
