<?php
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') {
    exit;
}

require_once __DIR__ . '/db.php';

function respond($data, $status = 200) {
    http_response_code($status);
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function loadAiConfig() {
    $fileConfig = [];
    $configPath = __DIR__ . '/ai_config.php';
    if (is_file($configPath)) {
        $loaded = require $configPath;
        if (is_array($loaded)) {
            $fileConfig = $loaded;
        }
    }

    $openAiKey = $fileConfig['openai_api_key'] ?? getenv('OPENAI_API_KEY') ?: '';
    $anthropicKey = $fileConfig['anthropic_api_key'] ?? getenv('ANTHROPIC_API_KEY') ?: '';
    $provider = $fileConfig['provider'] ?? getenv('AI_PROVIDER') ?: '';
    if (!$provider) {
        $provider = $anthropicKey || str_starts_with((string)$openAiKey, 'sk-ant-') ? 'anthropic' : 'openai';
    }

    return [
        'provider' => $provider,
        'openai_api_key' => $openAiKey,
        'openai_base_url' => rtrim($fileConfig['openai_base_url'] ?? getenv('OPENAI_BASE_URL') ?: 'https://api.openai.com/v1', '/'),
        'openai_model' => $fileConfig['openai_model'] ?? getenv('OPENAI_MODEL') ?: 'gpt-4.1-mini',
        'openai_web_tool' => $fileConfig['openai_web_tool'] ?? getenv('OPENAI_WEB_TOOL') ?: 'web_search_preview',
        'openai_require_auth' => array_key_exists('openai_require_auth', $fileConfig) ? (bool)$fileConfig['openai_require_auth'] : true,
        'anthropic_api_key' => $anthropicKey ?: (str_starts_with((string)$openAiKey, 'sk-ant-') ? $openAiKey : ''),
        'anthropic_model' => $fileConfig['anthropic_model'] ?? getenv('ANTHROPIC_MODEL') ?: 'claude-sonnet-4-20250514',
        'ssl_verify' => array_key_exists('ssl_verify', $fileConfig) ? (bool)$fileConfig['ssl_verify'] : true,
        'admin_key' => $fileConfig['admin_key'] ?? getenv('AI_ADMIN_KEY') ?: 'titoue-2026'
    ];
}

function requireAiAdmin($config) {
    $key = $_GET['key'] ?? '';
    if (!$key) {
        $body = json_decode(file_get_contents('php://input'), true);
        $key = is_array($body) ? ($body['key'] ?? '') : '';
    }
    if (!hash_equals($config['admin_key'], (string) $key)) {
        respond(['message' => 'Cle admin invalide'], 403);
    }
}

function jsonBody() {
    $raw = file_get_contents('php://input');
    if (!$raw) return [];
    $data = json_decode($raw, true);
    return is_array($data) ? $data : [];
}

function ensureAiTables($pdo) {
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS ai_daily_news (
            id INT AUTO_INCREMENT PRIMARY KEY,
            news_date DATE NOT NULL,
            locale VARCHAR(20) NOT NULL DEFAULT 'fr-FR',
            topic VARCHAR(120) NOT NULL DEFAULT 'general',
            digest LONGTEXT NOT NULL,
            questions LONGTEXT NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            UNIQUE KEY uq_ai_daily (news_date, locale, topic)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    ");

    $pdo->exec("
        CREATE TABLE IF NOT EXISTS ai_generation_logs (
            id INT AUTO_INCREMENT PRIMARY KEY,
            generation_type VARCHAR(40) NOT NULL,
            prompt LONGTEXT NOT NULL,
            raw_response LONGTEXT NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    ");
}

function ensureQuizQuestionsTableAi($pdo) {
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS quiz_questions (
            id INT AUTO_INCREMENT PRIMARY KEY,
            category VARCHAR(80) NOT NULL,
            question TEXT NOT NULL,
            options LONGTEXT NULL,
            answer TEXT NOT NULL,
            explanation TEXT NULL,
            difficulty VARCHAR(30) DEFAULT 'standard',
            active TINYINT(1) DEFAULT 1,
            source_hash CHAR(64) NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            UNIQUE KEY uq_source_hash (source_hash),
            INDEX idx_category_active (category, active)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    ");
}

function ensureGameQuestionsTableAi($pdo) {
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS game_questions (
            id INT AUTO_INCREMENT PRIMARY KEY,
            game_type ENUM('blitz','memory','imposteur','geo','sondage','juste_prix','timeline','popcorn','alcool_order') NOT NULL,
            question TEXT NOT NULL,
            options TEXT NULL,
            answer TEXT NOT NULL,
            explanation TEXT NULL,
            date_event VARCHAR(80) NULL,
            hints TEXT NULL,
            active TINYINT(1) DEFAULT 1,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            INDEX idx_game_type_active (game_type, active)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    ");
}

function normalizeList($value) {
    if (is_array($value)) {
        return array_values(array_filter(array_map('trim', array_map('strval', $value))));
    }
    if (is_string($value) && trim($value) !== '') {
        return array_values(array_filter(array_map('trim', preg_split('/\r\n|\r|\n|;/', $value))));
    }
    return [];
}

function questionHashAi($q) {
    return hash('sha256', strtolower(trim(($q['category'] ?? '') . '|' . ($q['question'] ?? '') . '|' . ($q['answer'] ?? ''))));
}

function importQuizQuestionsAi($pdo, $questions) {
    ensureQuizQuestionsTableAi($pdo);
    $stmt = $pdo->prepare("
        INSERT INTO quiz_questions (category, question, options, answer, explanation, difficulty, active, source_hash)
        VALUES (:category, :question, :options, :answer, :explanation, :difficulty, :active, :source_hash)
        ON DUPLICATE KEY UPDATE
            options = VALUES(options),
            answer = VALUES(answer),
            explanation = VALUES(explanation),
            difficulty = VALUES(difficulty),
            active = VALUES(active),
            updated_at = CURRENT_TIMESTAMP
    ");
    $count = 0;
    foreach ($questions as $q) {
        if (!is_array($q)) continue;
        $category = trim((string)($q['category'] ?? 'actu'));
        $question = trim((string)($q['question'] ?? ''));
        $answer = trim((string)($q['answer'] ?? ''));
        if ($category === '' || $question === '' || $answer === '') continue;
        $options = normalizeList($q['options'] ?? []);
        $stmt->execute([
            ':category' => $category,
            ':question' => $question,
            ':options' => json_encode($options, JSON_UNESCAPED_UNICODE),
            ':answer' => $answer,
            ':explanation' => trim((string)($q['explanation'] ?? '')),
            ':difficulty' => trim((string)($q['difficulty'] ?? 'standard')) ?: 'standard',
            ':active' => isset($q['active']) ? (int) !!$q['active'] : 1,
            ':source_hash' => questionHashAi(['category' => $category, 'question' => $question, 'answer' => $answer])
        ]);
        $count++;
    }
    return $count;
}

function importGameQuestionsAi($pdo, $questions) {
    ensureGameQuestionsTableAi($pdo);
    $valid = ['memory', 'timeline', 'popcorn', 'geo', 'sondage', 'juste_prix', 'alcool_order'];
    $stmt = $pdo->prepare("
        INSERT INTO game_questions (game_type, question, options, answer, explanation, date_event, hints, active)
        VALUES (:game_type, :question, :options, :answer, :explanation, :date_event, :hints, :active)
    ");
    $count = 0;
    foreach ($questions as $q) {
        if (!is_array($q)) continue;
        $type = trim((string)($q['game_type'] ?? ''));
        $question = trim((string)($q['question'] ?? ''));
        $answer = trim((string)($q['answer'] ?? ''));
        if (!in_array($type, $valid, true) || $question === '' || $answer === '') continue;
        $stmt->execute([
            ':game_type' => $type,
            ':question' => $question,
            ':options' => json_encode(normalizeList($q['options'] ?? []), JSON_UNESCAPED_UNICODE),
            ':answer' => $answer,
            ':explanation' => trim((string)($q['explanation'] ?? '')),
            ':date_event' => trim((string)($q['date_event'] ?? '')),
            ':hints' => json_encode(normalizeList($q['hints'] ?? []), JSON_UNESCAPED_UNICODE),
            ':active' => isset($q['active']) ? (int) !!$q['active'] : 1
        ]);
        $count++;
    }
    return $count;
}

function openAiResponsesPayload($config, $prompt, $useWeb) {
    $payload = [
        'model' => $config['openai_model'],
        'input' => [
            [
                'role' => 'system',
                'content' => 'Tu generes du contenu en francais pour un site de quiz. Reponds uniquement avec un JSON valide, sans markdown.'
            ],
            [
                'role' => 'user',
                'content' => $prompt
            ]
        ],
        'max_output_tokens' => 6000
    ];
    if ($useWeb) {
        $payload['tools'] = [['type' => $config['openai_web_tool']]];
    }
    return $payload;
}

function openAiChatPayload($config, $prompt) {
    return [
        'model' => $config['openai_model'],
        'messages' => [
            [
                'role' => 'system',
                'content' => 'Tu generes du contenu en francais pour un site de quiz. Reponds uniquement avec un JSON valide, sans markdown.'
            ],
            [
                'role' => 'user',
                'content' => $prompt
            ]
        ],
        'max_tokens' => 6000,
        'temperature' => 0.7
    ];
}

function extractOpenAiText($data) {
    if (isset($data['output_text']) && is_string($data['output_text'])) {
        return $data['output_text'];
    }
    if (isset($data['choices'][0]['message']['content']) && is_string($data['choices'][0]['message']['content'])) {
        return trim($data['choices'][0]['message']['content']);
    }
    $parts = [];
    foreach (($data['output'] ?? []) as $out) {
        foreach (($out['content'] ?? []) as $content) {
            if (isset($content['text']) && is_string($content['text'])) {
                $parts[] = $content['text'];
            }
        }
    }
    return trim(implode("\n", $parts));
}

function hasOpenAiKey($config) {
    $key = trim((string)($config['openai_api_key'] ?? ''));
    return $key !== '' && $key !== 'sk-a-remplacer' && $key !== 'TA_CLE_IA_ICI';
}

function callOpenAi($config, $prompt, $useWeb = false) {
    if (($config['openai_require_auth'] ?? true) && !hasOpenAiKey($config)) {
        respond(['message' => 'Cle IA manquante. Remplace TA_CLE_IA_ICI dans api/ai_config.php.'], 500);
    }
    if (!function_exists('curl_init')) {
        respond(['message' => 'Extension PHP cURL manquante sur le serveur.'], 500);
    }

    $baseUrl = rtrim($config['openai_base_url'] ?? 'https://api.openai.com/v1', '/');
    $useResponsesApi = ($baseUrl === 'https://api.openai.com/v1' && $useWeb);
    $endpoint = $useResponsesApi ? $baseUrl . '/responses' : $baseUrl . '/chat/completions';
    $payload = $useResponsesApi
        ? openAiResponsesPayload($config, $prompt, $useWeb)
        : openAiChatPayload($config, $prompt);

    $headers = ['Content-Type: application/json'];
    if (($config['openai_require_auth'] ?? true) && hasOpenAiKey($config)) {
        $headers[] = 'Authorization: Bearer ' . $config['openai_api_key'];
    }

    $ch = curl_init($endpoint);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
        CURLOPT_SSL_VERIFYPEER => (bool)($config['ssl_verify'] ?? true),
        CURLOPT_SSL_VERIFYHOST => (bool)($config['ssl_verify'] ?? true) ? 2 : 0,
        CURLOPT_TIMEOUT => 90
    ]);
    $raw = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    $error = curl_error($ch);
    curl_close($ch);

    if ($raw === false || $status < 200 || $status >= 300) {
        respond(['message' => 'Erreur IA', 'status' => $status, 'endpoint' => $endpoint, 'details' => $error ?: $raw], 502);
    }

    $data = json_decode($raw, true);
    if (!is_array($data)) {
        respond(['message' => 'Reponse IA illisible', 'raw' => $raw], 502);
    }
    return [$raw, extractOpenAiText($data)];
}

function anthropicPayload($config, $prompt) {
    return [
        'model' => $config['anthropic_model'],
        'max_tokens' => 6000,
        'system' => 'Tu generes du contenu en francais pour un site de quiz. Reponds uniquement avec un JSON valide, sans markdown.',
        'messages' => [
            [
                'role' => 'user',
                'content' => $prompt
            ]
        ]
    ];
}

function extractAnthropicText($data) {
    $parts = [];
    foreach (($data['content'] ?? []) as $content) {
        if (($content['type'] ?? '') === 'text' && isset($content['text'])) {
            $parts[] = $content['text'];
        }
    }
    return trim(implode("\n", $parts));
}

function callAnthropic($config, $prompt) {
    if (!$config['anthropic_api_key'] || $config['anthropic_api_key'] === 'sk-ant-a-remplacer') {
        respond(['message' => 'Cle Anthropic manquante. Ajoute anthropic_api_key dans api/ai_config.php.'], 500);
    }
    if (!function_exists('curl_init')) {
        respond(['message' => 'Extension PHP cURL manquante sur le serveur.'], 500);
    }

    $ch = curl_init('https://api.anthropic.com/v1/messages');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'x-api-key: ' . $config['anthropic_api_key'],
            'anthropic-version: 2023-06-01',
            'Content-Type: application/json'
        ],
        CURLOPT_POSTFIELDS => json_encode(anthropicPayload($config, $prompt), JSON_UNESCAPED_UNICODE),
        CURLOPT_TIMEOUT => 90
    ]);
    $raw = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    $error = curl_error($ch);
    curl_close($ch);

    if ($raw === false || $status < 200 || $status >= 300) {
        respond(['message' => 'Erreur Anthropic', 'status' => $status, 'details' => $error ?: $raw], 502);
    }

    $data = json_decode($raw, true);
    if (!is_array($data)) {
        respond(['message' => 'Reponse Anthropic illisible', 'raw' => $raw], 502);
    }
    return [$raw, extractAnthropicText($data)];
}

function callAiProvider($config, $prompt, $useWeb = false) {
    if (($config['provider'] ?? 'openai') === 'anthropic') {
        return callAnthropic($config, $prompt);
    }
    return callOpenAi($config, $prompt, $useWeb);
}

function decodeJsonAnswer($text) {
    $text = trim($text);
    $data = json_decode($text, true);
    if (is_array($data)) return $data;

    $start = strpos($text, '{');
    $end = strrpos($text, '}');
    if ($start !== false && $end !== false && $end > $start) {
        $slice = substr($text, $start, $end - $start + 1);
        $data = json_decode($slice, true);
        if (is_array($data)) return $data;
    }
    respond(['message' => 'JSON IA invalide', 'raw_text' => $text], 502);
}

function dailyPrompt($date, $topic, $instructions = '') {
    $customInstructions = trim((string)$instructions);
    $instructionBlock = $customInstructions !== ''
        ? "Consignes editoriales donnees par l'admin: {$customInstructions}\n"
        : "";
    return "Genere un resume clair et attractif de l'actu du jour pour l'accueil d'un site appele Titoue Quiz.\n"
        . "Date: {$date}. Theme: {$topic}.\n"
        . $instructionBlock
        . "Cherche ou utilise des informations actuelles si l'outil web est disponible. Evite les rumeurs et les details anxiogenes inutiles. Le ton doit etre clair, vivant, fiable, adapte a des jeunes/adultes curieux.\n"
        . "Format JSON exact:\n"
        . "{"
        . "\"title\":\"Actu du jour\","
        . "\"date\":\"{$date}\","
        . "\"intro\":\"Une phrase d'introduction courte\","
        . "\"summary\":[\"5 a 7 phrases courtes\"],"
        . "\"items\":[{\"title\":\"...\",\"what_happened\":\"...\",\"why_it_matters\":\"...\",\"source_hint\":\"media ou organisme a verifier\"}],"
        . "\"closing\":\"Une phrase finale sympa qui donne envie de lancer un quiz\""
        . "}\n"
        . "Ne genere pas de questions dans cette action. Genere 4 a 6 items maximum.";
}

function quizPrompt($category, $count, $difficulty, $theme) {
    return "Genere {$count} questions de quiz en francais pour la categorie '{$category}'. "
        . "Difficulte: {$difficulty}. Theme precis si fourni: {$theme}. "
        . "Chaque question doit avoir 4 options plausibles, une seule bonne reponse qui correspond exactement a une option, et une explication courte. "
        . "Format JSON exact: {\"questions\":[{\"category\":\"{$category}\",\"question\":\"...\",\"options\":[\"...\",\"...\",\"...\",\"...\"],\"answer\":\"...\",\"explanation\":\"...\",\"difficulty\":\"{$difficulty}\",\"active\":1}]}";
}

function gamePrompt($gameType, $count, $theme) {
    $rules = [
        'memory' => "question = evenement, answer = date ou annee a associer, date_event = precision affichee.",
        'timeline' => "question = evenement a replacer, answer = annee de tri, date_event = date exacte ou annee, options vides.",
        'popcorn' => "question = devinette culture moderne, options = 4 titres/personnes, answer = bonne option, hints = 3 indices progressifs.",
        'geo' => "question = lieu a deviner, answer = lieu exact, hints = 4 indices progressifs.",
        'sondage' => "question = estimation en pourcentage, answer = nombre, explication = contexte de l'ecart.",
        'juste_prix' => "question = estimation numerique avec unite, answer = nombre, explication = contexte.",
        'alcool_order' => "question = nom d'une boisson, answer = degre numerique pour trier, date_event = degre affiche avec % vol., options vides."
    ];
    $rule = $rules[$gameType] ?? $rules['popcorn'];
    return "Genere {$count} questions pour le mini-jeu '{$gameType}' en francais. {$rule} "
        . "Theme precis si fourni: {$theme}. "
        . "Format JSON exact: {\"questions\":[{\"game_type\":\"{$gameType}\",\"question\":\"...\",\"options\":[],\"answer\":\"...\",\"explanation\":\"...\",\"date_event\":\"\",\"hints\":[],\"active\":1}]}";
}

$config = loadAiConfig();
$action = $_GET['action'] ?? 'status';
ensureAiTables($pdo);

if ($action === 'status') {
    $last = $pdo->query("SELECT news_date, topic, updated_at FROM ai_daily_news ORDER BY updated_at DESC LIMIT 1")->fetch();
    $openAiConfigured = !($config['openai_require_auth'] ?? true)
        || hasOpenAiKey($config);
    respond([
        'configured' => (($config['provider'] ?? 'openai') === 'anthropic')
            ? ((bool) $config['anthropic_api_key'] && $config['anthropic_api_key'] !== 'sk-ant-a-remplacer')
            : $openAiConfigured,
        'provider' => $config['provider'],
        'model' => (($config['provider'] ?? 'openai') === 'anthropic') ? $config['anthropic_model'] : $config['openai_model'],
        'base_url' => $config['openai_base_url'] ?? null,
        'last_daily' => $last ?: null
    ]);
}

if ($action === 'daily_cached') {
    $date = $_GET['date'] ?? date('Y-m-d');
    $topic = $_GET['topic'] ?? 'general';
    $stmt = $pdo->prepare("SELECT * FROM ai_daily_news WHERE news_date = ? AND topic = ? LIMIT 1");
    $stmt->execute([$date, $topic]);
    $row = $stmt->fetch();
    if (!$row) respond(['message' => 'Aucune actu en cache'], 404);
    respond([
        'news_date' => $row['news_date'],
        'topic' => $row['topic'],
        'digest' => json_decode($row['digest'], true),
        'questions' => json_decode($row['questions'], true),
        'updated_at' => $row['updated_at']
    ]);
}

requireAiAdmin($config);
$body = jsonBody();

if ($action === 'test_ai') {
    [$raw, $text] = callAiProvider($config, 'Reponds uniquement avec ce JSON exact: {"ok":true,"message":"IA connectee"}', false);
    $decoded = decodeJsonAnswer($text);
    respond([
        'message' => 'Test IA réussi',
        'provider' => $config['provider'],
        'model' => (($config['provider'] ?? 'openai') === 'anthropic') ? $config['anthropic_model'] : $config['openai_model'],
        'base_url' => $config['openai_base_url'] ?? null,
        'answer' => $decoded
    ]);
}

if ($action === 'generate_daily') {
    $date = $body['date'] ?? $_GET['date'] ?? date('Y-m-d');
    $topic = trim((string)($body['topic'] ?? $_GET['topic'] ?? 'general')) ?: 'general';
    $instructions = trim((string)($body['instructions'] ?? $_GET['instructions'] ?? ''));
    $useWeb = !empty($body['use_web']) || !empty($_GET['use_web']);
    $prompt = dailyPrompt($date, $topic, $instructions);
    [$raw, $text] = callAiProvider($config, $prompt, $useWeb);
    $data = decodeJsonAnswer($text);

    $quizQuestions = $data['quiz_questions'] ?? [];
    $gameQuestions = $data['game_questions'] ?? [];
    $digest = $data;
    unset($digest['quiz_questions'], $digest['game_questions']);

    $stmt = $pdo->prepare("
        INSERT INTO ai_daily_news (news_date, locale, topic, digest, questions)
        VALUES (:news_date, 'fr-FR', :topic, :digest, :questions)
        ON DUPLICATE KEY UPDATE digest = VALUES(digest), questions = VALUES(questions), updated_at = CURRENT_TIMESTAMP
    ");
    $stmt->execute([
        ':news_date' => $date,
        ':topic' => $topic,
        ':digest' => json_encode($digest, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
        ':questions' => json_encode(['quiz' => $quizQuestions, 'games' => $gameQuestions], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
    ]);
    $pdo->prepare("INSERT INTO ai_generation_logs (generation_type, prompt, raw_response) VALUES ('daily', ?, ?)")->execute([$prompt, $raw]);

    $importedQuiz = (!empty($body['import_quiz']) || !empty($_GET['import_quiz'])) ? importQuizQuestionsAi($pdo, $quizQuestions) : 0;
    $importedGames = (!empty($body['import_games']) || !empty($_GET['import_games'])) ? importGameQuestionsAi($pdo, $gameQuestions) : 0;

    respond(['digest' => $digest, 'quiz_questions' => $quizQuestions, 'game_questions' => $gameQuestions, 'imported_quiz' => $importedQuiz, 'imported_games' => $importedGames]);
}

if ($action === 'generate_quiz') {
    $category = trim((string)($body['category'] ?? 'science')) ?: 'science';
    $count = max(1, min(50, (int)($body['count'] ?? 10)));
    $difficulty = trim((string)($body['difficulty'] ?? 'standard')) ?: 'standard';
    $theme = trim((string)($body['theme'] ?? ''));
    [$raw, $text] = callAiProvider($config, quizPrompt($category, $count, $difficulty, $theme), !empty($body['use_web']));
    $data = decodeJsonAnswer($text);
    $questions = $data['questions'] ?? [];
    $pdo->prepare("INSERT INTO ai_generation_logs (generation_type, prompt, raw_response) VALUES ('quiz', ?, ?)")->execute([quizPrompt($category, $count, $difficulty, $theme), $raw]);
    $imported = !empty($body['import_questions']) ? importQuizQuestionsAi($pdo, $questions) : 0;
    respond(['questions' => $questions, 'imported' => $imported]);
}

if ($action === 'generate_game') {
    $gameType = trim((string)($body['game_type'] ?? 'popcorn')) ?: 'popcorn';
    $count = max(1, min(50, (int)($body['count'] ?? 10)));
    $theme = trim((string)($body['theme'] ?? ''));
    [$raw, $text] = callAiProvider($config, gamePrompt($gameType, $count, $theme), !empty($body['use_web']));
    $data = decodeJsonAnswer($text);
    $questions = $data['questions'] ?? [];
    $pdo->prepare("INSERT INTO ai_generation_logs (generation_type, prompt, raw_response) VALUES ('game', ?, ?)")->execute([gamePrompt($gameType, $count, $theme), $raw]);
    $imported = !empty($body['import_questions']) ? importGameQuestionsAi($pdo, $questions) : 0;
    respond(['questions' => $questions, 'imported' => $imported]);
}

respond(['message' => 'Action inconnue'], 404);
