#!/usr/bin/env python3
"""
Fetch betting odds using BallDontLie MCP Server for comprehensive historical data.

This script leverages the official BallDontLie MCP server to access extensive
betting odds data across multiple sports and seasons.

Usage:
    python scripts/fetch_mcp_odds.py [sport] [season]

    sport: nba, nfl, nhl, mlb, epl, seriea, ucl, bundesliga, ligue1, or all (default: all)
    season: specific season year (default: current season)
"""

import os
import sys
import json
import time
from datetime import datetime, timedelta
from pathlib import Path
from typing import Dict, List, Any

# Import MCP server (assuming it's available in the environment)
try:
    # Try to import the MCP server components
    # Note: This may need adjustment based on how the MCP server is set up
    pass
except ImportError:
    print("MCP server components not available. Falling back to direct API calls.")

# Configuration
API_KEY = os.environ.get("BALLDONTLIE_API_KEY")
if not API_KEY:
    raise RuntimeError("BALLDONTLIE_API_KEY is not set. Put it in the environment (recommended: .env / systemd EnvironmentFile).")
BASE_URL = "https://api.balldontlie.io"

# Local data directories
DATA_DIR = Path(__file__).parent.parent / "data" / "betting"
ODDS_DIR = Path(__file__).parent.parent / "data" / "odds"

def make_api_request(endpoint: str, params: Dict[str, Any] = None) -> Dict[str, Any]:
    """Make a request to BallDontLie API."""
    import requests

    headers = {"Authorization": API_KEY}
    url = f"{BASE_URL}/{endpoint}"

    if params:
        # Convert params to query string
        query_parts = []
        for key, value in params.items():
            if isinstance(value, list):
                for item in value:
                    query_parts.append(f"{key}[]={item}")
            else:
                query_parts.append(f"{key}={value}")
        if query_parts:
            url += "?" + "&".join(query_parts)

    try:
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"API Error for {endpoint}: {e}")
        return {"error": str(e)}

def fetch_nba_odds_comprehensive(season: int = 2024) -> List[Dict[str, Any]]:
    """Fetch comprehensive NBA betting odds from BallDontLie API."""
    print(f"Fetching NBA odds for recent dates...")

    all_games = []

    # Get recent dates (last 30 days to avoid rate limits)
    from datetime import datetime, timedelta
    today = datetime.now()
    dates = [(today - timedelta(days=i)).strftime("%Y-%m-%d") for i in range(30)]

    for date in dates:
        print(f"  Fetching odds for {date}...", end=" ")

        try:
            # Use the correct odds endpoint
            data = make_api_request(f"v1/odds?date={date}")
            items = data.get("data", [])

            if not items:
                print("no data")
                continue

            print(f"{len(items)} odds entries")

            # Group odds by game_id
            games_by_id = {}

            for item in items:
                game_id = str(item.get("game_id", ""))
                if game_id not in games_by_id:
                    games_by_id[game_id] = {
                        "id": game_id,
                        "sport": "nba",
                        "date": date,
                        "season": season,
                        "odds": {
                            "source": "balldontlie_api"
                        }
                    }

                game = games_by_id[game_id]
                odds_type = item.get("type", "")
                vendor = item.get("vendor", "")

                # Parse different odds types
                if odds_type == "2way":  # Moneyline
                    if "odds_american_home" in item:
                        game["odds"]["moneylineHome"] = item["odds_american_home"]
                        game["odds"]["moneylineAway"] = item["odds_american_visitor"]

                elif odds_type == "spread":
                    if "away_spread" in item:
                        # For spread, we need to determine home/away based on the spread value
                        spread = float(item["away_spread"])
                        game["odds"]["spreadAway"] = spread
                        game["odds"]["spreadHome"] = -spread

                elif odds_type == "over/under":
                    if "over_under" in item:
                        game["odds"]["totalLine"] = float(item["over_under"])

            # Convert to list
            all_games.extend(games_by_id.values())

        except Exception as e:
            print(f"error: {e}")

        # Rate limiting
        import time
        time.sleep(0.5)

    print(f"Total unique games with odds: {len(all_games)}")
    return all_games

