<?php
// --- API JEUX GROUPE ---
// Routes :
//   POST  games.php?action=create_game   → creer une partie (memory/timeline/popcorn/geo/sondage/juste_prix/alcool_order)
//   GET   games.php?action=get_game      → recuperer une partie
//   POST  games.php?action=submit_game   → soumettre son resultat
//   POST  games.php?action=vote_imposteur → voter pour l'imposteur
//   GET   games.php?action=league        → classement ligue hebdo du groupe

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }

require 'db.php';
require 'jwt_helper.php';

$action = $_GET['action'] ?? '';
$method = $_SERVER['REQUEST_METHOD'];
$body   = json_decode(file_get_contents('php://input'), true) ?? [];

// --- Semaine courante (lundi = debut) ---
function getWeekNumber() {
    $monday = new DateTime();
    $monday->setISODate((int)$monday->format('o'), (int)$monday->format('W'));
    $ref = new DateTime('2025-01-06'); // premier lundi 2025
    return (int)$monday->diff($ref)->days / 7;
}

// --- Tire N questions uniques pour un groupe (seed = groupId + gameType + semaine) ---
function pickQuestionsForGroup($pdo, $groupId, $gameType, $count = 10) {
    $week = getWeekNumber();
    $seed = crc32($groupId . $gameType . $week);
    // Recupere toutes les questions du type
    $stmt = $pdo->prepare("SELECT * FROM game_questions WHERE game_type = ? AND active = 1 ORDER BY id ASC");
    $stmt->execute([$gameType]);
    $all = $stmt->fetchAll();
    if (empty($all)) return [];
    // Shuffle deterministe avec le seed
    $indices = range(0, count($all) - 1);
    srand($seed);
    shuffle($indices);
    srand(); // reset
    $picked = array_slice($indices, 0, min($count, count($all)));
    return array_map(fn($i) => $all[$i], $picked);
}

