<?php
/**
 * Judge Scoring API
 * Handles all data operations for the judge scoring panel
 */

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;
}

include '../includes/auth_simple.php';
include '../includes/db.php';

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; // Use user_id as judge_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_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_latest_scores':
            $event_id = $_GET['event_id'] ?? null;
            $response = getLatestScores($pdo, $event_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;
            
        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
        $events_stmt = $pdo->prepare("
            SELECT e.id, e.name, e.date, e.scoring_format
            FROM events e
            JOIN judge_assignments ja ON e.id = ja.event_id
            WHERE ja.judge_id = ?
            ORDER BY e.date DESC
        ");
        $events_stmt->execute([$judge_id]);
        $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 including format, criteria, figures
 */
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.*, sf.name as format_name, sf.sport, sf.mode
            FROM events e
            LEFT JOIN scoring_formats sf ON e.scoring_format = sf.format_id
            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
        $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);

        // Get scoring criteria
        $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);

        // Get format configuration
        $format_config = [];
        if ($event['scoring_format']) {
            $format_stmt = $pdo->prepare("
                SELECT jf.min_judges, jf.max_judges, jf.scale_min, jf.scale_max, 
                       jf.scale_type, jf.precision_decimal, jf.drop_rule
                FROM scoring_format_judges jf
                WHERE jf.format_id = ?
            ");
            $format_stmt->execute([$event['scoring_format']]);
            $format_config = $format_stmt->fetch(PDO::FETCH_ASSOC) ?: [];
        }

        // Get figures data if available
        $figures_data = ['available' => false, 'categories' => [], 'items_by_category' => []];
        if (!empty($event['sport'])) {
            $fig_stmt = $pdo->prepare("
                SELECT DISTINCT category 
                FROM figures 
                WHERE sport = ? 
                ORDER BY category
            ");
            $fig_stmt->execute([$event['sport']]);
            $categories = $fig_stmt->fetchAll(PDO::FETCH_COLUMN);

            if (!empty($categories)) {
                $figures_data['available'] = true;
                $figures_data['categories'] = $categories;

                foreach ($categories as $category) {
                    $items_stmt = $pdo->prepare("
                        SELECT item 
                        FROM figures 
                        WHERE sport = ? AND category = ? 
                        ORDER BY item
                    ");
                    $items_stmt->execute([$event['sport'], $category]);
                    $figures_data['items_by_category'][$category] = $items_stmt->fetchAll(PDO::FETCH_COLUMN);
                }
            }
        }

        // Get diversity rules
        $diversity_rules = [];
        if ($event['scoring_format']) {
            $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);
        }

        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,
                ep.sort_order,
                -- Check if this participant has been scored by this judge for this run
                (SELECT COUNT(*) 
                 FROM scores s 
                 JOIN runs r ON s.run_id = r.id 
                 WHERE r.event_participant_id = ep.id 
                   AND r.run_number = ? 
                   AND s.judge_id = ?) as is_scored
            FROM event_participants ep
            JOIN participants p ON ep.participant_id = p.id
            WHERE ep.event_id = ? AND ep.heat_number = ?
            ORDER BY ep.sort_order ASC, ep.bib_number ASC
        ");
        $stmt->execute([$run_number, $judge_id, $event_id, $heat_number]);
        $participants = $stmt->fetchAll(PDO::FETCH_ASSOC);

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

    } catch (Exception $e) {
        return [
            'success' => false,
            'message' => 'Failed to get participants: ' . $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 and format info
        $event_stmt = $pdo->prepare("
            SELECT e.*, sf.mode, jf.scale_min, jf.scale_max, jf.precision_decimal
            FROM events e
            LEFT JOIN scoring_formats sf ON e.scoring_format = sf.format_id
            LEFT JOIN scoring_format_judges jf ON sf.format_id = jf.format_id
            WHERE e.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' => $event_data['mode'] ?? 'standard',
                'scale_min' => $event_data['scale_min'] ?? 0,
                'scale_max' => $event_data['scale_max'] ?? 100,
                'precision' => $event_data['precision_decimal'] ?? 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);

        if ($existing_score) {
            // Update existing score
            $update_stmt = $pdo->prepare("
                UPDATE scores 
                SET score_value = ?, status = ?, figures_json = ?, criteria_scores = ?, updated_at = NOW()
                WHERE id = ?
            ");
            $update_stmt->execute([$score_value, $status, $figures_json ?: null, $criteria_scores_json ?: null, $existing_score['id']]);
            $score_id = $existing_score['id'];
        } else {
            // Insert new score
            $insert_stmt = $pdo->prepare("
                INSERT INTO scores (run_id, judge_id, score_value, status, figures_json, criteria_scores)
                VALUES (?, ?, ?, ?, ?, ?)
            ");
            $insert_stmt->execute([$run_id, $judge_id, $score_value, $status, $figures_json ?: null, $criteria_scores_json ?: null]);
            $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) {
        $pdo->rollBack();
        return [
            'success' => false,
            'message' => 'Failed to submit score: ' . $e->getMessage()
        ];
    }
}

/**
 * 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.figures_json, 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 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
        $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);

        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()
        ];
    }
}

/**
 * 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 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'];
        }

        $stmt = $pdo->prepare("
            SELECT s.*, r.run_number, u.username as judge_name
            FROM scores s
            JOIN runs r ON s.run_id = r.id
            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()
        ];
    }
}
?>