def fetch_nfl_odds_comprehensive(season: int = 2024) -> List[Dict[str, Any]]:
    """Fetch comprehensive NFL betting odds using MCP server."""
    print(f"Fetching NFL odds for {season} season...")

    all_odds = []

    try:
        # NFL season spans calendar years
        params = {
            "season": season,
            "per_page": 100
        }

        data = make_api_request(f"nfl/v1/odds?season={season}")
        items = data.get("data", [])

        print(f"Found {len(items)} NFL odds entries")

        # Process NFL odds data
        for item in items:
            game_data = {
                "id": str(item.get("game_id", "")),
                "sport": "nfl",
                "date": item.get("date", ""),
                "season": season,
                "week": item.get("week"),
                "home_team": item.get("home_team", {}).get("name", ""),
                "away_team": item.get("away_team", {}).get("name", ""),
                "odds": {
                    "moneylineHome": item.get("home_moneyline"),
                    "moneylineAway": item.get("away_moneyline"),
                    "spreadHome": item.get("home_spread"),
                    "spreadAway": item.get("away_spread"),
                    "totalLine": item.get("total"),
                    "source": "mcp_api"
                }
            }
            all_odds.append(game_data)

        return all_odds

    except Exception as e:
        print(f"Error fetching NFL odds: {e}")
        return []

def fetch_soccer_odds_comprehensive(league: str, season: str = "2024-2025") -> List[Dict[str, Any]]:
    """Fetch comprehensive soccer betting odds using MCP server."""
    print(f"Fetching {league.upper()} odds for {season} season...")

    all_odds = []

    try:
        # Map league names to MCP endpoints
        league_map = {
            "epl": "epl",
            "seriea": "seriea",
            "ucl": "ucl",
            "bundesliga": "bundesliga",
            "ligue1": "ligue1"
        }

        endpoint = league_map.get(league.lower())
        if not endpoint:
            print(f"Unknown league: {league}")
            return []

        params = {
            "season": season,
            "per_page": 100
        }

        data = make_api_request(f"{endpoint}/v1/odds?season={season}")
        items = data.get("data", [])

        print(f"Found {len(items)} {league.upper()} odds entries")

        # Process soccer odds data
        for item in items:
            game_data = {
                "id": str(item.get("match_id", "")),
                "sport": "soccer",
                "league": league.upper(),
                "date": item.get("date", ""),
                "season": season,
                "home_team": item.get("home_team", {}).get("name", ""),
                "away_team": item.get("away_team", {}).get("name", ""),
                "odds": {
                    "moneylineHome": item.get("home_moneyline"),
                    "moneylineAway": item.get("away_moneyline"),
                    "spreadHome": item.get("home_spread"),
                    "spreadAway": item.get("away_spread"),
                    "totalLine": item.get("total"),
                    "source": "mcp_api"
                }
            }
            all_odds.append(game_data)

        return all_odds

    except Exception as e:
        print(f"Error fetching {league.upper()} odds: {e}")
        return []

def merge_with_existing_data(new_odds: List[Dict[str, Any]], sport: str) -> List[Dict[str, Any]]:
    """Merge new odds data with existing historical data."""
    existing_file = DATA_DIR / f"{sport}_historical.json"

    if existing_file.exists():
        try:
            with open(existing_file, "r") as f:
                existing_data = json.load(f)

            # Create lookup by game ID to avoid duplicates
            existing_lookup = {game["id"]: game for game in existing_data}

            # Add new data
            merged_count = 0
            for game in new_odds:
                if game["id"] not in existing_lookup:
                    existing_data.append(game)
                    merged_count += 1
                else:
                    # Update existing game with new odds if available
                    existing_game = existing_lookup[game["id"]]
                    if game.get("odds") and not existing_game.get("odds", {}).get("source"):
                        existing_game["odds"] = game["odds"]
                        merged_count += 1

            print(f"Merged {merged_count} new games with existing data")
            return existing_data

        except Exception as e:
            print(f"Error merging data: {e}")
            return new_odds
    else:
        print("No existing data found, using new data only")
        return new_odds

def save_data(data: List[Dict[str, Any]], sport: str):
    """Save the merged data to file."""
    DATA_DIR.mkdir(parents=True, exist_ok=True)
    output_file = DATA_DIR / f"{sport}_historical.json"

    with open(output_file, "w") as f:
        json.dump(data, f, indent=2, default=str)

    print(f"Saved {len(data)} games to {output_file}")

    # Update metadata
    update_metadata(sport, len(data))