function fallbackQuestionsForGame($gameType) {
    $timeline = [
        ['game_type'=>'timeline','question'=>'Sortie du premier film Toy Story','options'=>[],'answer'=>'1995','explanation'=>'Toy Story est le premier long metrage entierement realise en images de synthese par Pixar.','date_event'=>'1995','hints'=>null],
        ['game_type'=>'timeline','question'=>'Lancement de YouTube','options'=>[],'answer'=>'2005','explanation'=>'YouTube est lance en 2005 par Steve Chen, Chad Hurley et Jawed Karim.','date_event'=>'2005','hints'=>null],
        ['game_type'=>'timeline','question'=>'Sortie du premier iPhone','options'=>[],'answer'=>'2007','explanation'=>'Steve Jobs presente le premier iPhone en janvier 2007.','date_event'=>'2007','hints'=>null],
        ['game_type'=>'timeline','question'=>'Creation d Instagram','options'=>[],'answer'=>'2010','explanation'=>'Instagram est lance en octobre 2010 avant son rachat par Meta.','date_event'=>'2010','hints'=>null],
        ['game_type'=>'timeline','question'=>'Sortie du jeu Minecraft en version officielle','options'=>[],'answer'=>'2011','explanation'=>'Minecraft sort officiellement en 2011 apres une longue phase alpha/beta.','date_event'=>'2011','hints'=>null],
        ['game_type'=>'timeline','question'=>'Premiere diffusion de Stranger Things','options'=>[],'answer'=>'2016','explanation'=>'Stranger Things arrive sur Netflix en juillet 2016.','date_event'=>'2016','hints'=>null],
        ['game_type'=>'timeline','question'=>'Sortie du film Avengers: Endgame','options'=>[],'answer'=>'2019','explanation'=>'Avengers: Endgame conclut la saga de l Infini du MCU en 2019.','date_event'=>'2019','hints'=>null],
        ['game_type'=>'timeline','question'=>'Sortie du film Barbie de Greta Gerwig','options'=>[],'answer'=>'2023','explanation'=>'Barbie devient l un des grands phenomenes cinema de 2023.','date_event'=>'2023','hints'=>null],
    ];

    $popcorn = [
        ['game_type'=>'popcorn','question'=>'De quelle oeuvre ou personnalite pop culture parle-t-on ?','options'=>['Stranger Things','Dark','The Boys','Wednesday'],'answer'=>'Stranger Things','explanation'=>'Serie Netflix devenue culte avec Eleven, Hawkins et le monde a l envers.','date_event'=>null,'hints'=>['Une petite ville americaine cache des experiences scientifiques inquietantes.','Un monde parallele y est appele l Upside Down.','Eleven adore les gaufres.']],
        ['game_type'=>'popcorn','question'=>'De quelle oeuvre ou personnalite pop culture parle-t-on ?','options'=>['One Piece','Naruto','Demon Slayer','Jujutsu Kaisen'],'answer'=>'One Piece','explanation'=>'Manga et anime centre sur Luffy et son equipage a la recherche du tresor ultime.','date_event'=>null,'hints'=>['Un heros elastique veut devenir le roi d un monde de pirates.','Son equipage navigue sur Grand Line.','Son tresor ultime donne son nom a l oeuvre.']],
        ['game_type'=>'popcorn','question'=>'De quelle oeuvre ou personnalite pop culture parle-t-on ?','options'=>['GP Explorer','Koh-Lanta','Top Gear France','Formula 1 Drive to Survive'],'answer'=>'GP Explorer','explanation'=>'Evenement cree par Squeezie autour d une course de Formule 4 avec des createurs web.','date_event'=>null,'hints'=>['Des createurs de contenu s affrontent sur circuit.','L evenement tourne autour de la Formule 4.','Squeezie en est l organisateur.']],
        ['game_type'=>'popcorn','question'=>'De quelle oeuvre ou personnalite pop culture parle-t-on ?','options'=>['Breaking Bad','Better Call Saul','Ozark','Narcos'],'answer'=>'Breaking Bad','explanation'=>'Serie culte avec Walter White, Jesse Pinkman et l empire de methamphetamine.','date_event'=>null,'hints'=>['Un professeur de chimie bascule dans le crime.','Los Pollos Hermanos y joue un role important.','Le duo central s appelle Walter et Jesse.']],
        ['game_type'=>'popcorn','question'=>'De quelle oeuvre ou personnalite pop culture parle-t-on ?','options'=>['Arcane','Cyberpunk Edgerunners','Castlevania','Invincible'],'answer'=>'Arcane','explanation'=>'Serie animee adaptee de League of Legends, centree sur Piltover, Zaun, Vi et Jinx.','date_event'=>null,'hints'=>['Deux villes opposees structurent l histoire.','Deux soeurs, Vi et Jinx, sont au coeur du drame.','La serie vient de l univers League of Legends.']],
        ['game_type'=>'popcorn','question'=>'De quelle oeuvre ou personnalite pop culture parle-t-on ?','options'=>['Inoxtag','Squeezie','Mister V','Gotaga'],'answer'=>'Inoxtag','explanation'=>'Createur francais connu notamment pour son documentaire Kaizen et son ascension de l Everest.','date_event'=>null,'hints'=>['Createur web francais tres suivi par les jeunes.','Il a documente une enorme preparation physique.','Son projet Kaizen culmine avec l Everest.']],
        ['game_type'=>'popcorn','question'=>'De quelle oeuvre ou personnalite pop culture parle-t-on ?','options'=>['Fortnite','Minecraft','Roblox','Fall Guys'],'answer'=>'Fortnite','explanation'=>'Battle royale d Epic Games connu pour ses skins, ses danses et ses evenements live.','date_event'=>null,'hints'=>['Le jeu melange combat, construction et saisons.','Il accueille souvent des concerts et crossovers enormes.','Le bus de combat est devenu iconique.']],
        ['game_type'=>'popcorn','question'=>'De quelle oeuvre ou personnalite pop culture parle-t-on ?','options'=>['Demon Slayer','My Hero Academia','Dragon Ball Super','Spy x Family'],'answer'=>'Demon Slayer','explanation'=>'Anime et manga ou Tanjiro affronte des demons pour sauver sa soeur Nezuko.','date_event'=>null,'hints'=>['Un jeune heros porte souvent une boite en bois.','Sa soeur a ete transformee.','Tanjiro et Nezuko sont les deux noms a retenir.']],
    ];

    $alcoolOrder = [
        ['game_type'=>'alcool_order','question'=>'Biere sans alcool','options'=>[],'answer'=>'0.5','explanation'=>'Une biere dite sans alcool peut contenir jusqu a 1,2% vol. en France, mais beaucoup tournent autour de 0,5%.','date_event'=>'0,5% vol.','hints'=>null],
        ['game_type'=>'alcool_order','question'=>'Panache','options'=>[],'answer'=>'1.5','explanation'=>'Le panache melange biere et limonade : son degre est generalement tres faible.','date_event'=>'1,5% vol.','hints'=>null],
        ['game_type'=>'alcool_order','question'=>'Biere blonde classique','options'=>[],'answer'=>'5','explanation'=>'Beaucoup de lagers et blondes classiques sont proches de 5% vol.','date_event'=>'5% vol.','hints'=>null],
        ['game_type'=>'alcool_order','question'=>'Cidre brut','options'=>[],'answer'=>'5.5','explanation'=>'Le cidre brut varie selon les maisons, souvent autour de 4,5 a 6% vol.','date_event'=>'5,5% vol.','hints'=>null],
        ['game_type'=>'alcool_order','question'=>'IPA','options'=>[],'answer'=>'6.5','explanation'=>'Les IPA modernes sont souvent autour de 6 a 7% vol.','date_event'=>'6,5% vol.','hints'=>null],
        ['game_type'=>'alcool_order','question'=>'Champagne brut','options'=>[],'answer'=>'12','explanation'=>'Le champagne est generalement autour de 12% vol.','date_event'=>'12% vol.','hints'=>null],
        ['game_type'=>'alcool_order','question'=>'Vin rouge classique','options'=>[],'answer'=>'13.5','explanation'=>'Beaucoup de rouges modernes se situent autour de 13 a 14,5% vol.','date_event'=>'13,5% vol.','hints'=>null],
        ['game_type'=>'alcool_order','question'=>'Porto','options'=>[],'answer'=>'20','explanation'=>'Le porto est un vin fortifie, souvent proche de 19 a 22% vol.','date_event'=>'20% vol.','hints'=>null],
        ['game_type'=>'alcool_order','question'=>'Vodka','options'=>[],'answer'=>'40','explanation'=>'La vodka classique est tres souvent embouteillee a 40% vol.','date_event'=>'40% vol.','hints'=>null],
        ['game_type'=>'alcool_order','question'=>'Absinthe','options'=>[],'answer'=>'60','explanation'=>'L absinthe peut etre tres forte, souvent entre 45 et 70% vol. selon les bouteilles.','date_event'=>'60% vol.','hints'=>null],
    ];

    if ($gameType === 'timeline') return $timeline;
    if ($gameType === 'popcorn') return $popcorn;
    if ($gameType === 'alcool_order') return $alcoolOrder;
    return [];
}

