<?php
/**
 * Start List API
 * 
 * Generates official start lists for events and heats
 * 
 * Example Usage:
 * - Single heat: /api/start_list_api.php?event_id=3&heat_number=1
 * - All heats: /api/start_list_api.php?event_id=3
 * - Specific format: /api/start_list_api.php?event_id=3&heat_number=1&format=json
 * 
 * 
 * Usage Examples**/
/*The API endpoint supports various use cases:

JSON Response (Default):
GET /api/start_list_api.php?event_id=3&heat_number=1
HTML Table:
GET /api/start_list_api.php?event_id=3&heat_number=1&format=html
CSV Download:
GET /api/start_list_api.php?event_id=3&heat_number=1&format=csv
All Heats:
GET /api/start_list_api.php?event_id=3
With Pagination:
GET /api/start_list_api.php?event_id=3&page=2&limit=50
Features
 * 
 */
   // Use Dompdf for PDF generation
    require_once '../includes/dompdf/autoload.inc.php';
    use Dompdf\Dompdf;
    use Dompdf\Options;
header('Content-Type: application/json; charset=utf-8');
include '../includes/db.php';
include '../includes/participant_colors.php';
include_once '../includes/country_codes.php';



// Configuration
$config = [
    'debug_mode' => false,
    'default_format' => 'json', // json, html, csv
    'items_per_page' => 100,
    'table_classes' => [
        'table' => 'table table-bordered',
        'header' => '',
        'row_even' => '',
        'row_odd' => ''
    ]
];

// Get and validate parameters
$event_id = (int)($_GET['event_id'] ?? 0);
$heat_number = isset($_GET['heat_number']) ? (int)$_GET['heat_number'] : null;
$heat_numbers = null;

// Support for multiple heat numbers
if (isset($_GET['heat_numbers']) && !empty($_GET['heat_numbers'])) {
    $heat_numbers = array_map('intval', array_filter(explode(',', $_GET['heat_numbers'])));
    $heat_number = null; // Clear single heat if multiple provided
}

$format = $_GET['format'] ?? $config['default_format'];
$config_name = $_GET['config_name'] ?? null;
$page = max(1, (int)($_GET['page'] ?? 1));
$limit = min(500, max(10, (int)($_GET['limit'] ?? $config['items_per_page'])));
$config_id = isset($_GET['config_id']) ? (int)$_GET['config_id'] : null;