def update_metadata(sport: str, total_games: int):
    """Update the metadata file with new counts."""
    metadata_file = DATA_DIR / "metadata.json"

    try:
        if metadata_file.exists():
            with open(metadata_file, "r") as f:
                metadata = json.load(f)
        else:
            metadata = {
                "importedAt": datetime.now().isoformat(),
                "source": "BallDontLie MCP API",
                "sports": [],
                "seasons": []
            }

        # Update counts
        if sport not in [s["sport"] for s in metadata.get("sports", [])]:
            metadata["sports"].append({
                "sport": sport,
                "games": total_games,
                "hasOdds": True
            })
        else:
            for sport_info in metadata["sports"]:
                if sport_info["sport"] == sport:
                    sport_info["games"] = total_games

        metadata["importedAt"] = datetime.now().isoformat()

        with open(metadata_file, "w") as f:
            json.dump(metadata, f, indent=2)

    except Exception as e:
        print(f"Error updating metadata: {e}")

def process_sport(sport: str, season: int = None):
    """Process a specific sport."""
    print(f"\n{'='*60}")
    print(f"Processing {sport.upper()} via MCP Server")
    print(f"{'='*60}")

    if season is None:
        season = 2024  # Default to current season

    try:
        if sport.lower() == "nba":
            new_games = fetch_nba_odds_comprehensive(season)
        elif sport.lower() == "nfl":
            new_games = fetch_nfl_odds_comprehensive(season)
        elif sport.lower() in ["epl", "seriea", "ucl", "bundesliga", "ligue1"]:
            new_games = fetch_soccer_odds_comprehensive(sport, f"{season}-{season+1}")
        else:
            print(f"Sport {sport} not yet implemented")
            return 0

        if new_games:
            merged_data = merge_with_existing_data(new_games, sport.lower())
            save_data(merged_data, sport.lower())
            results[sport] = len(new_games)
        else:
            print(f"No new data found for {sport}")
            results[sport] = 0

    except Exception as e:
        print(f"Error processing {sport}: {e}")
        return 0

def main():
    """Main entry point."""
    print("=" * 60)
    print("BallDontLie MCP Server Odds Fetcher")
    print("=" * 60)
    print(f"Using API Key: {API_KEY[:8]}...")

    # Ensure directories exist
    DATA_DIR.mkdir(parents=True, exist_ok=True)
    ODDS_DIR.mkdir(parents=True, exist_ok=True)

    # Determine which sports to process
    sports_to_process = ["nba", "nfl", "nhl", "mlb", "epl", "seriea", "ucl", "bundesliga", "ligue1"]

    if len(sys.argv) > 1:
        arg = sys.argv[1].lower()
        if arg == "all":
            sports_to_process = ["nba", "nfl", "nhl", "mlb", "epl", "seriea", "ucl", "bundesliga", "ligue1"]
        elif arg in sports_to_process:
            sports_to_process = [arg]
        else:
            print(f"Unknown sport: {arg}")
            print(f"Available: {', '.join(sports_to_process)}, all")
            sys.exit(1)

    # Get season if specified
    season = None
    if len(sys.argv) > 2:
        try:
            season = int(sys.argv[2])
        except ValueError:
            print(f"Invalid season: {sys.argv[2]}")
            sys.exit(1)

    # Process each sport
    results = {}
    total_new_games = 0

    for sport in sports_to_process:
        new_games = process_sport(sport, season)
        results[sport] = new_games
        total_new_games += new_games

        # Rate limiting
        time.sleep(1)

    # Summary
    print(f"\n{'='*60}")
    print("MCP SERVER ODDS FETCH SUMMARY")
    print(f"{'='*60}")
    for sport, count in results.items():
        print("15")
    print(f"\nTotal new odds entries: {total_new_games}")

    if total_new_games > 0:
        print("✅ Successfully fetched new odds data via MCP server!")
        print("💡 Tip: Run this script daily to accumulate comprehensive historical data.")
    else:
        print("⚠️ No new odds data found. This might indicate:")
        print("   - API rate limiting")
        print("   - No new games with odds available")
        print("   - Try again later or check API status")

if __name__ == "__main__":
    main()