// --- CREATE GAME ---
if ($action === 'create_game' && $method === 'POST') {
    $userId   = requireAuth();
    $groupId  = (int)($body['group_id'] ?? 0);
    $gameType = trim($body['game_type'] ?? '');

    if (!$groupId || !in_array($gameType, ['memory','geo','sondage','juste_prix','timeline','popcorn','alcool_order'])) {
        http_response_code(400);
        echo json_encode(['message' => 'game_type invalide']);
        exit;
    }

    // Verif membre
    $stmt = $pdo->prepare("SELECT 1 FROM group_members WHERE group_id = ? AND user_id = ?");
    $stmt->execute([$groupId, $userId]);
    if (!$stmt->fetch()) { http_response_code(403); echo json_encode(['message' => 'Acces refuse']); exit; }

    // Verif pas deja une partie active cette semaine pour ce type
    $week = getWeekNumber();
    $stmt = $pdo->prepare("SELECT id FROM group_games WHERE group_id = ? AND game_type = ? AND week_number = ?");
    $stmt->execute([$groupId, $gameType, $week]);
    $existing = $stmt->fetch();
    if ($existing) {
        echo json_encode(['game_id' => $existing['id'], 'already_exists' => true]);
        exit;
    }

    // Tire les questions
    $counts = ['memory' => 8, 'timeline' => 8, 'popcorn' => 8, 'geo' => 5, 'sondage' => 5, 'juste_prix' => 8, 'alcool_order' => 8];
    $count = $counts[$gameType] ?? 10;
    $questions = pickQuestionsForGroup($pdo, $groupId, $gameType, $count);
    if (count($questions) < $count && in_array($gameType, ['timeline','popcorn','alcool_order'])) {
        $questions = fallbackQuestionsForGame($gameType);
    }
    if (empty($questions)) {
        http_response_code(500);
        echo json_encode(['message' => 'Pas assez de questions disponibles pour ce jeu']);
        exit;
    }

    // Pour imposteur : designe un imposteur aleatoire parmi les membres
    $imposteurUserId = null;
    if ($gameType === 'imposteur') {
        $stmt = $pdo->prepare("SELECT user_id FROM group_members WHERE group_id = ? ORDER BY RAND() LIMIT 1");
        $stmt->execute([$groupId]);
        $imp = $stmt->fetch();
        $imposteurUserId = $imp ? (int)$imp['user_id'] : null;
    }

    $questionsJson = json_encode($questions, JSON_UNESCAPED_UNICODE);
    $pdo->prepare("INSERT INTO group_games (group_id, game_type, week_number, questions_json, imposteur_user_id, created_by) VALUES (?, ?, ?, ?, ?, ?)")
        ->execute([$groupId, $gameType, $week, $questionsJson, $imposteurUserId, $userId]);
    $gameId = (int)$pdo->lastInsertId();

    echo json_encode(['game_id' => $gameId, 'already_exists' => false]);
    exit;
}

