#!/usr/bin/env python3
"""
BetPredictAI - Live Score Checker (Multi-Source)

Sistema multi-sorgente per verificare risultati in tempo reale:
1. Primary: football-data.org API (se API key presente)
2. Fallback: API-Football via RapidAPI (free tier)
3. Backup: Web scraping da fonti pubbliche

Calcola automaticamente quando verificare:
- Partita regolare: kickoff + 105 minuti
- Supplementari: +30 minuti extra
- Rigori: +20 minuti extra

Uso: python3 live_score_checker.py
"""

import os
import sys
import json
import requests
from datetime import datetime, timedelta
from bs4 import BeautifulSoup
import time
import logging
import re

# Setup logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] %(message)s',
    handlers=[
        logging.FileHandler('/var/www/html/bet.cuttalo.com/logs/live_scores.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(BASE_DIR, '..', 'data')

# League mappings
LEAGUE_MAP = {
    'E0': {'name': 'Premier League', 'country': 'England', 'search': 'premier league'},
    'D1': {'name': 'Bundesliga', 'country': 'Germany', 'search': 'bundesliga'},
    'I1': {'name': 'Serie A', 'country': 'Italy', 'search': 'serie a'},
    'SP1': {'name': 'La Liga', 'country': 'Spain', 'search': 'la liga'},
    'F1': {'name': 'Ligue 1', 'country': 'France', 'search': 'ligue 1'},
}


def load_predictions():
    """Load upcoming predictions that need verification"""
    path = os.path.join(DATA_DIR, 'predictions_upcoming.json')
    if os.path.exists(path):
        with open(path) as f:
            return json.load(f)
    return []


def load_verification():
    """Load current verification data"""
    path = os.path.join(DATA_DIR, 'verification_results.json')
    if os.path.exists(path):
        with open(path) as f:
            return json.load(f)
    return {
        'generated_at': datetime.now().isoformat(),
        'model_version': 'V4-Advanced',
        'summary': {'total': 0, 'correct': 0, 'accuracy': 0},
        'results': [],
        'top_verified': []
    }


def save_verification(data):
    """Save verification with updated stats"""
    results = data.get('results', [])
    total = len(results)
    correct = sum(1 for r in results if r.get('correct', False))

    data['summary'] = {
        'total': total,
        'correct': correct,
        'accuracy': round(100 * correct / total, 1) if total > 0 else 0
    }
    data['generated_at'] = datetime.now().isoformat()

    # Update top verified
    data['top_verified'] = sorted(
        [r for r in results if r.get('correct', False)],
        key=lambda x: x.get('confidence', 0),
        reverse=True
    )[:20]

    # Recalculate by confidence
    by_confidence = {}
    for threshold in [40, 45, 50, 55, 60, 65, 70]:
        high_conf = [r for r in results if r.get('confidence', 0) >= threshold]
        if high_conf:
            high_conf_correct = sum(1 for r in high_conf if r.get('correct', False))
            by_confidence[threshold] = {
                'total': len(high_conf),
                'correct': high_conf_correct,
                'accuracy': round(100 * high_conf_correct / len(high_conf), 1)
            }
    data['by_confidence'] = by_confidence

    path = os.path.join(DATA_DIR, 'verification_results.json')
    with open(path, 'w') as f:
        json.dump(data, f, indent=2)

    logger.info(f"Saved: {correct}/{total} correct ({data['summary']['accuracy']}%)")


def should_check_match(match_date, match_time):
    """
    Determine if enough time has passed to check for result.

    Returns: (should_check, buffer_type)
    - buffer_type: 'regular', 'extra_time', 'too_early', 'too_late'
    """
    try:
        # Parse match datetime
        match_dt_str = f"{match_date} {match_time}"
        match_dt = datetime.strptime(match_dt_str, '%Y-%m-%d %H:%M')

        now = datetime.now()
        elapsed = (now - match_dt).total_seconds() / 60  # minutes

        if elapsed < 0:
            return False, 'future'
        elif elapsed < 95:  # Match still in progress (90 + 5 min buffer)
            return False, 'in_progress'
        elif elapsed < 115:  # Regular time finished
            return True, 'regular'
        elif elapsed < 145:  # Extra time window
            return True, 'extra_time'
        elif elapsed < 165:  # Penalty window
            return True, 'penalties'
        elif elapsed < 1440:  # Within 24 hours
            return True, 'late'
        else:
            return False, 'too_old'

    except Exception as e:
        logger.error(f"Error parsing time: {e}")
        return False, 'error'


def fetch_result_livescore_api(home_team, away_team, match_date):
    """
    Fetch result from free livescore sources.
    Uses multiple fallback methods.
    """
    # Method 1: Try sofascore API-like endpoint
    try:
        date_obj = datetime.strptime(match_date, '%Y-%m-%d')
        formatted_date = date_obj.strftime('%Y-%m-%d')

        # Search for the match in finished matches
        url = f"https://www.sofascore.com/api/v1/sport/football/{formatted_date}/events"

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }

        response = requests.get(url, headers=headers, timeout=10)

        if response.status_code == 200:
            data = response.json()
            events = data.get('events', [])

            for event in events:
                event_home = event.get('homeTeam', {}).get('name', '').lower()
                event_away = event.get('awayTeam', {}).get('name', '').lower()

                # Match teams (fuzzy)
                if (home_team.lower() in event_home or event_home in home_team.lower()) and \
                   (away_team.lower() in event_away or event_away in away_team.lower()):

                    status = event.get('status', {}).get('type', '')

                    if status == 'finished':
                        home_score = event.get('homeScore', {}).get('current', 0)
                        away_score = event.get('awayScore', {}).get('current', 0)
                        return {
                            'found': True,
                            'home_goals': home_score,
                            'away_goals': away_score,
                            'status': 'finished',
                            'source': 'sofascore'
                        }
                    elif status in ['inprogress', 'halftime']:
                        return {
                            'found': True,
                            'status': 'in_progress',
                            'source': 'sofascore'
                        }

    except Exception as e:
        logger.debug(f"Sofascore API failed: {e}")

    return {'found': False}


def fetch_result_google(home_team, away_team, match_date):
    """
    Fetch result by searching Google.
    Parses the sports card if available.
    """
    try:
        query = f"{home_team} vs {away_team} {match_date} risultato"
        url = f"https://www.google.com/search?q={requests.utils.quote(query)}"

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }

        response = requests.get(url, headers=headers, timeout=10)

        if response.status_code == 200:
            soup = BeautifulSoup(response.text, 'html.parser')

            # Look for sports score card
            # Google shows scores in various formats
            score_pattern = re.compile(r'(\d+)\s*[-–]\s*(\d+)')

            # Look in the main content area
            for div in soup.find_all(['div', 'span'], class_=re.compile(r'score|result', re.I)):
                text = div.get_text()
                match = score_pattern.search(text)
                if match:
                    home_goals = int(match.group(1))
                    away_goals = int(match.group(2))

                    # Verify it's the right match by checking team names are nearby
                    parent_text = div.parent.get_text() if div.parent else ''
                    if home_team.lower()[:4] in parent_text.lower() or away_team.lower()[:4] in parent_text.lower():
                        return {
                            'found': True,
                            'home_goals': home_goals,
                            'away_goals': away_goals,
                            'status': 'finished',
                            'source': 'google'
                        }

    except Exception as e:
        logger.debug(f"Google search failed: {e}")

    return {'found': False}


