<?php
// CRON ENGINE: Automated API-Sports Data Ingestion with Odds
// OPTIMISED for large fixture lists – runs in batches to avoid timeout

error_reporting(E_ALL);
ini_set('display_errors', 1);
set_time_limit(0); // Unlimited execution time for CLI, but we'll manage it ourselves

require_once __DIR__ . '/../config/config.php';

// 1. Check Feature Flag
if (!defined('DATA_SOURCE') || DATA_SOURCE !== 'api') {
    die("CRON TERMINATED: Not in API Data Source Mode.\n");
}

$api_key = defined('FOOTBALL_API_KEY') ? FOOTBALL_API_KEY : '';
$api_url = defined('FOOTBALL_API_URL') ? FOOTBALL_API_URL : 'https://v3.football.api-sports.io/';
if (empty($api_key)) die("CRON TERMINATED: API Key missing.\n");

// ==========================================
// 2. CONFIGURATION
// ==========================================
$date = date('Y-m-d');
$timeout_seconds = 110; // Stop just before the 120s server limit
$batch_size = 10; // Process fixtures in batches of 10
$start_time = time();

echo "Starting sync for {$date}... (timeout after {$timeout_seconds}s)\n";

// 3. Fetch fixtures once
$endpoint = rtrim($api_url, '/') . "/fixtures?date={$date}";
$response = file_get_contents_with_curl($endpoint, $api_key);
$data = json_decode($response, true);

if (empty($data['response'])) {
    die("No fixtures found for {$date}.\n");
}

$all_fixtures = $data['response'];
$total = count($all_fixtures);
echo "Found {$total} fixtures.\n";

$processed = 0;
$odds_fetched = 0;
$errors = 0;

// ==========================================
// 4. PROCESS IN BATCHES
// ==========================================
foreach (array_chunk($all_fixtures, $batch_size) as $batch_index => $batch) {
    // Check timeout before each batch
    if (time() - $start_time > $timeout_seconds) {
        echo "⏱️ Timeout approaching. Stopping after {$processed} fixtures.\n";
        echo "Run the script again to continue processing.\n";
        break;
    }

    echo "Processing batch " . ($batch_index + 1) . " (" . count($batch) . " fixtures)...\n";

    foreach ($batch as $match) {
        // Check timeout for each fixture
        if (time() - $start_time > $timeout_seconds) {
            echo "⏱️ Timeout approaching. Stopping after {$processed} fixtures.\n";
            break 2;
        }

        $api_fixture_id = $match['fixture']['id'];
        $match_date     = $match['fixture']['date'];
        $league_name    = $match['league']['name'] ?? 'Football League';
        $status_short   = $match['fixture']['status']['short'] ?? 'NS';

        $home_team_api_id = $match['teams']['home']['id'];
        $home_team_name   = $match['teams']['home']['name'];
        $home_team_logo   = $match['teams']['home']['logo'];

        $away_team_api_id = $match['teams']['away']['id'];
        $away_team_name   = $match['teams']['away']['name'];
        $away_team_logo   = $match['teams']['away']['logo'];

        $home_goals = $match['goals']['home'] ?? null;
        $away_goals = $match['goals']['away'] ?? null;

        // Check if fixture already exists
        $check = $pdo->prepare("SELECT id, home_odds, draw_odds, away_odds FROM fixtures WHERE api_fixture_id = ?");
        $check->execute([$api_fixture_id]);
        $existing = $check->fetch(PDO::FETCH_ASSOC);

        // Only fetch odds if:
        // 1. Fixture doesn't exist, OR
        // 2. Odds columns are empty/null, OR
        // 3. Match is not finished (still need odds)
        $is_finished = in_array($status_short, ['FT', 'AET', 'PEN']);
        $needs_odds = false;

        if (!$existing) {
            $needs_odds = true;
        } elseif (!$is_finished) {
            // For live/upcoming matches, check if odds are missing
            $h_odds = isset($existing['home_odds']) ? (float)$existing['home_odds'] : 0;
            $d_odds = isset($existing['draw_odds']) ? (float)$existing['draw_odds'] : 0;
            $a_odds = isset($existing['away_odds']) ? (float)$existing['away_odds'] : 0;
            if ($h_odds == 0 && $d_odds == 0 && $a_odds == 0) {
                $needs_odds = true;
            }
        }

        // Fetch odds only if needed
        if ($needs_odds) {
            $odds_data = fetch_odds_for_fixture($api_fixture_id, $api_key, $api_url);
            $home_odds = $odds_data['home'] ?? null;
            $draw_odds = $odds_data['draw'] ?? null;
            $away_odds = $odds_data['away'] ?? null;
            $odds_fetched++;
        } else {
            // Use existing odds if available
            $home_odds = $existing['home_odds'] ?? null;
            $draw_odds = $existing['draw_odds'] ?? null;
            $away_odds = $existing['away_odds'] ?? null;
        }

        // Determine winner
        $winner = null;
        if ($is_finished && $home_goals !== null && $away_goals !== null) {
            if ($home_goals > $away_goals) $winner = '1';
            elseif ($home_goals < $away_goals) $winner = '2';
            else $winner = 'X';
        }

        // Begin DB transaction
        $pdo->beginTransaction();
        try {
            $home_internal_id = getOrInsertTeam($pdo, $home_team_api_id, $home_team_name, $home_team_logo);
            $away_internal_id = getOrInsertTeam($pdo, $away_team_api_id, $away_team_name, $away_team_logo);

            if ($existing) {
                $update = $pdo->prepare("UPDATE fixtures SET home_goals=?, away_goals=?, match_status=?, home_odds=?, draw_odds=?, away_odds=?, winner=? WHERE api_fixture_id=?");
                $update->execute([$home_goals, $away_goals, $status_short, $home_odds, $draw_odds, $away_odds, $winner, $api_fixture_id]);
            } else {
                $insert = $pdo->prepare("INSERT INTO fixtures (api_fixture_id, league_name, match_date, home_team_id, away_team_id, home_goals, away_goals, match_status, home_odds, draw_odds, away_odds, winner, source) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'API')");
                $insert->execute([$api_fixture_id, $league_name, $match_date, $home_internal_id, $away_internal_id, $home_goals, $away_goals, $status_short, $home_odds, $draw_odds, $away_odds, $winner]);
            }

            $pdo->commit();
            $processed++;
        } catch (Exception $e) {
            $pdo->rollBack();
            $errors++;
            echo "Error on fixture {$api_fixture_id}: " . $e->getMessage() . "\n";
        }
    }

    // Small delay between batches to avoid API rate limits
    if ($batch_index < count(array_chunk($all_fixtures, $batch_size)) - 1) {
        echo "Pausing 1 second before next batch...\n";
        sleep(1);
    }
}