// --- GET GAME ---
if ($action === 'get_game' && $method === 'GET') {
    $userId = requireAuth();
    $gameId = (int)($_GET['game_id'] ?? 0);

    if (!$gameId) { http_response_code(400); echo json_encode(['message' => 'game_id requis']); exit; }

    $stmt = $pdo->prepare("SELECT gg.*, u.username AS created_by_name FROM group_games gg JOIN users u ON u.id = gg.created_by JOIN group_members gm ON gm.group_id = gg.group_id AND gm.user_id = ? WHERE gg.id = ?");
    $stmt->execute([$userId, $gameId]);
    $game = $stmt->fetch();
    if (!$game) { http_response_code(403); echo json_encode(['message' => 'Jeu introuvable ou acces refuse']); exit; }

    $questions = json_decode($game['questions_json'], true);

    // Pour imposteur : si c'est moi l'imposteur, je recois une fausse reponse sur la Q1
    $isImposteur = ($game['game_type'] === 'imposteur' && (int)$game['imposteur_user_id'] === $userId);
    if ($isImposteur && !empty($questions)) {
        // Remplace la bonne reponse de la Q1 par une mauvaise
        $wrongOptions = array_filter($questions[0]['options'] ?? [], fn($o) => $o !== $questions[0]['answer']);
        if (!empty($wrongOptions)) {
            $questions[0]['answer'] = array_values($wrongOptions)[0];
        }
    }

    // Mon resultat
    $stmt = $pdo->prepare("SELECT score, good, bad, time_ms, finished_at FROM game_results WHERE game_id = ? AND user_id = ?");
    $stmt->execute([$gameId, $userId]);
    $myResult = $stmt->fetch() ?: null;

    // Resultats de tous (visibles apres avoir joue)
    $results = [];
    if ($myResult) {
        $stmt = $pdo->prepare("SELECT gr.score, gr.good, gr.bad, gr.time_ms, gr.finished_at, u.username FROM game_results gr JOIN users u ON u.id = gr.user_id WHERE gr.game_id = ? ORDER BY gr.score DESC, gr.time_ms ASC");
        $stmt->execute([$gameId]);
        $results = $stmt->fetchAll();
    }

    // Votes imposteur (visibles apres avoir joue)
    $votes = [];
    $imposteurRevealed = null;
    if ($game['game_type'] === 'imposteur' && $myResult) {
        $stmt = $pdo->prepare("SELECT iv.voted_for_user_id, u.username AS voted_for, COUNT(*) AS vote_count FROM imposteur_votes iv JOIN users u ON u.id = iv.voted_for_user_id WHERE iv.game_id = ? GROUP BY iv.voted_for_user_id ORDER BY vote_count DESC");
        $stmt->execute([$gameId]);
        $votes = $stmt->fetchAll();
        $stmt = $pdo->prepare("SELECT u.username FROM users u WHERE u.id = ?");
        $stmt->execute([$game['imposteur_user_id']]);
        $imp = $stmt->fetch();
        $imposteurRevealed = $imp ? $imp['username'] : null;
    }

    // Reponses sondage (visibles apres avoir joue)
    $sondageAnswers = [];
    if ($game['game_type'] === 'sondage' && $myResult) {
        $stmt = $pdo->prepare("SELECT sa.question_index, sa.estimate, u.username FROM sondage_answers sa JOIN users u ON u.id = sa.user_id WHERE sa.game_id = ? ORDER BY sa.question_index, ABS(sa.estimate - (SELECT correct_value FROM game_questions WHERE id = (SELECT JSON_UNQUOTE(JSON_EXTRACT(gg.questions_json, CONCAT('$[', sa.question_index, '].id'))) FROM group_games gg WHERE gg.id = sa.game_id)))");
        $stmt->execute([$gameId]);
        $sondageAnswers = $stmt->fetchAll();
    }

    // Estimations juste prix (visibles apres avoir joue)
    $justeAnswers = [];
    if ($game['game_type'] === 'juste_prix' && $myResult) {
        $stmt = $pdo->prepare("SELECT ja.question_index, ja.estimate, ja.score_pts, u.username FROM juste_prix_answers ja JOIN users u ON u.id = ja.user_id WHERE ja.game_id = ? ORDER BY ja.question_index, ja.score_pts DESC");
        $stmt->execute([$gameId]);
        $justeAnswers = $stmt->fetchAll();
    }

    // Nombre de membres du groupe
    $stmt = $pdo->prepare("SELECT COUNT(*) AS cnt FROM group_members WHERE group_id = ?");
    $stmt->execute([$game['group_id']]);
    $memberCount = (int)$stmt->fetch()['cnt'];

    // Pour geo : indices progressifs selon nb de mauvaises reponses de l'utilisateur
    $geoHintIndex = 0;
    $geoMyAnswers = [];
    if ($game['game_type'] === 'geo') {
        $stmt = $pdo->prepare("SELECT question_index, attempt, answer, correct FROM geo_answers WHERE game_id = ? AND user_id = ? ORDER BY question_index, attempt");
        $stmt->execute([$gameId, $userId]);
        $geoMyAnswers = $stmt->fetchAll();
    }

    echo json_encode([
        'game' => [
            'id'                => (int)$game['id'],
            'game_type'         => $game['game_type'],
            'week_number'       => (int)$game['week_number'],
            'group_id'          => (int)$game['group_id'],
            'created_by'        => $game['created_by_name'],
            'questions'         => $questions,
            'my_result'         => $myResult,
            'results'           => $results,
            'member_count'      => $memberCount,
            'is_imposteur'      => $isImposteur,
            'votes'             => $votes,
            'imposteur_revealed'=> $imposteurRevealed,
            'sondage_answers'   => $sondageAnswers,
            'juste_answers'     => $justeAnswers,
            'geo_my_answers'    => $geoMyAnswers,
        ]
    ]);
    exit;
}