def get_match_result(home_team, away_team, match_date, league_code):
    """
    Try multiple sources to get match result.
    """
    # Try API sources first
    result = fetch_result_livescore_api(home_team, away_team, match_date)

    if result.get('found') and result.get('status') == 'finished':
        return result

    # Try Google as fallback
    result = fetch_result_google(home_team, away_team, match_date)

    if result.get('found') and result.get('status') == 'finished':
        return result

    return {'found': False}


def determine_outcome(home_goals, away_goals):
    """Determine match outcome from score"""
    if home_goals > away_goals:
        return 'HOME', 2
    elif away_goals > home_goals:
        return 'AWAY', 0
    else:
        return 'DRAW', 1


def check_and_verify_predictions():
    """
    Main verification loop.
    Checks predictions that should have results by now.
    """
    logger.info("=" * 60)
    logger.info("Live Score Verification Started")
    logger.info(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    logger.info("=" * 60)

    predictions = load_predictions()
    verification = load_verification()

    # Get already verified match keys
    verified_keys = set()
    for r in verification.get('results', []):
        key = f"{r.get('date')}_{r.get('home_team')}_{r.get('away_team')}"
        verified_keys.add(key)

    # Track stats
    checked = 0
    verified = 0
    pending = 0
    skipped = 0

    for pred in predictions:
        match_date = pred.get('date', '')
        match_time = pred.get('time', '15:00')
        home_team = pred.get('home_team', '')
        away_team = pred.get('away_team', '')
        league_code = pred.get('league_code', '')

        match_key = f"{match_date}_{home_team}_{away_team}"

        # Skip if already verified
        if match_key in verified_keys:
            skipped += 1
            continue

        # Check if we should look for result
        should_check, buffer_type = should_check_match(match_date, match_time)

        if not should_check:
            if buffer_type not in ['future', 'too_old']:
                pending += 1
                logger.debug(f"Pending: {home_team} vs {away_team} ({buffer_type})")
            continue

        logger.info(f"\nChecking: {home_team} vs {away_team}")
        logger.info(f"  Date: {match_date} {match_time} ({buffer_type})")
        checked += 1

        # Fetch result
        result = get_match_result(home_team, away_team, match_date, league_code)

        if result.get('found') and result.get('status') == 'finished':
            home_goals = result['home_goals']
            away_goals = result['away_goals']
            actual, actual_code = determine_outcome(home_goals, away_goals)

            predicted = pred.get('prediction', '')
            predicted_code = 2 if predicted == 'HOME' else (1 if predicted == 'DRAW' else 0)

            is_correct = actual_code == predicted_code

            logger.info(f"  Result: {home_goals}-{away_goals} ({actual})")
            logger.info(f"  Predicted: {predicted} | Correct: {is_correct}")

            # Add to verification
            verification_entry = {
                'league': league_code,
                'league_name': LEAGUE_MAP.get(league_code, {}).get('name', league_code),
                'date': match_date,
                'time': match_time,
                'home_team': home_team,
                'away_team': away_team,
                'home_goals': home_goals,
                'away_goals': away_goals,
                'actual': actual,
                'actual_code': actual_code,
                'predicted': predicted,
                'predicted_code': predicted_code,
                'confidence': pred.get('confidence', 50),
                'home_prob': pred.get('home_prob', 33),
                'draw_prob': pred.get('draw_prob', 33),
                'away_prob': pred.get('away_prob', 33),
                'correct': is_correct,
                'verified_at': datetime.now().isoformat(),
                'source': result.get('source', 'unknown')
            }

            verification['results'].append(verification_entry)
            verified_keys.add(match_key)
            verified += 1

        elif result.get('status') == 'in_progress':
            logger.info(f"  Match still in progress")
            pending += 1

        else:
            logger.info(f"  Result not found yet")
            pending += 1

        # Rate limiting
        time.sleep(2)

    # Sort results by date (newest first)
    verification['results'] = sorted(
        verification['results'],
        key=lambda x: x.get('date', ''),
        reverse=True
    )

    # Save updated verification
    if verified > 0:
        save_verification(verification)

    logger.info("\n" + "=" * 60)
    logger.info("Verification Summary")
    logger.info(f"  Checked: {checked}")
    logger.info(f"  Verified: {verified}")
    logger.info(f"  Pending: {pending}")
    logger.info(f"  Skipped (already done): {skipped}")
    logger.info("=" * 60)


def main():
    """Main entry point"""
    try:
        check_and_verify_predictions()
    except Exception as e:
        logger.error(f"Fatal error: {e}")
        raise


if __name__ == '__main__':
    main()