// ==========================================
// 5. SUMMARY
// ==========================================
$elapsed = time() - $start_time;
echo "\n" . str_repeat("=", 60) . "\n";
echo "CRON SUMMARY:\n";
echo "  • Fixtures processed: {$processed}/{$total}\n";
echo "  • Odds fetched: {$odds_fetched}\n";
echo "  • Errors: {$errors}\n";
echo "  • Time elapsed: {$elapsed}s\n";
echo "  • Status: " . ($processed == $total ? "✅ COMPLETE" : "⏳ PARTIAL (run again)") . "\n";
echo str_repeat("=", 60) . "\n";

// ==========================================
// HELPER FUNCTIONS
// ==========================================

function fetch_odds_for_fixture($fixture_id, $api_key, $api_url) {
    $endpoint = rtrim($api_url, '/') . "/odds?fixture={$fixture_id}";
    $response = file_get_contents_with_curl($endpoint, $api_key);
    $data = json_decode($response, true);

    if (empty($data['response'])) {
        return ['home' => null, 'draw' => null, 'away' => null];
    }

    // Find first bookmaker with Match Winner odds
    foreach ($data['response'] as $bookmaker) {
        if (!empty($bookmaker['bookmaker']['name'])) {
            foreach ($bookmaker['odds'] as $odd) {
                if ($odd['name'] === 'Match Winner') {
                    $values = $odd['values'];
                    $home = $away = $draw = null;
                    foreach ($values as $v) {
                        if ($v['value'] === 'Home') $home = $v['odd'];
                        if ($v['value'] === 'Draw') $draw = $v['odd'];
                        if ($v['value'] === 'Away') $away = $v['odd'];
                    }
                    if ($home && $draw && $away) {
                        return ['home' => $home, 'draw' => $draw, 'away' => $away];
                    }
                }
            }
        }
    }
    return ['home' => null, 'draw' => null, 'away' => null];
}

function file_get_contents_with_curl($url, $api_key) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "x-apisports-key: " . $api_key,
        "Accept: application/json"
    ]);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

function getOrInsertTeam($pdo, $api_team_id, $name, $logo_url) {
    $stmt = $pdo->prepare("SELECT id FROM teams WHERE api_team_id = ?");
    $stmt->execute([$api_team_id]);
    if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        return $row['id'];
    }
    $insert = $pdo->prepare("INSERT INTO teams (api_team_id, name, logo_url, source) VALUES (?, ?, ?, 'API')");
    $insert->execute([$api_team_id, $name, $logo_url]);
    return $pdo->lastInsertId();
}
?>