<?php
require_once '../core/bootstrap.php';

// --- Authentication Check ---
if (!isset($_SESSION['user_id']) || !in_array($_SESSION['user_role'], ['super_admin', 'admin', 'fixtures_manager'])) {
    header('Location: ../app/login.php');
    exit();
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: manage_fixtures.php');
    exit();
}

// --- Get Inputs ---
$league_id = filter_input(INPUT_POST, 'league_id', FILTER_VALIDATE_INT);
$season = $_POST['season'] ?? '';
$legs = filter_input(INPUT_POST, 'legs', FILTER_VALIDATE_INT);
$match_days = $_POST['match_days'] ?? [];
$start_date = $_POST['start_date'] ?? '';
$start_time = $_POST['start_time'] ?? '15:00';
$gameweek_interval = filter_input(INPUT_POST, 'gameweek_interval', FILTER_VALIDATE_INT);
$grounds = array_filter($_POST['grounds'] ?? []); // Remove empty entries
$matches_per_ground = filter_input(INPUT_POST, 'matches_per_ground', FILTER_VALIDATE_INT) ?: 2;
$match_break = filter_input(INPUT_POST, 'match_break', FILTER_VALIDATE_INT) ?: 15;

if (!$league_id || empty($season) || empty($match_days) || empty($start_date)) {
    $_SESSION['flash_error'] = 'Please fill in all required fields.';
    header('Location: generate_fixtures.php');
    exit();
}

// --- Fetch Teams ---
$db = new Database();
$db->query("SELECT t.id FROM teams t JOIN clubs c ON t.club_id = c.id WHERE c.league_id = :league_id");
$db->bind(':league_id', $league_id);
$teams_result = $db->resultSet();
$teams = array_map(function($t) { return $t->id; }, $teams_result);

$num_teams = count($teams);
if ($num_teams < 2) {
    $_SESSION['flash_error'] = 'Not enough teams in this league to generate fixtures.';
    header('Location: generate_fixtures.php');
    exit();
}

// --- Clear Existing Fixtures for this League ---
$db->query("DELETE FROM fixtures WHERE league_id = :league_id");
$db->bind(':league_id', $league_id);
$db->execute();

// --- Fetch Settings for Duration ---
$settingModel = new Setting();
$settings = $settingModel->getAll();
$match_duration = $settings['full_time_duration'] ?? 90;
$half_time_break = $settings['half_time_duration'] ?? 15;
$total_slot_duration = $match_duration + $half_time_break + $match_break;

// --- Round Robin Algorithm (Berger Tables) ---
// If odd number of teams, add a dummy 'bye' team
$has_ghost = false;
if ($num_teams % 2 != 0) {
    $teams[] = null; // Ghost team
    $num_teams++;
    $has_ghost = true;
}

$total_rounds = $num_teams - 1;
$matches_per_round = $num_teams / 2;
$rounds = [];

for ($round = 0; $round < $total_rounds; $round++) {
    $round_matches = [];
    for ($match = 0; $match < $matches_per_round; $match++) {
        $home = $teams[$match];
        $away = $teams[$num_teams - 1 - $match];

        // Swap home/away for fairness in single leg, though standard Berger does this specific rotation
        if ($match == 0 && $round % 2 == 1) {
            $temp = $home; $home = $away; $away = $temp;
        }
        
        if ($home !== null && $away !== null) {
            $round_matches[] = ['home' => $home, 'away' => $away];
        }
    }
    $rounds[] = $round_matches;

    // Rotate teams array (keep first fixed, rotate rest)
    $fixed = $teams[0];
    $moving = array_slice($teams, 1);
    $last = array_pop($moving);
    array_unshift($moving, $last);
    $teams = array_merge([$fixed], $moving);
}

// Shuffle the order of rounds randomly as requested
shuffle($rounds);

// --- Handle 2nd Leg ---
if ($legs == 2) {
    $second_half_rounds = [];
    foreach ($rounds as $round_matches) {
        $new_round = [];
        foreach ($round_matches as $match) {
            // Swap home and away
            $new_round[] = ['home' => $match['away'], 'away' => $match['home']];
        }
        $second_half_rounds[] = $new_round;
    }
    // Append second leg rounds
    $rounds = array_merge($rounds, $second_half_rounds);
}

