"""
V11 — Market: ventana de 15 min en Polymarket.

Igual que V10: obtener tokens + strike. Outcome siempre oficial.
"""
import json, time, requests
from .config import Config, GAMMA_API, PRICE_API, UA, iso


class Market:
    def __init__(self, start_ts: int, cfg: Config):
        self.start_ts  = start_ts
        self.end_ts    = start_ts + cfg.win_secs
        self.slug      = f"{cfg.slug_prefix}{start_ts}"
        self.token_yes = None
        self.token_no  = None
        self.strike    = None
        self.strike_source = None
        self._cfg      = cfg

    def fetch_data(self, session: requests.Session,
                   binance_price: float = 0) -> bool:
        for attempt in range(8):
            try:
                r = session.get(
                    f"{GAMMA_API}/{self.slug}", timeout=10, headers=UA
                ).json()
                m = r["markets"][0]
                tokens = json.loads(m["clobTokenIds"])
                self.token_yes, self.token_no = tokens[0], tokens[1]

                # 1) Strike oficial de Polymarket
                try:
                    params = {
                        "symbol": self._cfg.price_symbol,
                        "eventStartTime": iso(self.start_ts),
                        "variant": self._cfg.price_variant,
                        "endDate": iso(self.end_ts),
                    }
                    pr = requests.get(
                        PRICE_API, params=params, timeout=5, headers=UA
                    ).json()
                    if pr.get("openPrice"):
                        self.strike = float(pr["openPrice"])
                        self.strike_source = "polymarket"
                        return True
                except Exception:
                    pass

                # 2) Fallback: precio Binance
                if binance_price > 0:
                    self.strike = binance_price
                    self.strike_source = "binance"
                    print(f"  [strike] usando Binance ${binance_price:,.2f} "
                          f"(polymarket.com bloqueado)")
                    return True

                print(f"[market] tokens OK pero sin strike disponible")
                return False
            except (ConnectionError, ConnectionResetError, OSError) as e:
                print(f"[market] intento {attempt+1}/8 (conn): {e}")
                session.close()
                session.__init__()
                session.headers.update(UA)
                time.sleep(2 + attempt)
            except Exception as e:
                print(f"[market] intento {attempt+1}/8: {e}")
                time.sleep(1 + attempt)
        return False

    def fetch_outcome(self, session: requests.Session) -> str | None:
        """Outcome oficial de Polymarket via Gamma API.
        NUNCA infiere — solo devuelve Up/Down cuando el mercado está resuelto.
        """
        for attempt in range(3):
            try:
                r = session.get(
                    f"{GAMMA_API}/{self.slug}", timeout=10, headers=UA
                ).json()
                m = r["markets"][0]
                closed = m.get("closed", False)
                uma    = (m.get("umaResolutionStatus") or "").lower()
                if not closed or uma != "resolved":
                    return None

                outcomes = m.get("outcomes")
                prices   = m.get("outcomePrices")
                if isinstance(outcomes, str):
                    outcomes = json.loads(outcomes)
                if isinstance(prices, str):
                    prices = json.loads(prices)

                if not outcomes or not prices or len(outcomes) != len(prices):
                    return None

                win_idx = None
                for i, p in enumerate(prices):
                    try:
                        if float(p) >= 0.99:
                            win_idx = i
                            break
                    except (TypeError, ValueError):
                        continue
                if win_idx is None:
                    return None

                label = str(outcomes[win_idx]).strip().lower()
                if label.startswith("up"):
                    return "Up"
                if label.startswith("down"):
                    return "Down"
                return None
            except (ConnectionError, ConnectionResetError, OSError) as e:
                print(f"[outcome] intento {attempt+1}/3 (conn): {e}")
                session.close()
                session.__init__()
                session.headers.update(UA)
                time.sleep(3)
            except Exception as e:
                print(f"[outcome] intento {attempt+1}/3: {e}")
                time.sleep(2)
        return None
