#!/usr/bin/env python3
"""
Scrape DraftKings for Quarter & Half Lines
Gets Q1-Q4 spreads/totals and 1H/2H lines that APIs don't provide.
Unlocks: Q4 (half spreads vs full game efficiency)

Run: Every 4 hours during betting hours
"""
import requests
import psycopg2
import json
import os
import time
from datetime import datetime, timezone

HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Accept': 'application/json',
    'Accept-Language': 'en-US,en;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'Origin': 'https://sportsbook.draftkings.com',
    'Referer': 'https://sportsbook.draftkings.com/',
}

# DraftKings sport IDs and event group IDs
SPORT_CONFIG = {
    'nba': {
        'event_group_id': 42648,  # NBA
        'sport_id': 3,
    },
    'nfl': {
        'event_group_id': 88808,  # NFL
        'sport_id': 1,
    },
    'nhl': {
        'event_group_id': 42133,  # NHL
        'sport_id': 6,
    },
    'ncaab': {
        'event_group_id': 92483,  # NCAAB
        'sport_id': 3,
    },
}

# Market categories we want (quarters, halves)
HALF_QUARTER_CATEGORIES = [
    '1st Half',
    '2nd Half',
    '1st Quarter',
    '2nd Quarter',
    '3rd Quarter',
    '4th Quarter',
    '1st Period',
    '2nd Period',
    '3rd Period',
]


def load_db_url():
    env_path = '/var/www/html/eventheodds/.env'
    try:
        with open(env_path, 'r') as f:
            for line in f:
                if line.startswith('SPORTS_DATABASE_URL='):
                    return line.split('=', 1)[1].strip().split('?')[0]
    except FileNotFoundError:
        pass
    return os.environ.get('SPORTS_DATABASE_URL', '').split('?')[0]


def fetch_dk_events(league):
    """Fetch events from DraftKings for a league"""
    config = SPORT_CONFIG.get(league)
    if not config:
        return []

    url = f"https://sportsbook-nash.draftkings.com/api/sportscontent/dkusva/v1/leagues/{config['event_group_id']}/categories/487"  # 487 = game lines

    try:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        if resp.status_code == 200:
            return resp.json()
        else:
            print(f"  DK API returned {resp.status_code}")
            return {}
    except Exception as e:
        print(f"  Error fetching DK events: {e}")
        return {}


def fetch_dk_event_markets(event_id):
    """Fetch all markets for a specific event including halves/quarters"""
    url = f"https://sportsbook-nash.draftkings.com/api/sportscontent/dkusva/v1/events/{event_id}/categories"

    try:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        if resp.status_code == 200:
            return resp.json()
        return {}
    except Exception as e:
        return {}


def fetch_dk_category_markets(event_id, category_id):
    """Fetch markets for a specific category (e.g., 1st Half)"""
    url = f"https://sportsbook-nash.draftkings.com/api/sportscontent/dkusva/v1/events/{event_id}/categories/{category_id}"

    try:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        if resp.status_code == 200:
            return resp.json()
        return {}
    except Exception as e:
        return {}


def parse_half_quarter_lines(data, event_info):
    """Parse half and quarter lines from DK response"""
    lines = []

    categories = data.get('categories', [])

    for category in categories:
        cat_name = category.get('name', '')

        # Check if this is a half/quarter category
        period = None
        for hq in HALF_QUARTER_CATEGORIES:
            if hq.lower() in cat_name.lower():
                period = hq.lower().replace(' ', '')
                break

        if not period:
            continue

        for subcategory in category.get('subcategories', []):
            for market in subcategory.get('markets', []):
                market_name = market.get('name', '').lower()

                # Determine market type
                market_type = None
                if 'spread' in market_name or 'handicap' in market_name:
                    market_type = 'spread'
                elif 'total' in market_name or 'over/under' in market_name:
                    market_type = 'total'
                elif 'moneyline' in market_name or 'winner' in market_name:
                    market_type = 'moneyline'

                if not market_type:
                    continue

                for selection in market.get('selections', []):
                    outcome = selection.get('outcome', '')
                    line = selection.get('points')
                    odds = selection.get('oddsAmerican')

                    if odds:
                        lines.append({
                            'event_id': event_info.get('id'),
                            'home_team': event_info.get('home'),
                            'away_team': event_info.get('away'),
                            'game_date': event_info.get('date'),
                            'period': period,
                            'market': market_type,
                            'side': outcome,
                            'line_value': line,
                            'odds': int(odds) if odds else None,
                        })

    return lines