// --- SUBMIT GEO ANSWER (tentative sur une question geo) ---
if ($action === 'submit_geo' && $method === 'POST') {
    $userId        = requireAuth();
    $gameId        = (int)($body['game_id']        ?? 0);
    $questionIndex = (int)($body['question_index'] ?? 0);
    $answer        = trim($body['answer']          ?? '');

    if (!$gameId || !$answer) { http_response_code(400); echo json_encode(['message' => 'Parametres manquants']); exit; }

    $stmt = $pdo->prepare("SELECT gg.questions_json, gg.group_id FROM group_games gg JOIN group_members gm ON gm.group_id = gg.group_id AND gm.user_id = ? WHERE gg.id = ? AND gg.game_type = 'geo'");
    $stmt->execute([$userId, $gameId]);
    $game = $stmt->fetch();
    if (!$game) { http_response_code(403); echo json_encode(['message' => 'Acces refuse']); exit; }

    $questions = json_decode($game['questions_json'], true);
    $q = $questions[$questionIndex] ?? null;
    if (!$q) { http_response_code(400); echo json_encode(['message' => 'Question introuvable']); exit; }

    // Compte les tentatives existantes
    $stmt = $pdo->prepare("SELECT COUNT(*) AS cnt FROM geo_answers WHERE game_id = ? AND user_id = ? AND question_index = ?");
    $stmt->execute([$gameId, $userId, $questionIndex]);
    $attempt = (int)$stmt->fetch()['cnt'];
    if ($attempt >= 4) { echo json_encode(['message' => 'Max tentatives atteint', 'correct' => false, 'attempt' => $attempt]); exit; }

    // Verifie si correct (insensible a la casse)
    $correct = strtolower(trim($answer)) === strtolower(trim($q['answer']));

    $pdo->prepare("INSERT INTO geo_answers (game_id, user_id, question_index, attempt, answer, correct) VALUES (?, ?, ?, ?, ?, ?)")
        ->execute([$gameId, $userId, $questionIndex, $attempt + 1, $answer, $correct ? 1 : 0]);

    // Score : 10 pts si correct au 1er essai, 7 au 2e, 4 au 3e, 1 au 4e
    $pts = $correct ? max(1, 10 - ($attempt * 3)) : 0;

    echo json_encode([
        'correct'      => $correct,
        'attempt'      => $attempt + 1,
        'score_pts'    => $pts,
        'correct_answer' => $correct || $attempt >= 3 ? $q['answer'] : null,
        'next_hint'    => !$correct && $attempt < 3 ? ($q['hints'][$attempt + 1] ?? null) : null,
    ]);
    exit;
}