// --- Assign Dates and Insert ---
$current_gameweek_date = new DateTime($start_date);
$fixtureModel = new Fixture();
$fixtures_created = 0;

foreach ($rounds as $index => $round_matches) {
    $gameweek = $index + 1;
    
    // Shuffle matches within the gameweek to randomize who plays on which selected day
    shuffle($round_matches);

    // Determine available dates for this gameweek based on selected days
    // We start looking from the $current_gameweek_date
    $gw_dates = [];
    $temp_date = clone $current_gameweek_date;
    
    // Find the next occurrences of the selected days (e.g., next Sat, next Sun)
    // We want to distribute matches across these days.
    // Simple logic: Map selected day names to dates relative to the gameweek start
    
    // Sort match days to ensure chronological order (e.g., Friday before Saturday)
    $sorter = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
    usort($match_days, function($a, $b) use ($sorter) {
        return array_search($a, $sorter) - array_search($b, $sorter);
    });

    // --- Generate Slots for this Gameweek ---
    $slots = [];
    foreach ($match_days as $day_name) {
        // Calculate specific date for this day name relative to gameweek start
        $d = clone $current_gameweek_date;
        $d->modify('next ' . $day_name);
        // If the current gameweek date IS that day, use it, otherwise next
        if ($current_gameweek_date->format('l') === $day_name) {
            $d = clone $current_gameweek_date;
        }
        $date_str = $d->format('Y-m-d');
        
        // Generate time slots for this day
        $base_time = new DateTime($date_str . ' ' . $start_time);
        
        for ($i = 0; $i < $matches_per_ground; $i++) {
            $slot_time = clone $base_time;
            $minutes_to_add = $i * $total_slot_duration;
            $slot_time->modify("+{$minutes_to_add} minutes");
            
            // For each time slot, create a slot for each ground
            if (!empty($grounds)) {
                foreach ($grounds as $ground) {
                    $slots[] = [
                        'datetime' => $slot_time->format('Y-m-d H:i:s'),
                        'venue' => $ground
                    ];
                }
            } else {
                // Fallback if no grounds provided
                $slots[] = [
                    'datetime' => $slot_time->format('Y-m-d H:i:s'),
                    'venue' => null
                ];
            }
        }
    }

    // --- Assign Matches to Slots ---
    foreach ($round_matches as $k => $match) {
        // Use modulo to wrap around slots if we have more matches than capacity (overbooking)
        if (empty($slots)) {
            // Fallback if no slots generated (e.g. no days selected)
            $match_datetime = $current_gameweek_date->format('Y-m-d') . ' ' . $start_time . ':00';
            $venue = null;
        } else {
            $slot = $slots[$k % count($slots)];
            $match_datetime = $slot['datetime'];
            $venue = $slot['venue'];
        }

        $data = [
            'league_id' => $league_id,
            'home_team_id' => $match['home'],
            'away_team_id' => $match['away'],
            'match_datetime' => $match_datetime,
            'gameweek' => $gameweek,
            'venue' => $venue,
            'status' => 'scheduled'
        ];

        // Use DB directly for batch insert speed or model for safety. Using DB here.
        $db->query("INSERT INTO fixtures (league_id, home_team_id, away_team_id, match_datetime, gameweek, venue, status) VALUES (:league_id, :home_team_id, :away_team_id, :match_datetime, :gameweek, :venue, 'scheduled')");
        $db->bind(':league_id', $data['league_id']);
        $db->bind(':home_team_id', $data['home_team_id']);
        $db->bind(':away_team_id', $data['away_team_id']);
        $db->bind(':match_datetime', $data['match_datetime']);
        $db->bind(':gameweek', $data['gameweek']);
        $db->bind(':venue', $data['venue']);
        $db->execute();

        $fixtures_created++;
    }

    // Advance date for next gameweek
    $current_gameweek_date->modify('+' . $gameweek_interval . ' days');
}

$_SESSION['flash_message'] = "Successfully generated {$fixtures_created} fixtures for {$season}.";
header('Location: manage_fixtures.php');
exit();
?>
