<?php
// Suppress any PHP errors/warnings that could break JSON output
ini_set('display_errors', 0);
error_reporting(0);

header('Content-Type: application/json');

try {
    include '../includes/db.php';
} catch (Exception $e) {
    echo json_encode(['success' => false, 'message' => 'Database connection failed']);
    exit;
}

$action = $_GET['action'] ?? $_POST['action'] ?? null;

function respond($payload) {
    echo json_encode($payload);
    exit;
}

/**
 * Get category id=>name map for an event.
 *
 * @param PDO $pdo
 * @param int $event_id
 * @return array<int,string>
 */
function getCategoryMap(PDO $pdo, int $event_id): array {
    $stmt = $pdo->prepare("SELECT id, category_name FROM event_categories WHERE event_id = ?");
    $stmt->execute([$event_id]);
    $map = [];
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $map[(int)$row['id']] = $row['category_name'];
    }
    return $map;
}

/**
 * Build reports list for an event, optionally filtered by heat.
 * Returns start list placeholders and summary table configurations.
 *
 * @param PDO $pdo
 * @param int $event_id
 * @param int|null $heat_number
 * @return array
 */
function getReportsForEvent(PDO $pdo, int $event_id, ?int $heat_number = null): array {
    // Heats basic info
    $heats_sql = "
        SELECT heat_number, heat_name, categories
        FROM event_heat_settings
        WHERE event_id = ?
        " . ($heat_number !== null ? "AND heat_number = ?" : "") . "
        ORDER BY heat_number
    ";
    $heats_stmt = $pdo->prepare($heats_sql);
    $heats_stmt->execute($heat_number !== null ? [$event_id, $heat_number] : [$event_id]);
    $heats = $heats_stmt->fetchAll(PDO::FETCH_ASSOC);

    // Active configurations (summary tables)
    $configs_stmt = $pdo->prepare("
        SELECT id, name, view_type, heat_number, category, display_order
        FROM result_configurations
        WHERE event_id = ? AND status = 'active'
        " . ($heat_number !== null ? "AND (heat_number = ? OR heat_number IS NULL)" : "") . "
        ORDER BY heat_number, display_order, name
    ");
    $configs_stmt->execute($heat_number !== null ? [$event_id, $heat_number] : [$event_id]);
    $configs = $configs_stmt->fetchAll(PDO::FETCH_ASSOC);

    // Group configurations by heat_number (NULL => event-level)
    $configsByHeat = [];
    foreach ($configs as $cfg) {
        $hn = isset($cfg['heat_number']) ? (string)$cfg['heat_number'] : 'event';
        if ($hn === '' || $hn === '0') $hn = 'event';
        if (!isset($configsByHeat[$hn])) $configsByHeat[$hn] = [];
        $configsByHeat[$hn][] = [
            'id' => (int)$cfg['id'],
            'name' => $cfg['name'],
            'view_type' => $cfg['view_type'],
            'heat_number' => $cfg['heat_number'] !== null ? (int)$cfg['heat_number'] : null,
            'category' => $cfg['category'],
            'display_order' => (int)$cfg['display_order'],
            // URL is template-based on client; provide params for convenience
            'params' => [
                'config_id' => (int)$cfg['id'],
                'event_id' => $event_id,
                'heat_number' => $cfg['heat_number'] !== null ? (int)$cfg['heat_number'] : null,
            ],
        ];
    }

    // Categories map (optional enrichment)
    $catMap = getCategoryMap($pdo, $event_id);

    // Build per-heat report set
    $heatsReports = [];
    foreach ($heats as $h) {
        $hn = (int)$h['heat_number'];
        $catNames = [];
        if (!empty($h['categories'])) {
            $ids = json_decode($h['categories'], true);
            if (is_array($ids)) {
                foreach ($ids as $cid) {
                    $catNames[] = $catMap[$cid] ?? (string)$cid;
                }
            }
        }
        $heatsReports[] = [
            'heat_number' => $hn,
            'heat_name' => $h['heat_name'],
            'categories' => $catNames,
            'start_list' => [
                'title' => 'Start List',
                'params' => [
                    'event_id' => $event_id,
                    'heat_number' => $hn,
                ],
                // Client can apply its own template: start_list.php?event_id={eventId}&heat_number={heatNumber}
                'url' => null,
            ],
            'summary_tables' => $configsByHeat[(string)$hn] ?? [],
        ];
    }

    // Event-level (no heat) configurations
    $eventLevelReports = $configsByHeat['event'] ?? [];

    // Provide URL templates as hints (client may override)
    $urlTemplates = [
        'start_list' => 'start_list.php?event_id={eventId}&heat_number={heatNumber}',
        'summary_table' => 'results_summary.php?config_id={configId}',
    ];

    return [
        'event_id' => $event_id,
        'url_templates' => $urlTemplates,
        'event_level' => $eventLevelReports,
        'heats' => $heatsReports,
    ];
}

try {
    if ($action === 'get_events_overview') {
        $events_stmt = $pdo->prepare("
            SELECT 
                e.id, e.name, e.date, e.heats_total, e.runs_per_heat, e.status,
                ehs.heat_number as current_heat, ehs.active_run as current_run,
                COUNT(DISTINCT ep.id) as total_participants,
                COUNT(DISTINCT ja.judge_id) as total_judges
            FROM events e
            LEFT JOIN event_participants ep ON e.id = ep.event_id
            LEFT JOIN judge_assignments ja ON e.id = ja.event_id
            LEFT JOIN event_heat_settings ehs ON e.id = ehs.event_id AND ehs.is_active = 1
            WHERE e.status IN ('active', 'upcoming', 'in_progress', 'live')
            GROUP BY e.id, e.name, e.date, e.heats_total, e.runs_per_heat, e.status, ehs.heat_number, ehs.active_run
            ORDER BY e.date DESC, e.name
        ");
        $events_stmt->execute();
        $events = $events_stmt->fetchAll(PDO::FETCH_ASSOC);

        foreach ($events as &$event) {
            // Check if figures_json column exists first
            $hasFiguresColumn = false;
            try {
                $checkColumn = $pdo->query("SHOW COLUMNS FROM scores LIKE 'figures_json'");
                $hasFiguresColumn = $checkColumn->rowCount() > 0;
            } catch (Exception $e) {
                $hasFiguresColumn = false;
            }
            
            // latest score - build query based on column availability
            $figuresSelect = $hasFiguresColumn ? 's.figures_json,' : '';
            $latest_score_stmt = $pdo->prepare("
                SELECT s.score_value, s.created_at, s.run_id, {$figuresSelect}
                       p.first_name, p.last_name, p.club, p.country,
                       ep.bib_number, ep.category_id,
                       ec.category_name as category,
                       r.run_number,
                       ehs.heat_name
                FROM scores s
                JOIN runs r ON s.run_id = r.id
                JOIN event_participants ep ON r.event_participant_id = ep.id
                JOIN participants p ON ep.participant_id = p.id
                LEFT JOIN event_categories ec ON ep.category_id = ec.id
                LEFT JOIN event_heat_settings ehs ON ep.event_id = ehs.event_id AND ehs.heat_number = ep.heat_number
                WHERE ep.event_id = ?
                ORDER BY s.created_at DESC
                LIMIT 1
            ");
            $latest_score_stmt->execute([$event['id']]);
            $latest_score = $latest_score_stmt->fetch(PDO::FETCH_ASSOC);
            
            // Calculate proper ranking based on summary table logic
            if ($latest_score) {
                // Get the participant's best score and rank using summary table logic
                $rank_stmt = $pdo->prepare("
                    SELECT 
                        ep.id as participant_id,
                        ep.bib_number,
                        p.first_name, 
                        p.last_name,
                        ep.category_id,
                        ec.category_name,
                        MAX(s.score_value) as best_score,
                        ROW_NUMBER() OVER (
                            PARTITION BY ep.category_id 
                            ORDER BY MAX(s.score_value) DESC
                        ) as category_rank,
                        ROW_NUMBER() OVER (
                            ORDER BY MAX(s.score_value) DESC
                        ) as overall_rank
                    FROM event_participants ep
                    JOIN participants p ON ep.participant_id = p.id
                    LEFT JOIN event_categories ec ON ep.category_id = ec.id
                    LEFT JOIN runs r ON ep.id = r.event_participant_id
                    LEFT JOIN scores s ON r.id = s.run_id
                    WHERE ep.event_id = ?
                    GROUP BY ep.id, ep.bib_number, p.first_name, p.last_name, ep.category_id, ec.category_name
                    HAVING MAX(s.score_value) IS NOT NULL
                ");
                $rank_stmt->execute([$event['id']]);
                $rankings = $rank_stmt->fetchAll(PDO::FETCH_ASSOC);
                
                // Find the current participant's ranking
                foreach ($rankings as $ranking) {
                    if ($ranking['bib_number'] == $latest_score['bib_number']) {
                        $latest_score['current_rank'] = $ranking['category_rank'];
                        $latest_score['overall_rank'] = $ranking['overall_rank'];
                        break;
                    }
                }
                
                // If no rank found, set to null
                if (!isset($latest_score['current_rank'])) {
                    $latest_score['current_rank'] = null;
                    $latest_score['overall_rank'] = null;
                }
            }
            
            // Process figure information if available
            if ($latest_score && $hasFiguresColumn && !empty($latest_score['figures_json'])) {
                $figures_data = json_decode($latest_score['figures_json'], true);
                if (is_array($figures_data) && !empty($figures_data)) {
                    // Handle different possible structures for figures
                    $figure_names = [];
                    foreach ($figures_data as $figure) {
                        if (is_string($figure)) {
                            $figure_names[] = $figure;
                        } elseif (is_array($figure) && isset($figure['name'])) {
                            $figure_names[] = $figure['name'];
                        } elseif (is_array($figure) && isset($figure['figure_name'])) {
                            $figure_names[] = $figure['figure_name'];
                        }
                    }
                    $latest_score['figure'] = !empty($figure_names) ? implode(', ', $figure_names) : null;
                } else {
                    $latest_score['figure'] = null;
                }
            } else {
                $latest_score['figure'] = null;
            }
            
            $event['latest_score'] = $latest_score ?: null;
            
            // Debug: Log the actual structure
            if ($latest_score) {
                error_log("Latest score data for event " . $event['id'] . ": " . print_r($latest_score, true));
            } else {
                error_log("No latest score data found for event " . $event['id']);
            }

            // judge count for next_bib calc
            $judge_count_stmt = $pdo->prepare("SELECT COUNT(DISTINCT judge_id) FROM judge_assignments WHERE event_id = ?");
            $judge_count_stmt->execute([$event['id']]);
            $judge_count = (int)$judge_count_stmt->fetchColumn();

            // next BIB for current heat/run
            $next_bib_stmt = $pdo->prepare("
                    SELECT ep.bib_number, ep.category_id,
                           p.first_name, p.last_name, p.club, p.country,
                           ec.category_name as category,
                           ehs.heat_name
                    FROM event_participants ep
                    JOIN participants p ON ep.participant_id = p.id
                    LEFT JOIN event_categories ec ON ep.category_id = ec.id
                    LEFT JOIN event_heat_settings ehs ON ep.event_id = ehs.event_id AND ehs.heat_number = ep.heat_number
                    WHERE ep.event_id = ? AND ep.heat_number = ?
                    AND ep.id NOT IN (
                        SELECT DISTINCT r.event_participant_id
                        FROM runs r
                        JOIN scores s ON r.id = s.run_id
                        WHERE r.run_number = ?
                        GROUP BY r.event_participant_id
                        HAVING COUNT(s.id) >= ?
                    )
                    ORDER BY ep.bib_number
                    LIMIT 1
                ");
            $next_bib_stmt->execute([
                $event['id'],
                $event['current_heat'] ?? 1,
                $event['current_run'] ?? 1,
                $judge_count
            ]);
            $next_bip_data = $next_bib_stmt->fetch(PDO::FETCH_ASSOC);
            
            // Calculate proper ranking for next participant if they have scores
            if ($next_bip_data) {
                // Get the same ranking data we calculated above
                if (isset($rankings)) {
                    foreach ($rankings as $ranking) {
                        if ($ranking['bib_number'] == $next_bip_data['bib_number']) {
                            $next_bip_data['current_rank'] = $ranking['category_rank'];
                            $next_bip_data['overall_rank'] = $ranking['overall_rank'];
                            break;
                        }
                    }
                }
                
                // If no rank found, set to null
                if (!isset($next_bip_data['current_rank'])) {
                    $next_bip_data['current_rank'] = null;
                    $next_bip_data['overall_rank'] = null;
                }
                
                $next_bip_data['figure'] = null; // No figure info available for next participant
            }
            
            $event['next_bib'] = $next_bip_data ?: null;
            
            // Debug: Log the actual structure
            if ($next_bip_data) {
                error_log("Next bib data for event " . $event['id'] . ": " . print_r($next_bip_data, true));
            } else {
                error_log("No next bib data found for event " . $event['id']);
            }
        }

        respond(['success' => true, 'events' => $events]);
    }

    if ($action === 'get_event_heats') {
        $event_id = (int)($_GET['event_id'] ?? 0);
        
        if (!$event_id) {
            echo json_encode(['success' => false, 'message' => 'Invalid event ID']);
            exit;
        }
        
        // Get category names for all categories in this event
        $categories_stmt = $pdo->prepare("
            SELECT id, category_name FROM event_categories 
            WHERE event_id = ?
        ");
        $categories_stmt->execute([$event_id]);
        $category_map = [];
        while ($cat = $categories_stmt->fetch(PDO::FETCH_ASSOC)) {
            $category_map[$cat['id']] = $cat['category_name'];
        }
        
        // judge count
        $judges_count_stmt = $pdo->prepare("SELECT COUNT(*) FROM judge_assignments WHERE event_id = ?");
        $judges_count_stmt->execute([$event_id]);
        $judges_count = (int)$judges_count_stmt->fetchColumn();

        // heats
        $heats_stmt = $pdo->prepare("
    SELECT 
        ehs.id, ehs.event_id, ehs.heat_number, ehs.heat_name, 
        ehs.scoring_type, ehs.runs_count, ehs.categories,
        ehs.flow_type, ehs.flow_source_heat, ehs.flow_participants_per_category,
        ehs.is_active, ehs.active_run, ehs.bib_on_start, ehs.bib_latest_on_run,
        COUNT(DISTINCT ep.id) as participants,
        COUNT(DISTINCT CASE WHEN s.is_approved = 1 THEN s.id END) as total_scores,
        (COUNT(DISTINCT ep.id) * ehs.runs_count * ?) as expected_scores
    FROM event_heat_settings ehs
    LEFT JOIN event_participants ep ON ehs.event_id = ep.event_id AND ehs.heat_number = ep.heat_number
    LEFT JOIN runs r ON ep.id = r.event_participant_id
    LEFT JOIN scores s ON r.id = s.run_id
    WHERE ehs.event_id = ?
    GROUP BY ehs.id, ehs.event_id, ehs.heat_number, ehs.heat_name, 
             ehs.scoring_type, ehs.runs_count, ehs.runs_scoring_method,
             ehs.time_start, ehs.estimate_time_per_participant, ehs.categories,
             ehs.flow_type, ehs.flow_source_heat, ehs.flow_participants_per_category,
             ehs.is_active, ehs.active_run, ehs.bib_on_start, ehs.bib_latest_on_run
    ORDER BY ehs.heat_number
");
        $heats_stmt->execute([$judges_count, $event_id]);
        $heats = $heats_stmt->fetchAll(PDO::FETCH_ASSOC);

        // Add category names to each heat
        foreach ($heats as &$heat) {
            if (!empty($heat['categories'])) {
                try {
                    $category_ids = json_decode($heat['categories'], true);
                    if (is_array($category_ids)) {
                        // Map IDs to names using the category_map
                        $category_names = [];
                        foreach ($category_ids as $id) {
                            if (isset($category_map[$id])) {
                                $category_names[] = $category_map[$id];
                            } else {
                                $category_names[] = "ID: $id";
                            }
                        }
                        // Add category_names to the heat data
                        $heat['category_names'] = $category_names;
                    }
                } catch (Exception $e) {
                    // Keep original categories if there's an error
                }
            }
        }
        
        // configurations
        $configs_stmt = $pdo->prepare("
            SELECT id, name, view_type, heat_number, category, display_order
            FROM result_configurations
            WHERE event_id = ? AND status = 'active'
            ORDER BY heat_number, display_order, name
        ");
        $configs_stmt->execute([$event_id]);
        $configurations = $configs_stmt->fetchAll(PDO::FETCH_ASSOC);

        respond(['success' => true, 'heats' => $heats, 'configurations' => $configurations]);
    }

    if ($action === 'get_configurations') {
        $event_id = $_GET['event_id'] ?? $_POST['event_id'] ?? null;
        if (!$event_id) respond(['success' => false, 'message' => 'Missing event ID']);

        $configs_stmt = $pdo->prepare("
            SELECT id, name, view_type, heat_number, category, display_order
            FROM result_configurations
            WHERE event_id = ? AND status = 'active'
            ORDER BY display_order, name
        ");
        $configs_stmt->execute([$event_id]);
        $configurations = $configs_stmt->fetchAll(PDO::FETCH_ASSOC);

        respond(['success' => true, 'configurations' => $configurations]);
    }

    if ($action === 'get_active_heat_details') {
        $event_id = (int)($_GET['event_id'] ?? 0);
        
        if (!$event_id) {
            echo json_encode(['success' => false, 'message' => 'Invalid event ID']);
            exit;
        }
        
        // Get active heat details with participant names
        $heats_stmt = $pdo->prepare("
            SELECT 
                hs.heat_number, 
                hs.is_active, 
                hs.active_run, 
                hs.bib_on_start,
                CONCAT(p_start.first_name, ' ', p_start.last_name) as bib_start_name,
                hs.bib_latest_on_run,
                CONCAT(p_latest.first_name, ' ', p_latest.last_name) as bib_latest_name
            FROM event_heat_settings hs
            LEFT JOIN event_participants ep_start ON (hs.event_id = ep_start.event_id AND hs.heat_number = ep_start.heat_number AND ep_start.bib_number = hs.bib_on_start)
            LEFT JOIN participants p_start ON ep_start.participant_id = p_start.id
            LEFT JOIN event_participants ep_latest ON (hs.event_id = ep_latest.event_id AND hs.heat_number = ep_latest.heat_number AND ep_latest.bib_number = hs.bib_latest_on_run)
            LEFT JOIN participants p_latest ON ep_latest.participant_id = p_latest.id
            WHERE hs.event_id = ? AND hs.is_active = 1
        ");
        $heats_stmt->execute([$event_id]);
        $active_heats = $heats_stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // Format data as key-value by heat_number
        $heats_data = [];
        foreach ($active_heats as $heat) {
            $heats_data[$heat['heat_number']] = $heat;
        }
        
        echo json_encode([
            'success' => true,
            'heats' => $heats_data
        ]);
        exit;
    }

    if ($action === 'get_heat_rows') {
        $event_id = (int)($_GET['event_id'] ?? 0);
        
        if (!$event_id) {
            echo json_encode(['success' => false, 'message' => 'Invalid event ID']);
            exit;
        }
        
        // Get heat summary data for updating rows
        $heats_stmt = $pdo->prepare("
            SELECT 
                ehs.heat_number, ehs.heat_name, 
                ehs.scoring_type, ehs.runs_count,
                ehs.is_active, 
                COUNT(DISTINCT ep.id) as participants,
                COUNT(DISTINCT CASE WHEN s.is_approved = 1 THEN s.id END) as total_scores,
                (COUNT(DISTINCT ep.id) * ehs.runs_count * 
                    (SELECT COUNT(*) FROM judge_assignments ja WHERE ja.event_id = ehs.event_id)
                ) as expected_scores
            FROM event_heat_settings ehs
            LEFT JOIN event_participants ep ON ehs.event_id = ep.event_id AND ehs.heat_number = ep.heat_number
            LEFT JOIN runs r ON ep.id = r.event_participant_id
            LEFT JOIN scores s ON r.id = s.run_id
            WHERE ehs.event_id = ?
            GROUP BY ehs.heat_number, ehs.heat_name, ehs.scoring_type, ehs.runs_count, ehs.is_active
            ORDER BY ehs.heat_number
        ");
        $heats_stmt->execute([$event_id]);
        $heats = $heats_stmt->fetchAll(PDO::FETCH_ASSOC);
        
        echo json_encode([
            'success' => true,
            'heats' => $heats
        ]);
        exit;
    }

    // New: unified reports listing for event/heat
    if ($action === 'get_reports') {
        $event_id = (int)($_GET['event_id'] ?? $_POST['event_id'] ?? 0);
        $heat_number = isset($_GET['heat_number']) || isset($_POST['heat_number'])
            ? (int)($_GET['heat_number'] ?? $_POST['heat_number'])
            : null;

        if (!$event_id) {
            respond(['success' => false, 'message' => 'Missing event ID']);
        }

        $reports = getReportsForEvent($pdo, $event_id, $heat_number);
        respond(['success' => true] + $reports);
    }

    respond(['success' => false, 'message' => 'Invalid action']);
} catch (Exception $e) {
    // Log the actual error for debugging
    error_log("Public Dashboard API Error: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine());
    respond(['success' => false, 'message' => 'Database error: ' . $e->getMessage(), 'error_details' => [
        'file' => $e->getFile(),
        'line' => $e->getLine(),
        'trace' => $e->getTraceAsString()
    ]]);
}