// --- SUBMIT SONDAGE ANSWER ---
if ($action === 'submit_sondage' && $method === 'POST') {
    $userId    = requireAuth();
    $gameId    = (int)($body['game_id']    ?? 0);
    $answers   = $body['answers']          ?? []; // [{question_index, estimate}]

    if (!$gameId || empty($answers)) { http_response_code(400); echo json_encode(['message' => 'Parametres manquants']); exit; }

    $stmt = $pdo->prepare("SELECT gg.questions_json, gg.group_id FROM group_games gg JOIN group_members gm ON gm.group_id = gg.group_id AND gm.user_id = ? WHERE gg.id = ? AND gg.game_type = 'sondage'");
    $stmt->execute([$userId, $gameId]);
    $game = $stmt->fetch();
    if (!$game) { http_response_code(403); echo json_encode(['message' => 'Acces refuse']); exit; }

    // Deja soumis ?
    $stmt = $pdo->prepare("SELECT 1 FROM game_results WHERE game_id = ? AND user_id = ?");
    $stmt->execute([$gameId, $userId]);
    if ($stmt->fetch()) { http_response_code(409); echo json_encode(['message' => 'Deja soumis']); exit; }

    $questions = json_decode($game['questions_json'], true);
    $totalScore = 0;

    $insertAnswer = $pdo->prepare("INSERT INTO sondage_answers (game_id, user_id, question_index, estimate) VALUES (?, ?, ?, ?)");
    foreach ($answers as $a) {
        $qi = (int)($a['question_index'] ?? 0);
        $estimate = (int)($a['estimate'] ?? 0);
        $q = $questions[$qi] ?? null;
        if (!$q) continue;
        $correct = (int)$q['answer'];
        $diff = abs($estimate - $correct);
        // Score : 10 pts si ecart <= 2%, degressif jusqu'a 0 si ecart > 20%
        $pts = max(0, (int)(10 - floor($diff / 2)));
        $totalScore += $pts;
        $insertAnswer->execute([$gameId, $userId, $qi, $estimate]);
    }

    $pdo->prepare("INSERT INTO game_results (game_id, user_id, score, good, bad, time_ms) VALUES (?, ?, ?, 0, 0, 0)")
        ->execute([$gameId, $userId, $totalScore]);

    $week = getWeekNumber();
    $pdo->prepare("INSERT INTO league_scores (group_id, user_id, week_number, points) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE points = points + VALUES(points)")
        ->execute([$game['group_id'], $userId, $week, $totalScore]);

    echo json_encode(['score' => $totalScore]);
    exit;
}