// Load configuration if config_id is provided
$loaded_config = null;
if ($config_id) {
    try {
        $config_stmt = $pdo->prepare("
            SELECT 
                rc.*,
                e.name as event_name
            FROM result_configurations rc
            JOIN events e ON rc.event_id = e.id
            WHERE rc.id = ?
        ");
        $config_stmt->execute([$config_id]);
        $loaded_config = $config_stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($loaded_config) {
            $loaded_config['configuration'] = json_decode($loaded_config['configuration'], true);
            
            // Override event_id from configuration if it differs
            if ($loaded_config['event_id'] && $loaded_config['event_id'] != $event_id) {
                $event_id = (int)$loaded_config['event_id'];
            }
            
            // Override heat_number from configuration if set
            if (isset($loaded_config['heat_number']) && $loaded_config['heat_number']) {
                $heat_number = (int)$loaded_config['heat_number'];
            }
        }
    } catch (Exception $e) {
        // If config loading fails, continue with default parameters
        error_log("Failed to load configuration $config_id: " . $e->getMessage());
    }
}

// Column visibility parameters - use configuration if available, otherwise URL parameters
if ($loaded_config && isset($loaded_config['configuration'])) {
    $config_data = $loaded_config['configuration'];
    $show_rank = $config_data['showRank'] ?? true;
    $show_bib = $config_data['showBip'] ?? true;
    $show_participant = $config_data['showParticipant'] ?? true;
    $show_category = $config_data['showCategory'] ?? true;
    $show_club = $config_data['showClub'] ?? true;
    $show_gender = $config_data['showGender'] ?? true;
    $show_fis_code = $config_data['showFisCode'] ?? false;
    $show_licence_code = $config_data['showLicenceCode'] ?? false;
    $show_country = $config_data['showCountry'] ?? false;
    $show_birth_year = $config_data['showBirthYear'] ?? false;
    $show_age = $config_data['showAge'] ?? false;
    
    // Score column visibility
    $show_runs = $config_data['showRuns'] ?? true;
    $show_judges = $config_data['showJudges'] ?? false;
    $show_control_points = $config_data['showControlPoints'] ?? false;
    $show_figures = $config_data['showFigures'] ?? false;
    
    // Sorting parameters from configuration
    $sort_by = $config_data['sortBy'] ?? 'sort_order';
    $sort_direction = $config_data['sortDirection'] ?? 'asc';
    
    // Column renames from configuration
    $column_renames = $config_data['columnRenames'] ?? [];
    
    // Additional filters from configuration
    $category_filter = $config_data['category_filter'] ?? null;
    $gender_filter = $config_data['genderFilter'] ?? null;
} else {
    // Fallback to URL parameters
    $show_rank = isset($_GET['show_rank']) ? filter_var($_GET['show_rank'], FILTER_VALIDATE_BOOLEAN) : true;
    $show_bib = isset($_GET['show_bib']) ? filter_var($_GET['show_bib'], FILTER_VALIDATE_BOOLEAN) : true;
    $show_participant = isset($_GET['show_participant']) ? filter_var($_GET['show_participant'], FILTER_VALIDATE_BOOLEAN) : true;
    $show_category = isset($_GET['show_category']) ? filter_var($_GET['show_category'], FILTER_VALIDATE_BOOLEAN) : true;
    $show_club = isset($_GET['show_club']) ? filter_var($_GET['show_club'], FILTER_VALIDATE_BOOLEAN) : true;
    $show_gender = isset($_GET['show_gender']) ? filter_var($_GET['show_gender'], FILTER_VALIDATE_BOOLEAN) : true;
    $show_fis_code = isset($_GET['show_fis_code']) ? filter_var($_GET['show_fis_code'], FILTER_VALIDATE_BOOLEAN) : false;
    $show_licence_code = isset($_GET['show_licence_code']) ? filter_var($_GET['show_licence_code'], FILTER_VALIDATE_BOOLEAN) : false;
    $show_country = isset($_GET['show_country']) ? filter_var($_GET['show_country'], FILTER_VALIDATE_BOOLEAN) : false;
    $show_birth_year = isset($_GET['show_birth_year']) ? filter_var($_GET['show_birth_year'], FILTER_VALIDATE_BOOLEAN) : false;
    $show_age = isset($_GET['show_age']) ? filter_var($_GET['show_age'], FILTER_VALIDATE_BOOLEAN) : false;

    // Score column visibility parameters
    $show_runs = isset($_GET['show_runs']) ? filter_var($_GET['show_runs'], FILTER_VALIDATE_BOOLEAN) : true;
    $show_judges = isset($_GET['show_judges']) ? filter_var($_GET['show_judges'], FILTER_VALIDATE_BOOLEAN) : false;
    $show_control_points = isset($_GET['show_control_points']) ? filter_var($_GET['show_control_points'], FILTER_VALIDATE_BOOLEAN) : false;
    $show_figures = isset($_GET['show_figures']) ? filter_var($_GET['show_figures'], FILTER_VALIDATE_BOOLEAN) : false;

    // Sorting parameters
    $sort_by = $_GET['sort'] ?? 'sort_order';
    $sort_direction = $_GET['sort_direction'] ?? 'asc';

    // Column rename parameters
    $column_renames = [];
    foreach ($_GET as $key => $value) {
        if (strpos($key, 'rename_') === 0 && !empty($value)) {
            $column_key = substr($key, 7); // Remove 'rename_' prefix
            $column_renames[$column_key] = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
        }
    }
    
    // Additional filters
    $category_filter = null;
    $gender_filter = null;
}

// Validate event exists
if (!$event_id) {
    echo json_encode([
        'success' => false,
        'message' => 'Event ID is required',
        'error_code' => 'MISSING_EVENT_ID'
    ]);
    exit;
}

// Check if event exists
$event_stmt = $pdo->prepare("SELECT id, name FROM events WHERE id = ?");
$event_stmt->execute([$event_id]);
$event = $event_stmt->fetch(PDO::FETCH_ASSOC);

if (!$event) {
    echo json_encode([
        'success' => false,
        'message' => 'Event not found',
        'error_code' => 'EVENT_NOT_FOUND'
    ]);
    exit;
}
// Function to generate start list data
function generateStartListData($pdo, $event_id, $heat_number = null, $page = 1, $limit = 100, $sort_by = 'bib', $sort_direction = 'asc', 
                               $search_filter = '', $club_filter = '', $category_filter = null, $gender_filter = null, $heat_numbers = null) {
    $offset = ($page - 1) * $limit;
    
    // Base query
    $query = "
        SELECT 
            ep.id,
            ep.heat_number,
            ep.bib_number as bib,
            ep.category,
            ep.sort_order,
            p.id as participant_id,
            p.first_name,
            p.last_name,
            p.club,
            p.gender,
            p.date_of_birth,
            p.fis_code,
            p.licence_code,
            p.country,
            ehs.heat_name,
            ehs.categories as heat_categories,
            ehs.runs_scoring_method
        FROM event_participants ep
        JOIN participants p ON ep.participant_id = p.id
        LEFT JOIN event_heat_settings ehs ON ep.event_id = ehs.event_id AND ep.heat_number = ehs.heat_number
        WHERE ep.event_id = ?
    ";
    
    $params = [$event_id];
    
    // Add heat filter if specified
    // Add heat filter - support both single heat and multiple heats
    if ($heat_numbers !== null && is_array($heat_numbers) && !empty($heat_numbers)) {
        $heat_placeholders = str_repeat('?,', count($heat_numbers) - 1) . '?';
        $query .= " AND ep.heat_number IN ($heat_placeholders)";
        $params = array_merge($params, $heat_numbers);
    } elseif ($heat_number !== null) {
        $query .= " AND ep.heat_number = ?";
        $params[] = $heat_number;
    }
    
    // Add gender filter if specified
    if (!empty($gender_filter) && $gender_filter !== 'all') {
        $query .= " AND p.gender = ?";
        $params[] = $gender_filter;
    }
    
    // Add category filter if specified
    if (!empty($category_filter) && $category_filter !== 'all') {
        $query .= " AND ep.category = ?";
        $params[] = $category_filter;
    }
    
    // Add participant name search filter
    if (!empty($search_filter)) {
        $search = '%' . $search_filter . '%';
        $query .= " AND (p.first_name LIKE ? OR p.last_name LIKE ? OR CONCAT(p.last_name, ' ', p.first_name) LIKE ?)";
        $params[] = $search;
        $params[] = $search;
        $params[] = $search;
    }
    
    // Add club filter
    if (!empty($club_filter) && $club_filter !== 'all') {
        $query .= " AND p.club = ?";
        $params[] = $club_filter;
    }
    
    // Dynamic sorting based on parameters
    $valid_sort_columns = [
        'bib' => 'ep.bib_number',
        'name' => 'p.last_name',
        'participant_name' => 'p.last_name',
        'first_name' => 'p.first_name',
        'last_name' => 'p.last_name',
        'club' => 'p.club',
        'category' => 'ep.category',
        'gender' => 'p.gender',
        'sort_order' => 'ep.sort_order',
        'heat_number' => 'ep.heat_number',
        'country' => 'p.country',
        'fis_code' => 'p.fis_code',
        'licence_code' => 'p.licence_code'
    ];
    
    $sort_column = isset($valid_sort_columns[$sort_by]) ? $valid_sort_columns[$sort_by] : 'ep.sort_order';
    $sort_dir = (strtolower($sort_direction) === 'desc') ? 'DESC' : 'ASC';
    
    // Order by heat number first, then by chosen sort column
    $query .= " ORDER BY ep.heat_number ASC, {$sort_column} {$sort_dir}, ep.bib_number ASC";
    
    // Add pagination - use direct concatenation for LIMIT/OFFSET to ensure integers
    $query .= " LIMIT " . (int)$limit . " OFFSET " . (int)$offset;
    
    $stmt = $pdo->prepare($query);
    $stmt->execute($params);
    $participants = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // Get total count for pagination
    $count_query = "
        SELECT COUNT(*) 
        FROM event_participants ep 
        JOIN participants p ON ep.participant_id = p.id
        WHERE ep.event_id = ?
    ";
    $count_params = [$event_id];
    
    if ($heat_number !== null) {
        $count_query .= " AND ep.heat_number = ?";
        $count_params[] = $heat_number;
    }
    
    // Apply same filters as main query
    if (!empty($gender_filter) && $gender_filter !== 'all') {
        $count_query .= " AND p.gender = ?";
        $count_params[] = $gender_filter;
    }
    
    if (!empty($category_filter) && $category_filter !== 'all') {
        $count_query .= " AND ep.category = ?";
        $count_params[] = $category_filter;
    }
    
    // Apply same additional filters
    if (!empty($search_filter)) {
        $search = '%' . $search_filter . '%';
        $count_query .= " AND (p.first_name LIKE ? OR p.last_name LIKE ? OR CONCAT(p.last_name, ' ', p.first_name) LIKE ?)";
        $count_params[] = $search;
        $count_params[] = $search;
        $count_params[] = $search;
    }
    
    if (!empty($club_filter) && $club_filter !== 'all') {
        $count_query .= " AND p.club = ?";
        $count_params[] = $club_filter;
    }
    
    $count_stmt = $pdo->prepare($count_query);
    $count_stmt->execute($count_params);
    $total_count = $count_stmt->fetchColumn();
    
    // Group participants by heat
    $heats = [];
    $heat_stats = [];
    
    foreach ($participants as $participant) {
        $heat_num = $participant['heat_number'];
        
        if (!isset($heats[$heat_num])) {
            $heats[$heat_num] = [
                'heat_number' => $heat_num,
                'heat_name' => $participant['heat_name'],
                'heat_categories' => $participant['heat_categories'],
                'scoring_method' => $participant['runs_scoring_method'],
                'participants' => []
            ];
            $heat_stats[$heat_num] = [
                'total_participants' => 0,
                'categories' => [],
                'clubs' => [],
                'genders' => ['M' => 0, 'F' => 0]
            ];
        }
        
        // Add participant with calculated age
        $age = null;
        if ($participant['date_of_birth']) {
            $birth_date = new DateTime($participant['date_of_birth']);
            $today = new DateTime();
            $age = $birth_date->diff($today)->y;
        }
        
        $participant['age'] = $age;
        $participant['birth_year'] = $participant['date_of_birth'] ? date('Y', strtotime($participant['date_of_birth'])) : null;
        $participant['full_name'] = trim($participant['last_name'] . ' ' . $participant['first_name']);
        
        // Ensure additional fields are available
        $participant['fis_code'] = $participant['fis_code'] ?? null;
        $participant['licence_code'] = $participant['licence_code'] ?? null;
        $participant['country_code'] = $participant['country'] ?? null;
        
        $heats[$heat_num]['participants'][] = $participant;
        
        // Update stats
        $heat_stats[$heat_num]['total_participants']++;
        if ($participant['category']) {
            $heat_stats[$heat_num]['categories'][$participant['category']] = 
                ($heat_stats[$heat_num]['categories'][$participant['category']] ?? 0) + 1;
        }
        if ($participant['club']) {
            $heat_stats[$heat_num]['clubs'][$participant['club']] = 
                ($heat_stats[$heat_num]['clubs'][$participant['club']] ?? 0) + 1;
        }
        if ($participant['gender']) {
            $heat_stats[$heat_num]['genders'][$participant['gender']]++;
        }
    }
    
    // Calculate pagination info
    $total_pages = ceil($total_count / $limit);
    $has_next = $page < $total_pages;
    $has_prev = $page > 1;
    
    return [
        'heats' => $heats,
        'heat_stats' => $heat_stats,
        'pagination' => [
            'current_page' => $page,
            'total_pages' => $total_pages,
            'total_count' => $total_count,
            'limit' => $limit,
            'offset' => $offset,
            'has_next' => $has_next,
            'has_prev' => $has_prev
        ]
    ];
}

// Function to generate HTML table
function generateHTMLTable($data, $event, $heat_number = null, $participant_colors = []) {
    global $config, $show_rank, $show_bib, $show_participant, $show_category, $show_club, $show_gender;
    global $show_fis_code, $show_licence_code, $show_country, $show_birth_year, $show_age;
    global $show_runs, $show_judges, $show_control_points, $show_figures, $column_renames;
    
    $html = '';
    
    // Define column configuration
    $columns = [
        'rank' => ['show' => $show_rank, 'title' => 'rank', 'default' => '#'],
        'bib' => ['show' => $show_bib, 'title' => 'bib', 'default' => 'BIB'],
        'participant' => ['show' => $show_participant, 'title' => 'participant', 'default' => 'Name'],
        'category' => ['show' => $show_category, 'title' => 'category', 'default' => 'Category'],
        'club' => ['show' => $show_club, 'title' => 'club', 'default' => 'Club'],
        'gender' => ['show' => $show_gender, 'title' => 'gender', 'default' => 'Gender'],
        'fis_code' => ['show' => $show_fis_code, 'title' => 'fis_code', 'default' => 'FIS Code'],
        'licence_code' => ['show' => $show_licence_code, 'title' => 'licence_code', 'default' => 'Licence Code'],
        'country' => ['show' => $show_country, 'title' => 'country', 'default' => 'Country'],
        'birth_year' => ['show' => $show_birth_year, 'title' => 'birth_year', 'default' => 'Birth Year'],
        'age' => ['show' => $show_age, 'title' => 'age', 'default' => 'Age']
    ];
    
    // Generate tables for each heat
    foreach ($data['heats'] as $heat) {
        $heat_num = $heat['heat_number'];
        $participants = $heat['participants'];
        
        if (empty($participants)) continue;
        
        // Build complete heat-table-wrapper structure
        $html .= '<div class="heat-table-wrapper mb-4">';
        $html .= '    <div class="heat-table-header bg-primary text-white p-2 rounded-top">';
        $html .= '        <div class="d-flex justify-content-between align-items-center">';
        $html .= '            <h5 class="mb-0"><i class="fas fa-fire me-2"></i>Heat ' . htmlspecialchars($heat_num);
        if ($heat['heat_name']) {
            $html .= ' - ' . htmlspecialchars($heat['heat_name'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
        }
        $html .= '</h5>';
        $html .= '            <span class="badge bg-light text-dark">';
        $html .= '                <i class="fas fa-users me-1"></i>' . count($participants) . ' Participants';
        $html .= '            </span>';
        $html .= '        </div>';
        if ($heat['scoring_method']) {
            $html .= '        <small class="text-white-50"><i class="fas fa-calculator me-1"></i>Scoring: ' . htmlspecialchars($heat['scoring_method']) . '</small>';
        }
        $html .= '    </div>';
        $html .= '    <div class="table-responsive">';
        
        // Start table
        $html .= '<table class="' . $config['table_classes']['table'] . ' data-table">';
        $html .= '<thead class="' . $config['table_classes']['header'] . '">';
        $html .= '<tr>';
        
        // Generate dynamic headers
        foreach ($columns as $col_key => $col_config) {
            if ($col_config['show']) {
                $header_title = isset($column_renames[$col_key]) && !empty($column_renames[$col_key]) 
                    ? $column_renames[$col_key] 
                    : $col_config['default'];
                $html .= '<th>' . htmlspecialchars($header_title) . '</th>';
            }
        }
        
        $html .= '</tr>';
        $html .= '</thead>';
        $html .= '<tbody>';
        
        $position = 1;
        foreach ($participants as $p) {
            $row_class = ($position % 2 === 0) ? $config['table_classes']['row_even'] : $config['table_classes']['row_odd'];
            
            $html .= '<tr class="' . $row_class . '">';
            
            // Generate dynamic cells
            foreach ($columns as $col_key => $col_config) {
                if ($col_config['show']) {
                    
                    
                    switch ($col_key) {
                        case 'rank':
                            $html .= '<td class="css-rank">';
                            $html .= $position;
                            $html .= '</td>';
                            break;
                        case 'bib':
                            $html .= '<td class="css-bib">';
                            $html .= '<span class="badge bg-secondary">' . htmlspecialchars($p['bib'] ?? '-') . '</span>';
                            $html .= '</td>';
                            break;
                        case 'participant':
                            $html .= '<td class="css-participant">';
                            $html .= '<span class="p_full_cell">';
                            // Generate participant badge with colors
                            $initials = '';
                            $badge_class = '';
                            if (!empty($p['last_name']) && !empty($p['first_name'])) {
                                $initials = strtoupper(mb_substr($p['last_name'], 0, 1, 'UTF-8') . mb_substr($p['first_name'], 0, 1, 'UTF-8'));
                                $bib = $p['bib'] ?? '';
                                $badge_class = 'badge_p_' . $bib . '_' . $initials;
                            }
                            
                            if ($initials && $badge_class) {
                                $html .= '<span class="badge badge_p  me-2 ' . $badge_class . '">' . htmlspecialchars($initials) . '</span>';
                            }
                            $html .= '<strong>' . htmlspecialchars($p['full_name']) . '</strong>';
                            $html .= '</span>';
                            $html .= '</td>';
                            break;
                        case 'category':
                            $html .= '<td class="css-category">';
                            $html .= '<small><span class="badge bg-info">' . htmlspecialchars($p['category'] ?? '-') . '</span></small>';
                            $html .= '</td>';
                            break;
                        case 'club':
                            $html .= '<td class="css-club">';
                            $html .= '<small><span class="badge bg-secondary">' . htmlspecialchars($p['club'] ?? '-') . '</span></small>';
                            $html .= '</td>';
                            break;
                        case 'club':
                            $html .= '<td class="css-club">';
                            $html .= '<small><span class="badge bg-secondary">' . htmlspecialchars($p['club'] ?? '-') . '</span></small>';
                            $html .= '</td>';
                            break;
                        case 'gender':
                            $html .= '<td class="css-gender">';
                            if ($p['gender']) {
                                $gender_class = $p['gender'] === 'M' ? 'text-primary' : 'text-danger';
                                $gender_icon = $p['gender'] === 'M' ? 'fa-male' : 'fa-female';
                                $html .= '<i class="fas ' . $gender_icon . ' ' . $gender_class . ' me-1"></i>';
                                $html .= htmlspecialchars($p['gender']);
                            } else {
                                $html .= '-';
                            }
                            $html .= '</td>';
                            break;
                        case 'fis_code':
                            $html .= '<td class="css-fis_code">';
                            $html .= htmlspecialchars($p['fis_code'] ?? '-');
                            $html .= '</td>';
                            break;
                        case 'licence_code':
                            $html .= '<td class="css-licence_code">';
                            $html .= htmlspecialchars($p['licence_code'] ?? '-');
                            $html .= '</td>';
                            break;
                        case 'country':
                            $html .= '<td class="css-country">';
                            $html .= '<span class="country-code">'. getCountryEmoji($p['country'] ?? '') . '</span> ' . htmlspecialchars($p['country'] ?? '-');
                           
                            $html .= '</td>';
                            break;
                        case 'birth_year':
                            $html .= '<td class="css-birth_year">';
                            $html .= htmlspecialchars($p['birth_year'] ?? '-');
                            $html .= '</td>';
                            break;
                        case 'age':
                            $html .= '<td class="css-age">';
                            $html .= htmlspecialchars($p['age'] ?? '-');
                            $html .= '</td>';
                            break;
                        default:
                            $html .= '<td class="css-default">';
                            $html .= '-';
                            $html .= '</td>';
                            break;
                    }
                    
                    
                }
            }
            
            $html .= '</tr>';
            
            $position++;
        }
        
        $html .= '</tbody>';
        $html .= '</table>';
        $html .= '    </div>'; // end table-responsive
        $html .= '    <div class="heat-table-footer bg-light p-2 rounded-bottom">';
        $html .= '        <small class="text-muted"><i class="fas fa-users me-1"></i>' . count($participants) . ' Participants</small>';
        $html .= '    </div>';
        $html .= '</div>'; // end heat-table-wrapper
    }
    
    return $html;
}

// Function to generate CSV data
function generateCSV($data, $event) {
    global $show_rank, $show_bib, $show_participant, $show_category, $show_club, $show_gender;
    global $show_fis_code, $show_licence_code, $show_country, $show_birth_year, $show_age;
    global $column_renames;
    
    $csv_data = [];
    
    // Define column configuration for CSV
    $columns = [
        'heat' => ['show' => true, 'title' => 'heat', 'default' => 'Heat'],
        'rank' => ['show' => $show_rank, 'title' => 'rank', 'default' => 'Position'],
        'bib' => ['show' => $show_bib, 'title' => 'bib', 'default' => 'BIB'],
        'first_name' => ['show' => $show_participant, 'title' => 'first_name', 'default' => 'First Name'],
        'last_name' => ['show' => $show_participant, 'title' => 'last_name', 'default' => 'Last Name'],
        'full_name' => ['show' => $show_participant, 'title' => 'full_name', 'default' => 'Full Name'],
        'club' => ['show' => $show_club, 'title' => 'club', 'default' => 'Club'],
        'category' => ['show' => $show_category, 'title' => 'category', 'default' => 'Category'],
        'gender' => ['show' => $show_gender, 'title' => 'gender', 'default' => 'Gender'],
        'fis_code' => ['show' => $show_fis_code, 'title' => 'fis_code', 'default' => 'FIS Code'],
        'licence_code' => ['show' => $show_licence_code, 'title' => 'licence_code', 'default' => 'Licence Code'],
        'country' => ['show' => $show_country, 'title' => 'country', 'default' => 'Country'],
        'birth_year' => ['show' => $show_birth_year, 'title' => 'birth_year', 'default' => 'Birth Year'],
        'age' => ['show' => $show_age, 'title' => 'age', 'default' => 'Age'],
        'sort_order' => ['show' => true, 'title' => 'sort_order', 'default' => 'Sort Order']
    ];
    
    // Generate dynamic header
    $header = [];
    foreach ($columns as $col_key => $col_config) {
        if ($col_config['show']) {
            $header_title = isset($column_renames[$col_key]) && !empty($column_renames[$col_key]) 
                ? $column_renames[$col_key] 
                : $col_config['default'];
            $header[] = $header_title;
        }
    }
    $csv_data[] = $header;
    
    // Generate data rows
    foreach ($data['heats'] as $heat) {
        $position = 1;
        foreach ($heat['participants'] as $p) {
            $row = [];
            foreach ($columns as $col_key => $col_config) {
                if ($col_config['show']) {
                    switch ($col_key) {
                        case 'heat':
                            $row[] = $heat['heat_number'];
                            break;
                        case 'rank':
                            $row[] = $position;
                            break;
                        case 'bib':
                            $row[] = $p['bib'] ?? '';
                            break;
                        case 'first_name':
                            $row[] = $p['first_name'];
                            break;
                        case 'last_name':
                            $row[] = $p['last_name'];
                            break;
                        case 'full_name':
                            $row[] = $p['full_name'];
                            break;
                        case 'club':
                            $row[] = $p['club'] ?? '';
                            break;
                        case 'category':
                            $row[] = $p['category'] ?? '';
                            break;
                        case 'gender':
                            $row[] = $p['gender'] ?? '';
                            break;
                        case 'fis_code':
                            $row[] = $p['fis_code'] ?? '';
                            break;
                        case 'licence_code':
                            $row[] = $p['licence_code'] ?? '';
                            break;
                        case 'country':
                            $row[] = $p['country'] ?? '';
                            break;
                        case 'birth_year':
                            $row[] = $p['birth_year'] ?? '';
                            break;
                        case 'age':
                            $row[] = $p['age'] ?? '';
                            break;
                        case 'sort_order':
                            $row[] = $p['sort_order'] ?? '';
                            break;
                        default:
                            $row[] = '';
                            break;
                    }
                }
            }
            $csv_data[] = $row;
            $position++;
        }
    }
    
    return $csv_data;
}
 $search_filter = false;
        $club_filter = false;
try {
    // Generate start list data
    // Apply additional URL filters if no configuration is loaded
    if (!$loaded_config || !isset($loaded_config['configuration'])) {
        $search_filter = false;
        $club_filter = false;
        $category_filter = $_GET['category'] ?? null;
        $gender_filter = $_GET['gender'] ?? null;
    }
    
    $data = generateStartListData($pdo, $event_id, $heat_number, $page, $limit, $sort_by, $sort_direction, 
                                  $search_filter, $club_filter, $category_filter, $gender_filter, $heat_numbers);
    
    // Generate participant colors for consistent badge styling
    $all_participants = [];
    foreach ($data['heats'] as $heat) {
        foreach ($heat['participants'] as $participant) {
            $participant_key = $participant['bib'] . '_' . $participant['full_name'];
            $all_participants[$participant_key] = $participant;
        }
    }
    
    $participant_colors = collectParticipantColors($all_participants, ['mode' => 'light', 'saturation' => 0.65]);
    $table_css = generateParticipantCSS($participant_colors);
    
    // Determine response format
    switch ($format) {
        case 'html':
        case 'pdf':
            // Get styling (header/footer) from results_styling.php for both HTML and PDF
            $styling_mode = $_GET['styling'] ?? 'partial';

                        //$event_id = $selected_event ?? ($_GET['event_id'] ?? null);
                        $config_id = $_GET['config_id'] ?? null;

                        // Prepare API call to results_styling.php
                        $styling_api_url = dirname(__FILE__) . '/../admin/results_styling.php';
                        $api_endpoint = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . '/v2/admin/results_styling.php';
                        $post_fields = http_build_query([
                            'action' => 'get_styled_header_footer',
                            'event_id' => $event_id,
                            'config_id' => null
                        ]);

                        // Use cURL to call the API
                        $ch = curl_init($api_endpoint);
                        curl_setopt($ch, CURLOPT_POST, true);
                        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                        $styling_json = curl_exec($ch);
                        curl_close($ch);

                        $styling_data = json_decode($styling_json, true);

           

            // Generate the HTML table
            $html_table = generateHTMLTable($data, $event, $heat_number, $participant_colors);
            
            // Generate CSS for participant badges
            $table_css = generateParticipantCSS($participant_colors);
            
            if ($format === 'html' && $styling_mode === 'full') {
                ?>
            
                <?php
                header('Content-Type: text/html; charset=utf-8');
                // Output complete HTML page maintaining current appearance
                echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Start List</title>';
                echo '<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">';
                echo '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">';
                echo '<link href="/v2/assets/css/global.css" rel="stylesheet">';
                if (!empty($table_css)) {
                    echo '<style>' . $table_css . '</style>';
                }
                echo '</head><body class="ss_results format_pdf pdf_body">';
                echo $styling_data['header_html'] ?? '';
                echo $html_table;               
                echo $styling_data['footer_html'] ?? '';
                echo '</body></html>';
                exit;
            }

            if ($format === 'html' && $styling_mode === 'partial') {
                header('Content-Type: text/html; charset=utf-8');
                // Output HTML fragment for injection (public_results.php)
                
                if (!empty($table_css)) {
                    echo '<style>' . $table_css . '</style>';
                }
                
                echo $html_table;               
                
                exit;
            }
            
            if ($format === 'pdf') {
                // Build the full HTML for PDF
                $html = '<html>
                    <head>
                        <meta charset="utf-8">
                       <link href="/v2/assets/css/global.css" rel="stylesheet">
                    </head>
                    <body style="ss_results format_pdf"><div class="format_pdf">
                        ' . ($styling_data['header_html'] ?? '') . '
                        ' . $html_table . '
                        ' . ($styling_data['footer_html'] ?? '') . '
                    </div></body>
                </html>';

                // Setup Dompdf
                $options = new Options();
                $options->set('isHtml5ParserEnabled', true);
                $options->set('isRemoteEnabled', true);    
                $dompdf = new Dompdf($options);
                $dompdf->loadHtml($html);
                $dompdf->setPaper('A4', 'portrait');
                $dompdf->render();
                
                // Add page numbers
                $canvas = $dompdf->getCanvas();
                $font = $dompdf->getFontMetrics()->get_font("HelveticaCustom", "normal");
                $canvas->page_text(530, 822, "Page {PAGE_NUM} of {PAGE_COUNT}", $font, 6, [0,0,0]);

                // Serve PDF
                header('Content-Type: application/pdf');
                header('Content-Disposition: inline; filename="start_list_event_' . $event_id . ($heat_number ? '_heat_' . $heat_number : '') . '.pdf"');
                echo $dompdf->output();
                exit;
            }
            break;
            
        case 'csv':
            header('Content-Type: text/csv; charset=utf-8');
            header('Content-Disposition: attachment; filename="start_list_event_' . $event_id . 
                   ($heat_number ? '_heat_' . $heat_number : '') . '_' . date('Y-m-d') . '.csv"');
            
            $csv_data = generateCSV($data, $event);
            $output = fopen('php://output', 'w');
            foreach ($csv_data as $row) {
                fputcsv($output, $row);
            }
            fclose($output);
            break;
            
        case 'json':
        default:
            header('Content-Type: application/json');
            
            // Build response
            $response = [
                'success' => true,
                'data' => $data,
                'event' => $event,
                'filters' => [
                    'event_id' => $event_id,
                    'heat_number' => $heat_number
                ],
                'meta' => [
                    'total_heats' => count($data['heats']),
                    'total_participants' => $data['pagination']['total_count'],
                    'generated_at' => date('Y-m-d H:i:s'),
                    'format' => $format
                ],
                'participant_colors' => $participant_colors,
                'table_badge_colors' => htmlspecialchars($table_css)
            ];
            
            // Add debug information if enabled
            if ($config['debug_mode']) {
                $response['debug'] = [
                    'query_params' => $_GET,
                    'pagination_details' => $data['pagination'],
                    'heat_stats' => $data['heat_stats'] ?? []
                ];
            }
            
            echo json_encode($response, JSON_PRETTY_PRINT);
            break;
    }

} catch (Exception $e) {
    header('Content-Type: application/json');
    echo json_encode([
        'success' => false,
        'message' => 'Error generating start list: ' . $e->getMessage(),
        'error_code' => 'GENERATION_ERROR'
    ]);
}
?>