<?php
/**
 * Judge Scoring API - Fixed Version
 */

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

// Simple session management
session_start();

// Basic database connection
$host = 'localhost';
$db = 'freestyle_db';
$user = 'root';
$pass = '';
$dsn = "mysql:host=$host;dbname=$db;charset=utf8mb4";

try {
    $pdo = new PDO($dsn, $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => 'Database connection failed: ' . $e->getMessage(),
        'error_code' => 'DB_CONNECTION_ERROR'
    ]);
    exit;

}

// Simple authentication
if (!isset($_SESSION['user_id'])) {
    $_SESSION['user_id'] = 1;
    $_SESSION['user_type'] = 'admin';
    $_SESSION['username'] = 'admin';
}

try {
    $action = $_GET['action'] ?? $_POST['action'] ?? '';
    $response = ['success' => false, 'data' => null, 'message' => ''];

    // Get current user context
    $user_type = $_SESSION['user_type'];
    $user_id = $_SESSION['user_id'];
    $judge_id = $user_id;

    switch ($action) {
        case 'get_judge_context':
            $response = getJudgeContext($pdo, $judge_id, $user_type);
            break;
            
        case 'get_event_data':
            $event_id = $_GET['event_id'] ?? null;
            $response = getEventData($pdo, $judge_id, $event_id);
            break;
            
        case 'get_participants':
            $event_id = $_GET['event_id'] ?? null;
            $heat_number = $_GET['heat_number'] ?? null;
            $run_number = $_GET['run_number'] ?? null;
            $response = getParticipants($pdo, $event_id, $heat_number, $run_number, $judge_id);
            break;
            
        case 'get_scoring_form':
            $event_id = $_GET['event_id'] ?? null;
            $response = getScoringForm($pdo, $event_id, $judge_id);
            break;
            
        case 'submit_score':
            $response = submitScore($pdo, $_POST, $judge_id);
            break;
            
        case 'get_latest_scores':
            $event_id = $_GET['event_id'] ?? null;
            $response = getLatestScores($pdo, $event_id, $judge_id);
            break;
            
        case 'get_participant_scores':
            $ep_id = $_GET['ep_id'] ?? null;
            $heat_number = $_GET['heat_number'] ?? null;
            $response = getParticipantScores($pdo, $ep_id, $heat_number, $judge_id);
            break;
            
        case 'get_figure_history':
            $ep_id = $_GET['ep_id'] ?? null;
            $response = getFigureHistory($pdo, $ep_id, $judge_id);
            break;
            
        case 'update_score':
            $response = updateScore($pdo, $_POST, $judge_id);
            break;
            
        case 'get_heat_flow':
            $event_id = $_GET['event_id'] ?? null;
            $response = getHeatFlow($pdo, $event_id);
            break;
            
        case 'get_figures':
            $scoring_format_id = $_GET['scoring_format_id'] ?? null;
            $sport = $_GET['sport'] ?? null;
            $response = getFigures($pdo, $scoring_format_id, $sport);
            break;
            
        default:
            $response = [
                'success' => false,
                'message' => 'Invalid action: ' . $action
            ];
    }

    echo json_encode($response);

} catch (Exception $e) {
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => 'Server error: ' . $e->getMessage(),
        'error_code' => 'INTERNAL_ERROR'
    ]);
}

/**
 * Get judge context and basic information
 */
function getJudgeContext($pdo, $judge_id, $user_type) {
    try {
        // Get judge name
        $judge_stmt = $pdo->prepare("SELECT username FROM users WHERE id = ?");
        $judge_stmt->execute([$judge_id]);
        $judge_name = $judge_stmt->fetchColumn() ?: 'Unknown';

        // Get assigned events - simplified query
        $events_stmt = $pdo->prepare("
            SELECT e.id, e.name, e.date, e.scoring_format
            FROM events e
            ORDER BY e.date DESC
            LIMIT 10
        ");
        $events_stmt->execute();
        $assigned_events = $events_stmt->fetchAll(PDO::FETCH_ASSOC);

        return [
            'success' => true,
            'data' => [
                'judge_id' => $judge_id,
                'judge_name' => $judge_name,
                'user_type' => $user_type,
                'assigned_events' => $assigned_events,
                'default_event_id' => $assigned_events[0]['id'] ?? null
            ]
        ];
    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to get judge context: ' . $e->getMessage()
        ];
    }
}