def store_half_lines(conn, league, lines):
    """Store half/quarter lines in GameHalfLine table"""
    cur = conn.cursor()
    stored = 0

    for line in lines:
        try:
            # Find matching game
            game_id = None
            if line.get('home_team') and line.get('away_team'):
                cur.execute('''
                    SELECT id FROM "SportsGame"
                    WHERE league = %s
                      AND ("homeTeam" ILIKE %s OR "homeTeam" ILIKE %s)
                      AND ("awayTeam" ILIKE %s OR "awayTeam" ILIKE %s)
                      AND "gameDate" > NOW()
                      AND "gameDate" < NOW() + INTERVAL '7 days'
                    LIMIT 1
                ''', (league,
                      f"%{line['home_team']}%", line['home_team'],
                      f"%{line['away_team']}%", line['away_team']))
                result = cur.fetchone()
                if result:
                    game_id = result[0]

            # Insert or update
            cur.execute('''
                INSERT INTO "GameHalfLine"
                (league, "gameId", "gameDate", "homeTeam", "awayTeam",
                 period, market, side, "lineValue", "bookOdds", bookmaker, "createdAt", "updatedAt")
                VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 'draftkings', NOW(), NOW())
                ON CONFLICT DO NOTHING
            ''', (
                league,
                game_id,
                line.get('game_date'),
                line.get('home_team'),
                line.get('away_team'),
                line.get('period'),
                line.get('market'),
                line.get('side'),
                line.get('line_value'),
                line.get('odds'),
            ))
            stored += 1

        except Exception as e:
            continue

    conn.commit()
    cur.close()
    return stored


