"""Market manager — creates and rotates 5min/15min BTC prediction markets."""

import hashlib
import time
from dataclasses import dataclass, field

from orderbook import OrderBook, generate_mock_book, book_to_dict, PRICE_SCALE


def generate_market_id(interval: int, boundary_ts: int) -> str:
    """Market ID is based only on interval + boundary timestamp, not price."""
    raw = f"TURBO-BTC-{interval}m-{boundary_ts}"
    return "0x" + hashlib.sha256(raw.encode()).hexdigest()[:16]


def get_current_boundary(interval_minutes: int) -> tuple[int, int]:
    now = int(time.time())
    interval_secs = interval_minutes * 60
    start = (now // interval_secs) * interval_secs
    end = start + interval_secs
    return start, end


@dataclass
class Market:
    market_id: str = ""
    interval: int = 15
    strike_price: float = 0.0
    start_time: int = 0
    end_time: int = 0
    resolved: bool = False
    winning_outcome: int | None = None  # 0=YES, 1=NO
    yes_book: OrderBook = field(default_factory=OrderBook)
    no_book: OrderBook = field(default_factory=OrderBook)


@dataclass
class ResolvedMarket:
    market_id: str
    interval: int
    strike_price: float
    start_time: int
    end_time: int
    winning_outcome: int  # 0=YES, 1=NO
    final_price: float


class MarketManager:
    """Manages rolling BTC prediction markets for one interval (5 or 15 min)."""

    def __init__(self, interval: int):
        self.interval = interval
        self.market = Market(interval=interval)
        self.btc_price: float = 0.0
        self.pyth_mid: float = 0.5
        self.history: list[ResolvedMarket] = []

    def check_rotation(self) -> bool:
        """Rotate to current window. Returns True if rotated."""
        start, end = get_current_boundary(self.interval)
        expected_id = generate_market_id(self.interval, start)

        if self.market.market_id != expected_id and self.btc_price > 0:
            # Resolve old market if it existed
            if self.market.market_id and not self.market.resolved:
                outcome = 0 if self.btc_price >= self.market.strike_price else 1
                self.history.append(ResolvedMarket(
                    market_id=self.market.market_id,
                    interval=self.interval,
                    strike_price=self.market.strike_price,
                    start_time=self.market.start_time,
                    end_time=self.market.end_time,
                    winning_outcome=outcome,
                    final_price=self.btc_price,
                ))
                if len(self.history) > 50:
                    self.history = self.history[-50:]

            self.market = Market(
                market_id=expected_id,
                interval=self.interval,
                strike_price=self.btc_price,
                start_time=start,
                end_time=end,
            )
            return True
        return False

    def update_books(self):
        if self.btc_price <= 0 or not self.market.market_id:
            return
        if self.market.strike_price > 0:
            diff_pct = (self.btc_price - self.market.strike_price) / self.market.strike_price
            self.pyth_mid = max(0.05, min(0.95, 0.5 + diff_pct * 5))
        else:
            self.pyth_mid = 0.5

        self.market.yes_book = generate_mock_book(self.pyth_mid)
        self.market.no_book = generate_mock_book(1.0 - self.pyth_mid)

    def time_remaining(self) -> int:
        if self.market.end_time == 0:
            return 0
        return max(0, self.market.end_time - int(time.time()))

    def to_dict(self) -> dict:
        tr = self.time_remaining()
        return {
            "marketId": self.market.market_id,
            "interval": self.interval,
            "asset": "BTC",
            "strikePrice": self.market.strike_price,
            "startPrice": int(self.market.strike_price * 1e6),
            "startTime": self.market.start_time,
            "endTime": self.market.end_time,
            "resolved": self.market.resolved,
            "btcPrice": self.btc_price,
            "pythMid": self.pyth_mid,
            "timeRemaining": f"{tr // 60}:{tr % 60:02d}",
            "secondsRemaining": tr,
            "yesBook": book_to_dict(self.market.yes_book),
            "noBook": book_to_dict(self.market.no_book),
        }

    def history_list(self) -> list[dict]:
        return [
            {
                "marketId": m.market_id,
                "interval": m.interval,
                "strikePrice": m.strike_price,
                "startPrice": int(m.strike_price * 1e6),
                "startTime": m.start_time,
                "endTime": m.end_time,
                "resolved": True,
                "winningOutcome": m.winning_outcome,
                "finalPrice": m.final_price,
            }
            for m in reversed(self.history)
        ]