// --- SUBMIT JUSTE PRIX ANSWER ---
if ($action === 'submit_juste_prix' && $method === 'POST') {
    $userId  = requireAuth();
    $gameId  = (int)($body['game_id'] ?? 0);
    $answers = $body['answers']       ?? []; // [{question_index, estimate}]

    if (!$gameId || empty($answers)) { http_response_code(400); echo json_encode(['message' => 'Parametres manquants']); exit; }

    $stmt = $pdo->prepare("SELECT gg.questions_json, gg.group_id FROM group_games gg JOIN group_members gm ON gm.group_id = gg.group_id AND gm.user_id = ? WHERE gg.id = ? AND gg.game_type = 'juste_prix'");
    $stmt->execute([$userId, $gameId]);
    $game = $stmt->fetch();
    if (!$game) { http_response_code(403); echo json_encode(['message' => 'Acces refuse']); exit; }

    $stmt = $pdo->prepare("SELECT 1 FROM game_results WHERE game_id = ? AND user_id = ?");
    $stmt->execute([$gameId, $userId]);
    if ($stmt->fetch()) { http_response_code(409); echo json_encode(['message' => 'Deja soumis']); exit; }

    $questions = json_decode($game['questions_json'], true);
    $totalScore = 0;

    $insertAnswer = $pdo->prepare("INSERT INTO juste_prix_answers (game_id, user_id, question_index, estimate, score_pts) VALUES (?, ?, ?, ?, ?)");
    $details = [];
    foreach ($answers as $a) {
        $qi = (int)($a['question_index'] ?? 0);
        $estimate = (float)($a['estimate'] ?? 0);
        $q = $questions[$qi] ?? null;
        if (!$q) continue;
        $correct = (float)$q['answer'];
        $diff = abs($estimate - $correct);
        $diffPct = $correct > 0 ? (($diff / $correct) * 100) : ($estimate == 0 ? 0 : 100);
        $precision = max(0, 100 - $diffPct);
        // Score lisible : chaque question vaut 20 pts. Points = precision (%) / 5.
        $pts = max(0, min(20, (int)round($precision / 5)));
        $totalScore += $pts;
        $insertAnswer->execute([$gameId, $userId, $qi, $estimate, $pts]);
        $details[] = ['question_index' => $qi, 'estimate' => $estimate, 'correct' => $correct, 'diff_pct' => (int)round($diffPct), 'precision' => (int)round($precision), 'score_pts' => $pts];
    }

    $pdo->prepare("INSERT INTO game_results (game_id, user_id, score, good, bad, time_ms) VALUES (?, ?, ?, 0, 0, 0)")
        ->execute([$gameId, $userId, $totalScore]);

    $week = getWeekNumber();
    $pdo->prepare("INSERT INTO league_scores (group_id, user_id, week_number, points) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE points = points + VALUES(points)")
        ->execute([$game['group_id'], $userId, $week, $totalScore]);

    echo json_encode(['score' => $totalScore, 'details' => $details]);
    exit;
}

// --- SUBMIT GAME ---
if ($action === 'submit_game' && $method === 'POST') {
    $userId  = requireAuth();
    $gameId  = (int)($body['game_id'] ?? 0);
    $score   = (int)($body['score']   ?? 0);
    $good    = (int)($body['good']    ?? 0);
    $bad     = (int)($body['bad']     ?? 0);
    $timeMs  = (int)($body['time_ms'] ?? 0);

    if (!$gameId) { http_response_code(400); echo json_encode(['message' => 'game_id requis']); exit; }

    // Verif acces
    $stmt = $pdo->prepare("SELECT gg.group_id, gg.game_type FROM group_games gg JOIN group_members gm ON gm.group_id = gg.group_id AND gm.user_id = ? WHERE gg.id = ?");
    $stmt->execute([$userId, $gameId]);
    $game = $stmt->fetch();
    if (!$game) { http_response_code(403); echo json_encode(['message' => 'Acces refuse']); exit; }

    // Deja soumis ?
    $stmt = $pdo->prepare("SELECT 1 FROM game_results WHERE game_id = ? AND user_id = ?");
    $stmt->execute([$gameId, $userId]);
    if ($stmt->fetch()) { http_response_code(409); echo json_encode(['message' => 'Deja soumis']); exit; }

    $pdo->prepare("INSERT INTO game_results (game_id, user_id, score, good, bad, time_ms) VALUES (?, ?, ?, ?, ?, ?)")
        ->execute([$gameId, $userId, $score, $good, $bad, $timeMs]);

    // Ajoute les points a la ligue hebdo
    $week = getWeekNumber();
    $pdo->prepare("INSERT INTO league_scores (group_id, user_id, week_number, points) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE points = points + VALUES(points)")
        ->execute([$game['group_id'], $userId, $week, $score]);

    echo json_encode(['message' => 'Resultat enregistre', 'score' => $score]);
    exit;
}