def scrape_league(conn, league):
    """Scrape half/quarter lines for a league"""
    print(f"\n{league.upper()}: Fetching DraftKings half/quarter lines...")

    # First try the direct API
    url = f"https://sportsbook.draftkings.com/leagues/{league}"

    # Alternative: use the offers API
    config = SPORT_CONFIG.get(league, {})
    event_group = config.get('event_group_id')

    if not event_group:
        print(f"  No config for {league}")
        return 0

    # Fetch event list
    events_url = f"https://sportsbook-nash.draftkings.com/sites/US-VA-SB/api/v5/eventgroups/{event_group}"

    try:
        resp = requests.get(events_url, headers=HEADERS, timeout=30)
        if resp.status_code != 200:
            print(f"  Events API returned {resp.status_code}")
            return 0

        data = resp.json()
    except Exception as e:
        print(f"  Error: {e}")
        return 0

    # Parse events
    events = []
    event_group_data = data.get('eventGroup', {})

    for event in event_group_data.get('events', []):
        event_id = event.get('eventId')
        name = event.get('name', '')

        # Parse teams from name (usually "Away @ Home")
        if ' @ ' in name:
            parts = name.split(' @ ')
            away = parts[0].strip()
            home = parts[1].strip()
        elif ' vs ' in name.lower():
            parts = name.lower().split(' vs ')
            away = parts[0].strip()
            home = parts[1].strip()
        else:
            continue

        events.append({
            'id': event_id,
            'home': home,
            'away': away,
            'date': event.get('startDate'),
        })

    print(f"  Found {len(events)} events")

    total_lines = 0

    # For each event, fetch half/quarter markets
    for event in events[:20]:  # Limit to avoid rate limiting
        event_id = event['id']

        # Fetch categories for this event
        cats_url = f"https://sportsbook-nash.draftkings.com/sites/US-VA-SB/api/v5/eventgroups/{event_group}/categories/game-lines/subcategories/game/{event_id}"

        try:
            resp = requests.get(cats_url, headers=HEADERS, timeout=15)
            if resp.status_code == 200:
                market_data = resp.json()

                # Look for half/quarter offer categories
                offer_cats = market_data.get('offerCategories', [])

                for cat in offer_cats:
                    cat_name = cat.get('name', '')

                    # Check if this is a period category
                    period = None
                    if '1st half' in cat_name.lower():
                        period = '1h'
                    elif '2nd half' in cat_name.lower():
                        period = '2h'
                    elif '1st quarter' in cat_name.lower() or '1st qtr' in cat_name.lower():
                        period = '1q'
                    elif '2nd quarter' in cat_name.lower() or '2nd qtr' in cat_name.lower():
                        period = '2q'
                    elif '3rd quarter' in cat_name.lower() or '3rd qtr' in cat_name.lower():
                        period = '3q'
                    elif '4th quarter' in cat_name.lower() or '4th qtr' in cat_name.lower():
                        period = '4q'
                    elif '1st period' in cat_name.lower():
                        period = 'p1'
                    elif '2nd period' in cat_name.lower():
                        period = 'p2'
                    elif '3rd period' in cat_name.lower():
                        period = 'p3'

                    if not period:
                        continue

                    # Parse offers in this category
                    for subcat in cat.get('offerSubcategoryDescriptors', []):
                        for offer in subcat.get('offerSubcategory', {}).get('offers', []):
                            for market in offer:
                                market_type = None
                                label = market.get('label', '').lower()

                                if 'spread' in label:
                                    market_type = 'spread'
                                elif 'total' in label:
                                    market_type = 'total'
                                elif 'moneyline' in label:
                                    market_type = 'moneyline'

                                if not market_type:
                                    continue

                                for outcome in market.get('outcomes', []):
                                    line_data = {
                                        'home_team': event['home'],
                                        'away_team': event['away'],
                                        'game_date': event['date'],
                                        'period': period,
                                        'market': market_type,
                                        'side': outcome.get('label', ''),
                                        'line_value': outcome.get('line'),
                                        'odds': outcome.get('oddsAmerican'),
                                    }

                                    # Store directly
                                    cur = conn.cursor()
                                    try:
                                        cur.execute('''
                                            INSERT INTO "GameHalfLine"
                                            (league, "gameDate", "homeTeam", "awayTeam",
                                             period, market, side, "lineValue", "bookOdds",
                                             bookmaker, "createdAt", "updatedAt")
                                            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s,
                                                    'draftkings', NOW(), NOW())
                                            ON CONFLICT DO NOTHING
                                        ''', (
                                            league,
                                            event['date'],
                                            event['home'],
                                            event['away'],
                                            period,
                                            market_type,
                                            outcome.get('label', ''),
                                            outcome.get('line'),
                                            outcome.get('oddsAmerican'),
                                        ))
                                        total_lines += 1
                                    except:
                                        pass
                                    cur.close()

        except Exception as e:
            continue

        conn.commit()
        time.sleep(0.5)  # Rate limiting

    print(f"  Stored {total_lines} half/quarter lines")
    return total_lines


def main():
    print("=" * 60)
    print("SCRAPE DRAFTKINGS HALF/QUARTER LINES")
    print(f"Time: {datetime.now(timezone.utc).isoformat()}")
    print("=" * 60)

    db_url = load_db_url()
    conn = psycopg2.connect(db_url)

    total = 0
    for league in ['nba', 'nfl', 'nhl', 'ncaab']:
        lines = scrape_league(conn, league)
        total += lines
        time.sleep(1)

    conn.close()

    print("\n" + "=" * 60)
    print(f"Total half/quarter lines stored: {total}")
    print("=" * 60)


if __name__ == '__main__':
    main()