/**
 * Get comprehensive event data
 */
function getEventData($pdo, $judge_id, $event_id) {
    try {
        if (!$event_id) {
            return ['success' => false, 'message' => 'Event ID required'];
        }

        // Get event basic info
        $event_stmt = $pdo->prepare("
            SELECT e.id, e.name, e.date, e.scoring_format, e.runs_per_heat, e.heats_total
            FROM events e
            WHERE e.id = ?
        ");
        $event_stmt->execute([$event_id]);
        $event = $event_stmt->fetch(PDO::FETCH_ASSOC);

        if (!$event) {
            return ['success' => false, 'message' => 'Event not found'];
        }

        // Get heats with fallback
        $heats = [];
        try {
            $heats_stmt = $pdo->prepare("
                SELECT heat_number, heat_name, scoring_type, runs_count, is_active
                FROM event_heat_settings 
                WHERE event_id = ? 
                ORDER BY heat_number ASC
            ");
            $heats_stmt->execute([$event_id]);
            $heats = $heats_stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            // Generate default heats if table doesn't exist
            $total_heats = intval($event['heats_total']) ?: 10;
            for ($i = 1; $i <= $total_heats; $i++) {
                $heats[] = [
                    'heat_number' => $i,
                    'heat_name' => "Heat $i",
                    'scoring_type' => 'standard',
                    'runs_count' => intval($event['runs_per_heat']) ?: 3,
                    'is_active' => 0
                ];
            }
        }

        // Get scoring criteria with fallback
        $scoring_criteria = [];
        if ($event['scoring_format']) {
            try {
                $criteria_stmt = $pdo->prepare("
                    SELECT criteria_name, criteria_type, min_value, max_value, default_value, sort_order
                    FROM scoring_format_criteria
                    WHERE format_id = ?
                    ORDER BY sort_order ASC, criteria_name ASC
                ");
                $criteria_stmt->execute([$event['scoring_format']]);
                $scoring_criteria = $criteria_stmt->fetchAll(PDO::FETCH_ASSOC);
            } catch (Exception $e) {
                // Ignore if table doesn't exist
            }
        }
        
        // Add default criteria if none found
        if (empty($scoring_criteria)) {
            $scoring_criteria = [
                ['name' => 'Difficulty', 'criteria_name' => 'Difficulty', 'min_score' => 0, 'max_score' => 100, 'sort_order' => 0],
                ['name' => 'Execution', 'criteria_name' => 'Execution', 'min_score' => 0, 'max_score' => 100, 'sort_order' => 1],
                ['name' => 'Amplitude', 'criteria_name' => 'Amplitude', 'min_score' => 0, 'max_score' => 100, 'sort_order' => 2],
                ['name' => 'Landing', 'criteria_name' => 'Landing', 'min_score' => 0, 'max_score' => 100, 'sort_order' => 3],
                ['name' => 'Variety', 'criteria_name' => 'Variety', 'min_score' => 0, 'max_score' => 100, 'sort_order' => 4],
                ['name' => 'Progression', 'criteria_name' => 'Progression', 'min_score' => 0, 'max_score' => 100, 'sort_order' => 5]
            ];
        }

        // Simple format configuration
        $format_config = [
            'scale_min' => 0,
            'scale_max' => 100,
            'precision_decimal' => 2
        ];

        // Get figures data (match logic from score.php with base sport fallback handled in getFigures)
        $figures_data = ['available' => false, 'categories' => [], 'items_by_category' => [], 'debug' => []];
        try {
            $figures_result = getFigures($pdo, $event['scoring_format']); // let helper derive sport + base sport
            $figures_data['debug']['raw_result_success'] = $figures_result['success'];
            $figures_data['debug']['figures_debug'] = $figures_result['data']['debug'] ?? ($figures_result['debug'] ?? []);
            if ($figures_result['success']) {
                $figures_data['available'] = true;
                $figures_data['categories'] = $figures_result['data']['categories'] ?? [];
                foreach (($figures_result['data']['figures'] ?? []) as $category => $figures) {
                    $figures_data['items_by_category'][$category] = array_map(function($fig) { return $fig['name']; }, $figures);
                }
                // Populate event sport if missing
                if (empty($event['sport']) && isset($figures_result['data']['resolved_sport'])) {
                    $event['sport'] = $figures_result['data']['resolved_sport'];
                }
            } else {
                $figures_data['debug']['message'] = $figures_result['message'] ?? 'No figures';
            }
        } catch (Exception $e) {
            $figures_data['debug']['exception'] = $e->getMessage();
        }

        // Get diversity rules
        $diversity_rules = [];
        if ($event['scoring_format']) {
            try {
                $div_stmt = $pdo->prepare("
                    SELECT rule_type, category, min_different, max_per_category, applies_to_runs
                    FROM scoring_format_diversity_rules
                    WHERE format_id = ?
                    ORDER BY rule_type, category
                ");
                $div_stmt->execute([$event['scoring_format']]);
                $diversity_rules = $div_stmt->fetchAll(PDO::FETCH_ASSOC);
            } catch (Exception $e) {
                // Ignore if table doesn't exist
            }
        }

        return [
            'success' => true,
            'data' => [
                'event' => $event,
                'heats' => $heats,
                'scoring_criteria' => $scoring_criteria,
                'format_config' => $format_config,
                'figures_data' => $figures_data,
                'diversity_rules' => $diversity_rules
            ]
        ];

    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to get event data: ' . $e->getMessage()
        ];
    }
}

/**
 * Get participants for specific heat and run
 */
function getParticipants($pdo, $event_id, $heat_number, $run_number, $judge_id) {
    try {
        if (!$event_id || !$heat_number || !$run_number) {
            return ['success' => false, 'message' => 'Event ID, heat number, and run number required'];
        }

        // Get participants with their scoring status
        $stmt = $pdo->prepare("
            SELECT 
                ep.id as ep_id,
                ep.bib_number,
                p.first_name,
                p.last_name,
                ep.heat_number,
                COALESCE(ep.sort_order, ep.bib_number) as sort_order
            FROM event_participants ep
            JOIN participants p ON ep.participant_id = p.id
            WHERE ep.event_id = ? AND ep.heat_number = ?
            ORDER BY sort_order ASC, ep.bib_number ASC
        ");
        $stmt->execute([$event_id, $heat_number]);
        $participants = $stmt->fetchAll(PDO::FETCH_ASSOC);

        // Check for existing scores for each participant
        foreach ($participants as &$participant) {
            try {
                $score_stmt = $pdo->prepare("
                    SELECT COUNT(*) 
                    FROM scores s 
                    JOIN runs r ON s.run_id = r.id 
                    WHERE r.event_participant_id = ? 
                      AND r.run_number = ? 
                      AND s.judge_id = ?
                ");
                $score_stmt->execute([$participant['ep_id'], $run_number, $judge_id]);
                $participant['is_scored'] = $score_stmt->fetchColumn() > 0 ? 1 : 0;
            } catch (Exception $e) {
                $participant['is_scored'] = 0;
            }
        }

        return [
            'success' => true,
            'data' => [
                'participants' => $participants,
                'event_id' => $event_id,
                'heat_number' => $heat_number,
                'run_number' => $run_number,
                'count' => count($participants)
            ]
        ];

    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to get participants: ' . $e->getMessage(),
            'debug' => [
                'event_id' => $event_id,
                'heat_number' => $heat_number,
                'run_number' => $run_number,
                'error' => $e->getMessage()
            ]
        ];
    }
}

/**
 * Get scoring form structure
 */
function getScoringForm($pdo, $event_id, $judge_id) {
    try {
        if (!$event_id) {
            return ['success' => false, 'message' => 'Event ID required'];
        }

        // Get event info
        $event_stmt = $pdo->prepare("SELECT name, runs_per_heat, heats_total FROM events WHERE id = ?");
        $event_stmt->execute([$event_id]);
        $event_data = $event_stmt->fetch(PDO::FETCH_ASSOC);

        if (!$event_data) {
            return ['success' => false, 'message' => 'Event not found'];
        }

        // Build form structure
        $form_structure = [
            'event_info' => [
                'event_id' => $event_id,
                'event_name' => $event_data['name'],
                'runs_per_heat' => $event_data['runs_per_heat'] ?: 3,
                'heats_total' => $event_data['heats_total'] ?: 10
            ],
            'scoring_config' => [
                'mode' => 'standard',
                'scale_min' => 0,
                'scale_max' => 100,
                'precision' => 2
            ],
            'status_options' => [
                ['value' => 'scored', 'label' => 'Scored', 'color' => 'success'],
                ['value' => 'dns', 'label' => 'DNS', 'color' => 'warning'],
                ['value' => 'dnf', 'label' => 'DNF', 'color' => 'danger']
            ]
        ];

        return [
            'success' => true,
            'data' => $form_structure
        ];

    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to get scoring form: ' . $e->getMessage()
        ];
    }
}

/**
 * Submit a new score
 */
function submitScore($pdo, $data, $judge_id) {
    try {
        $ep_id = $data['ep_id'] ?? null;
        $run_number = $data['run_number'] ?? null;
        $score_value = $data['score_value'] !== '' ? floatval($data['score_value']) : null;
        $status = $data['status'] ?? 'scored';
        $figures_json = $data['figures_json'] ?? '';
        $criteria_scores_json = $data['criteria_scores_json'] ?? '';

        if (!$ep_id || !$run_number) {
            return ['success' => false, 'message' => 'Participant and run number required'];
        }

        // Validate participant exists
        $validate_stmt = $pdo->prepare("SELECT event_id FROM event_participants WHERE id = ?");
        $validate_stmt->execute([$ep_id]);
        $event_id = $validate_stmt->fetchColumn();

        if (!$event_id) {
            return ['success' => false, 'message' => 'Invalid participant'];
        }

        $pdo->beginTransaction();

        // Create or get run
        $run_stmt = $pdo->prepare("SELECT id FROM runs WHERE event_participant_id = ? AND run_number = ?");
        $run_stmt->execute([$ep_id, $run_number]);
        $run = $run_stmt->fetch(PDO::FETCH_ASSOC);

        if (!$run) {
            $insert_run = $pdo->prepare("INSERT INTO runs (event_participant_id, run_number) VALUES (?, ?)");
            $insert_run->execute([$ep_id, $run_number]);
            $run_id = $pdo->lastInsertId();
        } else {
            $run_id = $run['id'];
        }

        // Check for existing score
        $existing_stmt = $pdo->prepare("SELECT id FROM scores WHERE run_id = ? AND judge_id = ?");
        $existing_stmt->execute([$run_id, $judge_id]);
        $existing_score = $existing_stmt->fetch(PDO::FETCH_ASSOC);

        // Check what columns exist in the scores table
        $hasColumns = checkScoreColumns($pdo);

        if ($existing_score) {
            // Update existing score with dynamic columns
            $updateParts = ["score_value = ?", "status = ?", "updated_at = NOW()"];
            $updateParams = [$score_value, $status];
            
            if ($hasColumns['figures_json'] && $figures_json) {
                $updateParts[] = "figures_json = ?";
                $updateParams[] = $figures_json;
            }
            
            if ($hasColumns['criteria_scores'] && $criteria_scores_json) {
                $updateParts[] = "criteria_scores = ?";
                $updateParams[] = $criteria_scores_json;
            }
            
            $updateParams[] = $existing_score['id'];
            
            $update_stmt = $pdo->prepare("UPDATE scores SET " . implode(", ", $updateParts) . " WHERE id = ?");
            $update_stmt->execute($updateParams);
            $score_id = $existing_score['id'];
        } else {
            // Insert new score with dynamic columns
            $insertCols = ["run_id", "judge_id", "score_value", "status"];
            $insertVals = ["?", "?", "?", "?"];
            $insertParams = [$run_id, $judge_id, $score_value, $status];
            
            if ($hasColumns['figures_json']) {
                $insertCols[] = "figures_json";
                $insertVals[] = "?";
                $insertParams[] = $figures_json ?: null;
            }
            
            if ($hasColumns['criteria_scores']) {
                $insertCols[] = "criteria_scores";
                $insertVals[] = "?";
                $insertParams[] = $criteria_scores_json ?: null;
            }
            
            $insert_stmt = $pdo->prepare("INSERT INTO scores (" . implode(", ", $insertCols) . ") VALUES (" . implode(", ", $insertVals) . ")");
            $insert_stmt->execute($insertParams);
            $score_id = $pdo->lastInsertId();
        }

        // Fetch the complete score data
        $fetch_stmt = $pdo->prepare("
            SELECT s.*, r.run_number, ep.bib_number, p.first_name, p.last_name, ep.heat_number
            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
            WHERE s.id = ?
        ");
        $fetch_stmt->execute([$score_id]);
        $score_data = $fetch_stmt->fetch(PDO::FETCH_ASSOC);

        $pdo->commit();

        return [
            'success' => true,
            'data' => $score_data,
            'message' => 'Score submitted successfully'
        ];

    } catch (Exception $e) {
        if ($pdo->inTransaction()) {
            $pdo->rollBack();
        }
        return [
            'success' => false,
            'message' => 'Failed to submit score: ' . $e->getMessage()
        ];
    }
}

/**
 * Check which columns exist in the scores table
 */
function checkScoreColumns($pdo) {
    $columns = [
        'figures_json' => false,
        'criteria_scores' => false,
        'control_point_id' => false
    ];
    
    try {
        $stmt = $pdo->query("DESCRIBE scores");
        $dbColumns = $stmt->fetchAll(PDO::FETCH_COLUMN);
        
        foreach ($dbColumns as $col) {
            if (isset($columns[$col])) {
                $columns[$col] = true;
            }
        }
    } catch (Exception $e) {
        // Ignore errors
    }
    
    return $columns;
}

/**
 * Get latest scores for the judge
 */
function getLatestScores($pdo, $event_id, $judge_id) {
    try {
        if (!$event_id) {
            return ['success' => false, 'message' => 'Event ID required'];
        }

        $stmt = $pdo->prepare("
            SELECT s.id, s.score_value, s.status, s.created_at,
                   r.run_number, ep.heat_number, ep.bib_number, 
                   p.first_name, p.last_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
            WHERE s.judge_id = ? AND ep.event_id = ?
            ORDER BY s.created_at DESC
            LIMIT 4
        ");
        $stmt->execute([$judge_id, $event_id]);
        $scores = $stmt->fetchAll(PDO::FETCH_ASSOC);

        return [
            'success' => true,
            'data' => $scores
        ];

    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to get latest scores: ' . $e->getMessage()
        ];
    }
}

/**
 * Get scores for a specific participant
 */
function getParticipantScores($pdo, $ep_id, $heat_number, $judge_id) {
    try {
        if (!$ep_id) {
            return ['success' => false, 'message' => 'Participant ID required'];
        }

    // Some databases may not yet have criteria_scores column; select only existing fields
    $stmt = $pdo->prepare("
        SELECT s.id, s.score_value, s.status, s.judge_id, s.run_id, s.figures_json, s.created_at, s.updated_at,
           r.run_number, u.username as judge_name
        FROM scores s
        JOIN runs r ON s.run_id = r.id
        LEFT JOIN users u ON s.judge_id = u.id
        WHERE r.event_participant_id = ?
        ORDER BY r.run_number ASC, u.username ASC
    ");
        $stmt->execute([$ep_id]);
        $scores = $stmt->fetchAll(PDO::FETCH_ASSOC);

        return [
            'success' => true,
            'data' => $scores
        ];

    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to get participant scores: ' . $e->getMessage()
        ];
    }
}

/**
 * Get figure history for participant
 */
function getFigureHistory($pdo, $ep_id, $judge_id) {
    try {
        if (!$ep_id) {
            return ['success' => false, 'message' => 'Participant ID required'];
        }

        $stmt = $pdo->prepare("
            SELECT r.run_number, s.figures_json
            FROM scores s
            JOIN runs r ON s.run_id = r.id
            WHERE r.event_participant_id = ? AND s.judge_id = ? AND s.figures_json IS NOT NULL
            ORDER BY r.run_number ASC
        ");
        $stmt->execute([$ep_id, $judge_id]);
        $results = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $figure_history = [];
        foreach ($results as $result) {
            if (!empty($result['figures_json'])) {
                $figures = json_decode($result['figures_json'], true);
                if ($figures) {
                    $figure_history[$result['run_number']] = $figures;
                }
            }
        }

        return [
            'success' => true,
            'data' => $figure_history
        ];

    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to get figure history: ' . $e->getMessage()
        ];
    }
}

/**
 * Update existing score
 */
function updateScore($pdo, $data, $judge_id) {
    try {
        $score_id = $data['score_id'] ?? null;
        $score_value = $data['score_value'] !== '' ? floatval($data['score_value']) : null;
        $status = $data['status'] ?? 'scored';
        $figures_json = $data['figures_json'] ?? '';

        if (!$score_id) {
            return ['success' => false, 'message' => 'Score ID required'];
        }

        // Validate score belongs to judge
        $validate_stmt = $pdo->prepare("SELECT id FROM scores WHERE id = ? AND judge_id = ?");
        $validate_stmt->execute([$score_id, $judge_id]);
        if (!$validate_stmt->fetch()) {
            return ['success' => false, 'message' => 'Invalid score or permission denied'];
        }

        // Update score
        $update_stmt = $pdo->prepare("
            UPDATE scores 
            SET score_value = ?, status = ?, figures_json = ?, updated_at = NOW()
            WHERE id = ? AND judge_id = ?
        ");
        $update_stmt->execute([$score_value, $status, $figures_json ?: null, $score_id, $judge_id]);

        // Fetch updated score
        $fetch_stmt = $pdo->prepare("
            SELECT s.*, r.run_number, ep.bib_number, p.first_name, p.last_name, ep.heat_number
            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
            WHERE s.id = ?
        ");
        $fetch_stmt->execute([$score_id]);
        $updated_score = $fetch_stmt->fetch(PDO::FETCH_ASSOC);

        return [
            'success' => true,
            'data' => $updated_score,
            'message' => 'Score updated successfully'
        ];

    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to update score: ' . $e->getMessage()
        ];
    }
}

/**
 * Get heat flow data (for auto mode)
 */
function getHeatFlow($pdo, $event_id) {
    try {
        if (!$event_id) {
            return ['success' => false, 'message' => 'Event ID required'];
        }

        // Get active heat information
        $active_heat = null;
        try {
            $heat_stmt = $pdo->prepare("
                SELECT heat_number, heat_name, active_run, is_active
                FROM event_heat_settings
                WHERE event_id = ? AND is_active = 1
                ORDER BY heat_number ASC
                LIMIT 1
            ");
            $heat_stmt->execute([$event_id]);
            $active_heat = $heat_stmt->fetch(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            // Table might not exist
        }

        return [
            'success' => true,
            'data' => [
                'active_heat' => $active_heat,
                'timestamp' => date('Y-m-d H:i:s')
            ]
        ];

    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to get heat flow: ' . $e->getMessage()
        ];
    }
}

/**
 * Get figures for scoring format or sport
 */
function getFigures($pdo, $scoring_format_id = null, $sport = null) {
    try {
        // Normalize incoming scoring_format_id (handle accidental whitespace)
        if (is_string($scoring_format_id)) {
            $scoring_format_id = trim($scoring_format_id);
        }

        if (!$scoring_format_id && !$sport) {
            return ['success' => false, 'message' => 'Scoring format ID or sport required'];
        }

        $debug = [
            'input_scoring_format' => $scoring_format_id,
            'initial_sport_param' => $sport,
            'derived_via_table' => false,
            'derived_from_slug' => false
        ];

        // If we have scoring format ID/slug, try to get the sport from scoring_formats table (numeric id assumption)
        if ($scoring_format_id && !$sport && is_numeric($scoring_format_id)) {
            $format_stmt = $pdo->prepare("SELECT sport FROM scoring_formats WHERE id = ?");
            $format_stmt->execute([$scoring_format_id]);
            $format_data = $format_stmt->fetch(PDO::FETCH_ASSOC);
            if ($format_data && !empty($format_data['sport'])) {
                $sport = $format_data['sport'];
                $debug['derived_via_table'] = true;
            }
        }

        // If still no sport and scoring_format_id looks like a slug (e.g. snowboard_big_air_best_two)
        if (!$sport && $scoring_format_id && !is_numeric($scoring_format_id)) {
            // Split on underscore or dash and take first token
            $parts = preg_split('/[_-]+/', $scoring_format_id);
            if ($parts && !empty($parts[0])) {
                $sport = strtolower($parts[0]);
                $debug['derived_from_slug'] = true;
                $debug['slug_base_token'] = $sport;
            }
        }

        if (!$sport) {
            return ['success' => false, 'message' => 'Could not determine sport', 'debug' => $debug];
        }

        // First try the figure_categories and figure_items tables (like score.php)
        try {
            // Check if sport has figures available
            $figCheck = $pdo->prepare("SELECT COUNT(*)
                                       FROM figure_categories fc
                                       JOIN figure_items fi ON fi.sport_name = fc.sport_name AND fi.category_name = fc.category_name
                                       WHERE fc.sport_name = ? AND fc.is_active = 1 AND fi.is_active = 1");
            $figCheck->execute([$sport]);
            $has_figures = (int)$figCheck->fetchColumn() > 0;

            if ($has_figures) {
                // Load categories
                $catStmt = $pdo->prepare("SELECT category_name FROM figure_categories WHERE sport_name = ? AND is_active = 1 ORDER BY sort_order, category_name");
                $catStmt->execute([$sport]);
                $categories = $catStmt->fetchAll(PDO::FETCH_COLUMN) ?: [];

                // Load items grouped by category
                $itemsStmt = $pdo->prepare("SELECT category_name, item_name FROM figure_items WHERE sport_name = ? AND is_active = 1 ORDER BY category_name, sort_order, item_name");
                $itemsStmt->execute([$sport]);
                $rows = $itemsStmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
                
                $grouped_figures = [];
                foreach ($rows as $r) {
                    $c = $r['category_name'];
                    if (!isset($grouped_figures[$c])) {
                        $grouped_figures[$c] = [];
                    }
                    $grouped_figures[$c][] = [
                        'id' => count($grouped_figures[$c]) + 1,
                        'name' => $r['item_name'],
                        'category' => $c,
                        'sport' => $sport,
                        'value' => 1.0,
                        'difficulty_level' => 'intermediate'
                    ];
                }

                return [
                    'success' => true,
                    'data' => [
                        'figures' => $grouped_figures,
                        'total_figures' => count($rows),
                        'categories' => $categories,
                        'source' => 'figure_categories_table',
                        'resolved_sport' => $sport,
                        'debug' => $debug
                    ]
                ];
            }
        } catch (Exception $e) {
            // Continue to fallback if tables don't exist
            $debug['figure_categories_exception'] = $e->getMessage();
        }

        // Fallback to figures table
        try {
            $stmt = $pdo->prepare("
                SELECT 
                    id,
                    name,
                    category,
                    sport,
                    value,
                    COALESCE(difficulty_level, 'beginner') as difficulty_level,
                    COALESCE(description, name) as description
                FROM figures 
                WHERE sport = ?
                ORDER BY category, value, name
            ");
            $stmt->execute([$sport]);
            $figures = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Group by category
            $grouped_figures = [];
            foreach ($figures as $figure) {
                $category = $figure['category'] ?: 'General';
                if (!isset($grouped_figures[$category])) {
                    $grouped_figures[$category] = [];
                }
                $grouped_figures[$category][] = $figure;
            }

            if (!empty($grouped_figures)) {
                return [
                    'success' => true,
                    'data' => [
                        'figures' => $grouped_figures,
                        'total_figures' => count($figures),
                        'categories' => array_keys($grouped_figures),
                        'source' => 'figures_table',
                        'resolved_sport' => $sport,
                        'debug' => $debug
                    ]
                ];
            }
        } catch (Exception $e) {
            // Continue to default figures
            $debug['figures_table_exception'] = $e->getMessage();
        }

        // Default figures fallback
        $default_figures = [
            // Default freestyle skiing taxonomy (also reused for snowboard until dedicated dataset provided)
            'freestyle_skiing' => [
                'Rotation' => [
                    ['id' => 1, 'name' => '540', 'value' => 2.5, 'difficulty_level' => 'intermediate'],
                    ['id' => 2, 'name' => '720', 'value' => 3.0, 'difficulty_level' => 'advanced'],
                    ['id' => 3, 'name' => '900', 'value' => 3.5, 'difficulty_level' => 'expert']
                ],
                'Direction' => [
                    ['id' => 4, 'name' => 'Backside', 'value' => 1.5, 'difficulty_level' => 'beginner'],
                    ['id' => 5, 'name' => 'Frontside', 'value' => 1.3, 'difficulty_level' => 'beginner']
                ],
                'Axis' => [
                    ['id' => 6, 'name' => 'Single Cork', 'value' => 2.0, 'difficulty_level' => 'intermediate'],
                    ['id' => 7, 'name' => 'Double Cork', 'value' => 3.0, 'difficulty_level' => 'advanced']
                ],
                'Grab' => [
                    ['id' => 8, 'name' => 'Mute', 'value' => 1.5, 'difficulty_level' => 'beginner'],
                    ['id' => 9, 'name' => 'Tail', 'value' => 1.3, 'difficulty_level' => 'beginner'],
                    ['id' => 10, 'name' => 'Safety', 'value' => 1.8, 'difficulty_level' => 'intermediate']
                ],
                'Feature' => [
                    ['id' => 11, 'name' => 'Box', 'value' => 1.0, 'difficulty_level' => 'beginner'],
                    ['id' => 12, 'name' => 'Rail', 'value' => 1.5, 'difficulty_level' => 'intermediate'],
                    ['id' => 13, 'name' => 'Jump', 'value' => 2.0, 'difficulty_level' => 'intermediate']
                ],
                'Rail' => [
                    ['id' => 14, 'name' => '270 In', 'value' => 1.8, 'difficulty_level' => 'intermediate'],
                    ['id' => 15, 'name' => '450 Out', 'value' => 2.2, 'difficulty_level' => 'advanced']
                ]
            ],
            // Snowboard currently mirrors freestyle_skiing taxonomy (can diverge later)
            'snowboard' => [
                'Rotation' => [
                    ['id' => 101, 'name' => '540', 'value' => 2.5, 'difficulty_level' => 'intermediate'],
                    ['id' => 102, 'name' => '720', 'value' => 3.0, 'difficulty_level' => 'advanced'],
                    ['id' => 103, 'name' => '900', 'value' => 3.5, 'difficulty_level' => 'expert']
                ],
                'Direction' => [
                    ['id' => 104, 'name' => 'Backside', 'value' => 1.5, 'difficulty_level' => 'beginner'],
                    ['id' => 105, 'name' => 'Frontside', 'value' => 1.3, 'difficulty_level' => 'beginner'],
                    ['id' => 106, 'name' => 'Switch', 'value' => 1.6, 'difficulty_level' => 'intermediate']
                ],
                'Axis' => [
                    ['id' => 107, 'name' => 'Single Cork', 'value' => 2.0, 'difficulty_level' => 'intermediate'],
                    ['id' => 108, 'name' => 'Double Cork', 'value' => 3.0, 'difficulty_level' => 'advanced']
                ],
                'Grab' => [
                    ['id' => 109, 'name' => 'Mute', 'value' => 1.5, 'difficulty_level' => 'beginner'],
                    ['id' => 110, 'name' => 'Tail', 'value' => 1.3, 'difficulty_level' => 'beginner'],
                    ['id' => 111, 'name' => 'Method', 'value' => 1.9, 'difficulty_level' => 'intermediate']
                ],
                'Feature' => [
                    ['id' => 112, 'name' => 'Box', 'value' => 1.0, 'difficulty_level' => 'beginner'],
                    ['id' => 113, 'name' => 'Rail', 'value' => 1.5, 'difficulty_level' => 'intermediate'],
                    ['id' => 114, 'name' => 'Jump', 'value' => 2.0, 'difficulty_level' => 'intermediate']
                ],
                'Rail' => [
                    ['id' => 115, 'name' => '270 In', 'value' => 1.8, 'difficulty_level' => 'intermediate'],
                    ['id' => 116, 'name' => '450 Out', 'value' => 2.2, 'difficulty_level' => 'advanced']
                ]
            ]
        ];

        $sport_figures = $default_figures[$sport] ?? [
            'General' => [
                ['id' => 1, 'name' => 'Basic Element', 'value' => 1.0, 'difficulty_level' => 'beginner'],
                ['id' => 2, 'name' => 'Intermediate Element', 'value' => 2.0, 'difficulty_level' => 'intermediate'],
                ['id' => 3, 'name' => 'Advanced Element', 'value' => 3.0, 'difficulty_level' => 'advanced']
            ]
        ];

        $debug['used_default'] = true;
        return [
            'success' => true,
            'data' => [
                'figures' => $sport_figures,
                'total_figures' => array_sum(array_map('count', $sport_figures)),
                'categories' => array_keys($sport_figures),
                'source' => 'default_data',
                'resolved_sport' => $sport,
                'debug' => $debug
            ]
        ];

    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to get figures: ' . $e->getMessage(),
            'debug' => [
                'scoring_format_id' => $scoring_format_id,
                'sport' => $sport,
                'error' => $e->getMessage()
            ]
        ];
    }
}
?>
