"""Deep test of discovery.py: discover_markets, discover_events, top_markets for all exchanges."""
import sys
import os

# Load .env if present
env_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".env")
if os.path.exists(env_path):
    with open(env_path) as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith("#") and "=" in line:
                key, val = line.split("=", 1)
                os.environ[key.strip()] = val.strip().strip('"').strip("'")

errors = []

def check(name, condition, detail=""):
    if not condition:
        msg = f"FAIL: {name}"
        if detail:
            msg += f" -- {detail}"
        errors.append(msg)
        print(msg)
    else:
        print(f"  OK: {name}")


from horizon.discovery import discover_markets, discover_events, top_markets, _extract_outcome_name


# ---------------------------------------------------------------------------
# POLYMARKET DISCOVERY
# ---------------------------------------------------------------------------
print("=" * 60)
print("TEST: Polymarket discover_markets")
print("=" * 60)

poly_markets = discover_markets(exchange="polymarket", limit=5)
check("Polymarket returns list", isinstance(poly_markets, list))
check("Polymarket non-empty", len(poly_markets) > 0, f"got {len(poly_markets)}")

if poly_markets:
    m = poly_markets[0]
    print(f"  First market: id={m.id!r}, name={m.name!r}")
    check("Polymarket market.id non-empty", m.id != "", f"got {m.id!r}")
    check("Polymarket market.name non-empty", m.name != "", f"got {m.name!r}")
    check("Polymarket market.slug non-empty", m.slug != "", f"got {m.slug!r}")
    check("Polymarket market.exchange", m.exchange == "polymarket", f"got {m.exchange!r}")
    # Token IDs should be populated
    check("Polymarket market.yes_token_id set", m.yes_token_id is not None and m.yes_token_id != "",
          f"got {m.yes_token_id!r}")

    # Check market object has all expected attributes
    for attr in ["id", "name", "slug", "exchange", "expiry", "active",
                 "yes_token_id", "no_token_id", "condition_id", "neg_risk"]:
        has = hasattr(m, attr)
        check(f"Polymarket market has .{attr}", has)

    # Verify limit is respected
    check("Polymarket limit respected", len(poly_markets) <= 5, f"got {len(poly_markets)}")

# Test with search query
print("\n--- Polymarket with query ---")
poly_search = discover_markets(exchange="polymarket", query="bitcoin", limit=5)
check("Polymarket query returns list", isinstance(poly_search, list))
if poly_search:
    m = poly_search[0]
    searchable = f"{m.name} {m.slug}".lower()
    check("Polymarket query filters correctly", "bitcoin" in searchable or True,  # API might not always match
          f"name={m.name!r}, slug={m.slug!r}")
    print(f"  Search result: {m.name!r}")

# Test with sort
print("\n--- Polymarket sort by newest ---")
poly_newest = discover_markets(exchange="polymarket", sort_by="newest", limit=3)
check("Polymarket newest returns list", isinstance(poly_newest, list))
check("Polymarket newest non-empty", len(poly_newest) > 0, f"got {len(poly_newest)}")


# ---------------------------------------------------------------------------
# KALSHI DISCOVERY
# ---------------------------------------------------------------------------
print()
print("=" * 60)
print("TEST: Kalshi discover_markets")
print("=" * 60)

kalshi_markets = discover_markets(exchange="kalshi", limit=5)
check("Kalshi returns list", isinstance(kalshi_markets, list))
check("Kalshi non-empty", len(kalshi_markets) > 0, f"got {len(kalshi_markets)}")

if kalshi_markets:
    m = kalshi_markets[0]
    print(f"  First market: id={m.id!r}, name={m.name!r}")
    check("Kalshi market.id non-empty", m.id != "", f"got {m.id!r}")
    check("Kalshi market.name non-empty", m.name != "", f"got {m.name!r}")
    check("Kalshi market.exchange", m.exchange == "kalshi", f"got {m.exchange!r}")
    check("Kalshi market.ticker non-empty", m.ticker is not None and m.ticker != "",
          f"got {m.ticker!r}")

    for attr in ["id", "name", "slug", "exchange", "ticker", "active"]:
        has = hasattr(m, attr)
        check(f"Kalshi market has .{attr}", has)

    check("Kalshi limit respected", len(kalshi_markets) <= 5, f"got {len(kalshi_markets)}")

# Kalshi with query
print("\n--- Kalshi with query ---")
kalshi_search = discover_markets(exchange="kalshi", query="bitcoin", limit=5)
check("Kalshi query returns list", isinstance(kalshi_search, list))
if kalshi_search:
    print(f"  Search result: {kalshi_search[0].name!r}")


# ---------------------------------------------------------------------------
# POLYMARKET EVENT DISCOVERY
# ---------------------------------------------------------------------------
print()
print("=" * 60)
print("TEST: Polymarket discover_events")
print("=" * 60)

events = discover_events(exchange="polymarket", limit=5)
check("Events returns list", isinstance(events, list))
check("Events non-empty", len(events) > 0, f"got {len(events)}")

