#!/usr/bin/env python3
import os, time
from pathlib import Path
from datetime import datetime, timedelta
import numpy as np
import pandas as pd
import requests
__import__('warnings').filterwarnings('ignore')

REPO = Path('/root/.openclaw/workspace-flj_bot1/football-predictor-repro')
OUT_DIR = REPO / 'artifacts' / 'odds_api_history'
ODDS_API_KEY = os.environ.get('ODDS_API_KEY', '08e1ca367452b446f7bee50bbc9d0fc1')
BASE = 'https://api.the-odds-api.com'

SPORT_LEAGUES = {
    'soccer_epl':                    ('e0', '英超'),
    'soccer_efl_champ':              ('e1', '英冠'),
    'soccer_england_league1':        ('e2', '英甲'),
    'soccer_england_league2':        ('e2n', '英乙'),
    'soccer_germany_bundesliga':      ('d1', '德甲'),
    'soccer_germany_bundesliga2':     ('d2', '德乙'),
    'soccer_france_ligue_one':       ('f1', '法甲'),
    'soccer_france_ligue_two':       ('f2', '法乙'),
    'soccer_italy_serie_a':          ('i1', '意甲'),
    'soccer_italy_serie_b':         ('i2', '意乙'),
    'soccer_spain_la_liga':          ('sp1', '西甲'),
    'soccer_spain_segunda_division': ('sp2', '西乙'),
    'soccer_turkey_super_league':    ('tr1', '土超'),
    'soccer_portugal_primeira_liga': ('p1', '葡超'),
    'soccer_belgium_first_div':      ('b1', '比甲'),
    'soccer_greece_super_league':    ('g1', '希腊超'),
    'soccer_netherlands_eredivisie':  ('n1', '荷兰甲'),
    'soccer_norway_eliteserien':      ('n2', '荷兰乙'),
    'soccer_spl':                     ('sc1', '苏超'),
    'soccer_russia_premier_league':    ('r1', '俄超'),
    'soccer_australia_aleague':       ('a1', '澳超'),
    'soccer_austria_bundesliga':       ('at1', '奥甲'),
    'soccer_usa_mls':                 ('m1', '美职联'),
    'soccer_japan_j_league':         ('j1', '日职联'),
}
SEASONS = [2023, 2024, 2025]

def season_dates(year):
    return (f"{year}-05-01", f"{year+1}-05-31")

def sample_dates(start, end, step=3):
    dates = []
    cur = datetime.strptime(start, '%Y-%m-%d')
    end_d = datetime.strptime(end, '%Y-%m-%d')
    while cur <= end_d:
        dates.append(cur.strftime('%Y-%m-%d'))
        cur += timedelta(days=step)
    return dates

def fetch_pinn(sport_key, dates, code):
    all_rows = []
    out_file = OUT_DIR / f"{code}_pinnacle_ah.csv"
    existing = set()
    if out_file.exists():
        try:
            ex = pd.read_csv(out_file)
            if 'Date' in ex.columns:
                existing = set(zip(ex['Date'].astype(str), ex['HomeTeam'].astype(str), ex['AwayTeam'].astype(str)))
        except: pass
    
    new_count = 0
    for d in dates:
        try:
            r = requests.get(f"{BASE}/v4/sports/{sport_key}/odds-history",
                params={'apiKey': ODDS_API_KEY, 'regions': 'eu', 'markets': 'spreads', 'date': f"{d}T12:00:00Z"},
                timeout=30)
            if r.status_code == 429:
                time.sleep(90)
                r = requests.get(f"{BASE}/v4/sports/{sport_key}/odds-history",
                    params={'apiKey': ODDS_API_KEY, 'regions': 'eu', 'markets': 'spreads', 'date': f"{d}T12:00:00Z"},
                    timeout=30)
            if r.status_code == 200:
                for event in r.json().get('data', []):
                    home = event.get('home_team', '')
                    away = event.get('away_team', '')
                    mtime = event.get('commence_time', '')[:10]
                    key = (mtime, home, away)
                    if key in existing:
                        continue
                    for bm in event.get('bookmakers', []):
                        if bm.get('key') != 'pinnacle':
                            continue
                        for mkt in bm.get('markets', []):
                            if mkt.get('key') != 'spreads':
                                continue
                            outcomes = mkt.get('outcomes', [])
                            if len(outcomes) < 2:
                                continue
                            home_pt = away_pt = None
                            home_pr = away_pr = None
                            for o in outcomes:
                                pt = o.get('point')
                                if pt is None:
                                    continue
                                try:
                                    pt_v = float(pt)
                                except:
                                    continue
                                pr = o.get('price')
                                if pr is None or float(pr) <= 1:
                                    continue
                                if pt_v > 0:
                                    home_pt = pt_v
                                    home_pr = float(pr)
                                elif pt_v < 0:
                                    away_pt = abs(pt_v)
                                    away_pr = float(pr)
                            if home_pt and away_pt and home_pr and away_pr and home_pr > 1 and away_pr > 1:
                                all_rows.append({'Date': mtime, 'HomeTeam': home, 'AwayTeam': away,
                                    'AHh': home_pt, 'B365AHH': home_pr, 'B365AHA': away_pr, 'odds_source': 'pinnacle'})
                                new_count += 1
                                existing.add(key)
            time.sleep(0.3)
        except Exception as e:
            continue
    
    if all_rows:
        df_new = pd.DataFrame(all_rows)
        ex_df = pd.read_csv(out_file) if out_file.exists() else pd.DataFrame()
        comb = pd.concat([ex_df, df_new], ignore_index=True).drop_duplicates(subset=['Date','HomeTeam','AwayTeam'])
        comb.to_csv(out_file, index=False, encoding='utf-8')
        print(f"  新增 {new_count} 条 → {len(comb)} 总行", flush=True)
    return new_count

print('=' * 60)
print('Pinnacle AH 数据采集')
print('=' * 60)
total = 0
for sport_key, (code, name) in SPORT_LEAGUES.items():
    print(f"\n[{code}] {name}")
    st = 0
    for season in SEASONS:
        s, e = season_dates(season)
        dates = sample_dates(s, e, step=3)
        print(f"  S{season} ({len(dates)}采样日)...", end=" ", flush=True)
        n = fetch_pinn(sport_key, dates, code)
        st += n
    print(f"  小计: {st} 条")
    total += st

print(f"\n✅ 完成！共 {total} 条新记录")