// --- VOTE IMPOSTEUR ---
if ($action === 'vote_imposteur' && $method === 'POST') {
    $userId          = requireAuth();
    $gameId          = (int)($body['game_id']           ?? 0);
    $votedForUserId  = (int)($body['voted_for_user_id'] ?? 0);

    if (!$gameId || !$votedForUserId) { http_response_code(400); echo json_encode(['message' => 'game_id et voted_for_user_id requis']); exit; }

    // Verif acces + deja joue
    $stmt = $pdo->prepare("SELECT 1 FROM game_results WHERE game_id = ? AND user_id = ?");
    $stmt->execute([$gameId, $userId]);
    if (!$stmt->fetch()) { http_response_code(403); echo json_encode(['message' => 'Tu dois avoir joue avant de voter']); exit; }

    // Deja vote ?
    $stmt = $pdo->prepare("SELECT 1 FROM imposteur_votes WHERE game_id = ? AND voter_user_id = ?");
    $stmt->execute([$gameId, $userId]);
    if ($stmt->fetch()) { http_response_code(409); echo json_encode(['message' => 'Deja vote']); exit; }

    $pdo->prepare("INSERT INTO imposteur_votes (game_id, voter_user_id, voted_for_user_id) VALUES (?, ?, ?)")
        ->execute([$gameId, $userId, $votedForUserId]);

    echo json_encode(['message' => 'Vote enregistre']);
    exit;
}

// --- LEAGUE ---
if ($action === 'league' && $method === 'GET') {
    $userId  = requireAuth();
    $groupId = (int)($_GET['group_id'] ?? 0);
    if (!$groupId) { http_response_code(400); echo json_encode(['message' => 'group_id requis']); exit; }

    // Verif membre
    $stmt = $pdo->prepare("SELECT 1 FROM group_members WHERE group_id = ? AND user_id = ?");
    $stmt->execute([$groupId, $userId]);
    if (!$stmt->fetch()) { http_response_code(403); echo json_encode(['message' => 'Acces refuse']); exit; }

    $week = getWeekNumber();

    // Classement semaine courante
    $stmt = $pdo->prepare("SELECT u.username, ls.points FROM league_scores ls JOIN users u ON u.id = ls.user_id WHERE ls.group_id = ? AND ls.week_number = ? ORDER BY ls.points DESC");
    $stmt->execute([$groupId, $week]);
    $current = $stmt->fetchAll();

    // Classement semaine precedente
    $stmt = $pdo->prepare("SELECT u.username, ls.points FROM league_scores ls JOIN users u ON u.id = ls.user_id WHERE ls.group_id = ? AND ls.week_number = ? ORDER BY ls.points DESC");
    $stmt->execute([$groupId, $week - 1]);
    $previous = $stmt->fetchAll();

    // Jeux de cette semaine
    $stmt = $pdo->prepare("SELECT gg.id, gg.game_type, gg.created_at, (SELECT COUNT(*) FROM game_results gr WHERE gr.game_id = gg.id) AS played_count FROM group_games gg WHERE gg.group_id = ? AND gg.week_number = ? ORDER BY gg.created_at DESC");
    $stmt->execute([$groupId, $week]);
    $games = $stmt->fetchAll();

    echo json_encode([
        'week'     => $week,
        'current'  => $current,
        'previous' => $previous,
        'games'    => $games,
    ]);
    exit;
}

// --- GET WEEK GAMES (liste des jeux de la semaine pour un groupe) ---
if ($action === 'week_games' && $method === 'GET') {
    $userId  = requireAuth();
    $groupId = (int)($_GET['group_id'] ?? 0);
    if (!$groupId) { http_response_code(400); echo json_encode(['message' => 'group_id requis']); exit; }

    $stmt = $pdo->prepare("SELECT 1 FROM group_members WHERE group_id = ? AND user_id = ?");
    $stmt->execute([$groupId, $userId]);
    if (!$stmt->fetch()) { http_response_code(403); echo json_encode(['message' => 'Acces refuse']); exit; }

    $week = getWeekNumber();
    $stmt = $pdo->prepare("SELECT gg.id, gg.game_type, gg.created_at, (SELECT COUNT(*) FROM game_results gr WHERE gr.game_id = gg.id) AS played_count, (SELECT score FROM game_results WHERE game_id = gg.id AND user_id = ?) AS my_score FROM group_games gg WHERE gg.group_id = ? AND gg.week_number = ? ORDER BY gg.created_at DESC");
    $stmt->execute([$userId, $groupId, $week]);
    $games = $stmt->fetchAll();

    echo json_encode(['games' => $games, 'week' => $week]);
    exit;
}

http_response_code(404);
echo json_encode(['message' => 'Action inconnue']);
