#!/usr/bin/env python3
"""Generate Goal Number predictions for R1 (Russia Premier League) using R1-only model."""

from __future__ import annotations

import json
import os
from datetime import datetime, timedelta, timezone
from pathlib import Path

import joblib
import numpy as np
import pandas as pd
import requests

REPO_ROOT = Path(__file__).resolve().parents[1]
MODEL_PATH = REPO_ROOT / 'experiments' / 'goal_number_r1_only' / 'r1_goal_number_pipeline.pkl'
CONFIG_PATH = REPO_ROOT / 'experiments' / 'goal_number_r1_only' / 'r1_goal_number_config.json'
OUTPUT_DIR = REPO_ROOT / 'predictions'
LEAGUE_ID = 235  # Russia Premier League
LEAGUE_CODE = 'r1'
LEAGUE_NAME = '俄超'

BEIJING_TZ = timezone(timedelta(hours=8))

TEAM_ZH: dict = {
    'Lokomotiv': '火车头', 'Zenit': '泽尼特', 'CSKA Moscow': '莫斯科中央陆军',
    'Spartak Moscow': '莫斯科斯巴达', 'Dinamo Moscow': '莫斯科迪纳摩',
    'Krasnodar': '克拉斯诺达尔', 'FC Rostov': '罗斯托夫', 'Rubin': '喀山红宝石',
    'FC Sochi': '索契', 'Akhmat': '格罗兹尼艾哈迈特', 'FC Ufa': '乌法',
    'FC Orenburg': '奥伦堡', 'Arsenal Tula': '图拉兵工厂', 'FC Krasnodar-2': '克拉斯诺达尔B队',
    'Ural': '乌拉尔', 'FC Krylya Sovetov Samara': '萨马拉苏维埃之翼',
    'Nizhny Novgorod': '下诺夫哥罗德', 'Baltika': '巴蒂卡',
    'FC Orenburg-2': '奥伦堡B队', 'Fakel Voronezh': '沃罗涅日火炬',
    'Khimki': '希姆基', 'Torpedo Moscow': '莫斯科鱼雷', 'Pari NN': '帕里NN',
    'Dinamo Makhachkala': '马哈奇卡拉迪纳摩', 'Akhmat-2': '艾哈迈特B队',
}