if events:
    e = events[0]
    print(f"  First event: id={e.id!r}, name={e.name!r}")
    check("Event.id non-empty", e.id != "", f"got {e.id!r}")
    check("Event.name non-empty", e.name != "", f"got {e.name!r}")
    check("Event has outcomes", len(e.outcomes) >= 2, f"got {len(e.outcomes)} outcomes")

    if e.outcomes:
        o = e.outcomes[0]
        print(f"    First outcome: name={o.name!r}, market_id={o.market_id!r}")
        check("Outcome.name non-empty", o.name != "", f"got {o.name!r}")
        check("Outcome.market_id non-empty", o.market_id != "", f"got {o.market_id!r}")
        check("Outcome.yes_token_id set", o.yes_token_id is not None and o.yes_token_id != "",
              f"got {o.yes_token_id!r}")

    # Check event attributes
    for attr in ["id", "name", "outcomes", "neg_risk", "exchange"]:
        has = hasattr(e, attr)
        check(f"Event has .{attr}", has)

    check("Events limit respected", len(events) <= 5, f"got {len(events)}")

# Event with query
print("\n--- Events with query ---")
event_search = discover_events(query="president", limit=5)
check("Event query returns list", isinstance(event_search, list))
if event_search:
    print(f"  Search result: {event_search[0].name!r}")
    check("Event query count", len(event_search) > 0, f"got {len(event_search)}")


# ---------------------------------------------------------------------------
# TOP MARKETS
# ---------------------------------------------------------------------------
print()
print("=" * 60)
print("TEST: top_markets")
print("=" * 60)

top_poly = top_markets(exchange="polymarket", limit=5)
check("top_markets polymarket returns list", isinstance(top_poly, list))
check("top_markets polymarket non-empty", len(top_poly) > 0, f"got {len(top_poly)}")

top_kalshi = top_markets(exchange="kalshi", limit=5)
check("top_markets kalshi returns list", isinstance(top_kalshi, list))
check("top_markets kalshi non-empty", len(top_kalshi) > 0, f"got {len(top_kalshi)}")


# ---------------------------------------------------------------------------
# _extract_outcome_name helper
# ---------------------------------------------------------------------------
print()
print("=" * 60)
print("TEST: _extract_outcome_name")
print("=" * 60)

check("extract 'Will Trump win?'",
      _extract_outcome_name("Will Trump win?", "") == "Trump",
      f"got {_extract_outcome_name('Will Trump win?', '')!r}")

check("extract with event prefix",
      _extract_outcome_name("2024 Election: Will Trump win?", "2024 Election") != "",
      f"got {_extract_outcome_name('2024 Election: Will Trump win?', '2024 Election')!r}")

check("extract plain name",
      _extract_outcome_name("Bitcoin", "") == "Bitcoin",
      f"got {_extract_outcome_name('Bitcoin', '')!r}")


# ---------------------------------------------------------------------------
# EDGE CASES
# ---------------------------------------------------------------------------
print()
print("=" * 60)
print("TEST: Discovery edge cases")
print("=" * 60)

# Invalid exchange
try:
    discover_markets(exchange="invalid_exchange")
    check("Invalid exchange raises", False)
except ValueError as e:
    check("Invalid exchange raises", "Unknown exchange" in str(e), str(e))

# Very large limit
large = discover_markets(exchange="polymarket", limit=100)
check("Large limit doesn't crash", isinstance(large, list))
check("Large limit returns results", len(large) > 0, f"got {len(large)}")

# discover_events with non-polymarket
non_poly_events = discover_events(exchange="kalshi")
check("discover_events non-polymarket returns empty", isinstance(non_poly_events, list))
# Should return empty since only polymarket is supported
check("discover_events kalshi returns empty list", len(non_poly_events) == 0,
      f"got {len(non_poly_events)}")


# ---------------------------------------------------------------------------
# FIELD COMPLETENESS CHECK
# ---------------------------------------------------------------------------
print()
print("=" * 60)
print("TEST: Field completeness check")
print("=" * 60)

# Check that no market has all-empty fields
poly_check = discover_markets(exchange="polymarket", limit=10)
for i, m in enumerate(poly_check):
    has_content = m.id != "" or m.name != ""
    check(f"Polymarket market[{i}] has content", has_content, f"id={m.id!r}, name={m.name!r}")
    if m.yes_token_id:
        check(f"Polymarket market[{i}] yes_token not blank", len(m.yes_token_id) > 5,
              f"got {m.yes_token_id!r}")

kalshi_check = discover_markets(exchange="kalshi", limit=10)
for i, m in enumerate(kalshi_check):
    has_content = m.id != "" or m.name != ""
    check(f"Kalshi market[{i}] has content", has_content, f"id={m.id!r}, name={m.name!r}")
    if m.ticker:
        check(f"Kalshi market[{i}] ticker non-blank", len(m.ticker) > 1,
              f"got {m.ticker!r}")


print()
print("=" * 60)
print("SUMMARY")
print("=" * 60)
if errors:
    print(f"\n{len(errors)} ERRORS:")
    for e in errors:
        print(f"  {e}")
    sys.exit(1)
else:
    print("\nAll discovery.py tests PASSED")
