"""Summarise an odds-api.net history JSON response. No external packages needed.

Usage: python nbl_odds_analysis.py nbl-history.json
Optional: --home-odds 1.75 --away-odds 2.25
"""

import argparse
from datetime import datetime
import json
import math
from pathlib import Path


def decimal_price(value):
    if isinstance(value, bool):
        return None
    try:
        price = float(value)
    except (TypeError, ValueError):
        return None
    return price if math.isfinite(price) and price > 1 else None


def summarize_history(payload):
    price_type = payload.get("price_type", "odds")
    if price_type not in {"odds", "odds_no_vig", "fair_odds"}:
        raise ValueError("Unsupported history price_type")
    summaries = []
    for series in payload.get("series", []):
        observations = []
        for point in series.get("points", []):
            if point.get("is_available") is not True:
                continue
            value = point.get(price_type)
            price = decimal_price(value if value is not None else point.get("value"))
            if price is None:
                continue
            try:
                stamp = datetime.fromisoformat(point["tick_ts"].replace("Z", "+00:00"))
                if stamp.utcoffset() is None:
                    continue
            except (KeyError, TypeError, ValueError, AttributeError):
                continue
            observations.append((stamp, price))
        observations.sort(key=lambda item: item[0])
        if not observations:
            summaries.append({"bookmaker": series.get("bookmaker_name"), "sample_count": 0})
            continue
        first, last = observations[0][1], observations[-1][1]
        prices = [price for _, price in observations]
        summaries.append({
            "bookmaker": series.get("bookmaker_name"),
            "sample_count": len(prices),
            "first_tick": observations[0][0].isoformat(),
            "last_tick": observations[-1][0].isoformat(),
            "first_price": first,
            "last_price": last,
            "min_price": min(prices),
            "max_price": max(prices),
            "price_change_pct": round((last / first - 1) * 100, 4),
            "implied_probability_change_pp": round(100 / last - 100 / first, 4),
        })
    return {
        "event_id": payload.get("event_id"),
        "selection_key": payload.get("selection_key"),
        "price_type": price_type,
        "bookmakers": summaries,
    }


def two_way_market_stats(home_odds, away_odds):
    prices = [decimal_price(home_odds), decimal_price(away_odds)]
    if any(price is None for price in prices):
        raise ValueError("Both decimal prices must be finite numbers greater than 1")
    implied = [1 / price for price in prices]
    book = math.fsum(implied)
    return {
        "implied_probability_pct": [round(p * 100, 4) for p in implied],
        "overround_pct": round((book - 1) * 100, 4),
        "proportional_no_vig_probability_pct": [round(p / book * 100, 4) for p in implied],
    }


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("history_file", type=Path)
    parser.add_argument("--home-odds", type=float)
    parser.add_argument("--away-odds", type=float)
    args = parser.parse_args()
    if (args.home_odds is None) != (args.away_odds is None):
        parser.error("Supply both --home-odds and --away-odds for a two-outcome market")
    try:
        payload = json.loads(args.history_file.read_text(encoding="utf-8"))
        result = summarize_history(payload)
        if args.home_odds is not None:
            result["two_way_market"] = two_way_market_stats(args.home_odds, args.away_odds)
    except (OSError, ValueError, TypeError, AttributeError) as error:
        parser.error(str(error))
    print(json.dumps(result, indent=2, allow_nan=False))


if __name__ == "__main__":
    main()