def main() -> None:
    """Generate R1 goal number predictions."""
    print("Loading R1 goal-number model...")
    
    pipeline = joblib.load(MODEL_PATH)
    
    with open(CONFIG_PATH) as f:
        config = json.load(f)
    
    threshold = config.get('threshold', 0.74)
    print(f"Model threshold: {threshold:.2f}")
    print(f"Model accuracy: {config.get('bet_acc', 0):.2%}")
    
    print("\nFetching R1 fixtures and odds...")
    base_url = os.environ['API_FOOTBALL_BASE_URL'].rstrip('/')
    api_key = os.environ['API_FOOTBALL_KEY']
    session = requests.Session()
    session.headers.update({'x-apisports-key': api_key})
    
    now = datetime.now(timezone.utc)
    end = now + timedelta(hours=24)
    
    fixtures = []
    current_date = now.date()
    while current_date <= end.date():
        payload = session.get(base_url + '/fixtures', params={'league': LEAGUE_ID, 'date': current_date.isoformat()}, timeout=60).json()
        
        for item in payload.get('response', []):
            kickoff = datetime.fromtimestamp(item['fixture']['timestamp'], tz=timezone.utc)
            if now <= kickoff <= end:
                fixtures.append(item)
        
        current_date += timedelta(days=1)
    
    print(f"Found {len(fixtures)} R1 fixtures")
    
    if not fixtures:
        print("No R1 fixtures found in the next 24 hours.")
        return
    
    # Get odds for each fixture
    rows = []
    for item in fixtures:
        try:
            odds_payload = session.get(base_url + '/odds', params={'fixture': item['fixture']['id']}, timeout=60).json()
            response = odds_payload.get('response', [])
            if not response:
                continue
            
            # Get O/U odds
            ou_line = None
            over_odds = None
            under_odds = None
            bookmakers = response[0].get('bookmakers', [])
            
            for bookmaker in bookmakers:
                for bet in bookmaker.get('bets', []):
                    if bet.get('name') == 'Goals Over/Under':
                        for value in bet.get('values', []):
                            line_str = str(value.get('value', ''))
                            if 'Over' in line_str:
                                try:
                                    parts = line_str.split()
                                    if len(parts) == 2:
                                        ou_line = float(parts[1])
                                        over_odds = float(value.get('odd'))
                                except Exception:
                                    pass
                            elif 'Under' in line_str:
                                try:
                                    parts = line_str.split()
                                    if len(parts) == 2:
                                        under_odds = float(value.get('odd'))
                                except Exception:
                                    pass
            
            if ou_line is None or over_odds is None or under_odds is None:
                continue
            
            # Build features (default values since we don't have historical data for prediction)
            feature_row = {
                'home_gf_avg': 1.4,
                'home_ga_avg': 1.4,
                'away_gf_avg': 1.2,
                'away_ga_avg': 1.2,
                'home_tot_avg': 2.6,
                'away_tot_avg': 2.6,
                'home_over_rate': 0.5,
                'away_over_rate': 0.5,
                'home_home_gf_avg': 1.4,
                'home_home_ga_avg': 1.4,
                'away_away_gf_avg': 1.2,
                'away_away_ga_avg': 1.2,
                'home_home_over_rate': 0.5,
                'away_away_over_rate': 0.5,
                'home_gf_last5': 1.4,
                'home_ga_last5': 1.4,
                'away_gf_last5': 1.2,
                'away_ga_last5': 1.2,
                'home_over_last5': 0.5,
                'away_over_last5': 0.5,
                'expected_goals_proxy': ou_line,
                'combined_over_rate': 0.5,
            }
            
            # Predict
            X = pd.DataFrame([feature_row]).fillna(0)
            prob_over = float(pipeline.predict_proba(X)[0, 1])
            prob_under = 1.0 - prob_over
            conf = max(prob_over, prob_under)
            pred = '大球' if prob_over >= prob_under else '小球'
            
            home_team = item['teams']['home']['name']
            away_team = item['teams']['away']['name']
            kickoff_bj = datetime.fromtimestamp(item['fixture']['timestamp'], tz=timezone.utc).astimezone(BEIJING_TZ)
            
            rows.append({
                '开赛时间': kickoff_bj.strftime('%m-%d %H:%M'),
                '联赛': LEAGUE_NAME,
                '主队': TEAM_ZH.get(home_team, home_team),
                '客队': TEAM_ZH.get(away_team, away_team),
                '大小球盘口': ou_line,
                '大球赔率': round(over_odds, 2),
                '小球赔率': round(under_odds, 2),
                '大球概率': round(prob_over * 100, 1),
                '小球概率': round(prob_under * 100, 1),
                '预测方向': pred,
                '置信度': round(conf * 100, 1),
                '是否达阈值': '是' if conf >= threshold else '否',
                '推荐等级': '推荐' if conf >= threshold else '观望',
                '模型类型': f"俄超RF({config.get('model', 'RF')})",
                '模型回测命中率': round(config.get('bet_acc', 0.78) * 100, 1),
            })
        except Exception as e:
            print(f"Error processing fixture {item['fixture']['id']}: {e}")
            continue
    
    if not rows:
        print("No predictions generated!")
        return
    
    df = pd.DataFrame(rows)
    df = df.sort_values(['开赛时间', '置信度'], ascending=[True, False]).reset_index(drop=True)
    
    print(f"Generated {len(df)} predictions")
    
    # Save
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    csv_path = OUTPUT_DIR / 'goal_number_api_dynamic_24h.csv'
    xlsx_path = OUTPUT_DIR / 'goal_number_api_dynamic_24h.xlsx'
    
    df.to_csv(csv_path, index=False, encoding='utf-8-sig')
    with pd.ExcelWriter(xlsx_path, engine='openpyxl') as writer:
        df.to_excel(writer, index=False, sheet_name='24h_predictions')
    
    print(f"Saved to: {csv_path}")
    print(f"Saved to: {xlsx_path}")
    
    # Summary
    达阈值 = len(df[df['是否达阈值'] == '是'])
    print(f"\nSummary:")
    print(f"Total predictions: {len(df)}")
    print(f"达阈值: {达阈值} ({达阈值/len(df)*100:.1f}%)")
    print(f"Model accuracy: {config.get('bet_acc', 0):.2%}")


if __name__ == '__main__':
    main()
