<?php

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

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

require_once __DIR__ . '/../includes/supabase.php';
require_once __DIR__ . '/../includes/auth.php';

$token = requireAuth();
$userId = getUserId($token);
$input = getInput();
$action = $input['action'] ?? '';

switch ($action) {
    case 'queue': handleLudoQueue($userId, $input); break;
    case 'status': handleLudoStatus($userId); break;
    case 'move': handleLudoMove($userId, $input); break;
    case 'get': handleLudoGet($userId, $input); break;
    case 'complete': handleLudoComplete($userId, $input); break;
    case 'heartbeat': handleHeartbeat($userId, $input); break;
    case 'leave': handleLudoLeave($userId, $input); break;
    default: jsonError('Invalid action');
}

function handleLudoQueue(string $userId, array $input): void {
    $sdb = supabaseService();

    // Clean old waiting entries for this player
    $sdb->delete('ludo_queue', ['user_id' => 'eq.' . $userId]);

    // Check for ALL waiting opponents (up to 3 — we need at least 1 to start)
    $searchUrl = SUPABASE_REST . '/ludo_queue'
        . '?user_id=neq.' . $userId
        . '&match_id=is.null'
        . '&select=id,user_id'
        . '&limit=3';

    $ch = curl_init($searchUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'apikey: ' . SUPABASE_SERVICE_KEY,
        'Authorization: Bearer ' . SUPABASE_SERVICE_KEY,
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    $result = curl_exec($ch);
    curl_close($ch);
    $opponents = json_decode($result, true);

    if (!empty($opponents) && isset($opponents[0])) {
        // Found opponents — build player list (up to 4 humans, fill rest with bots)
        $humanPlayers = [$opponents[0]['user_id'], $userId];
        if (isset($opponents[1])) $humanPlayers[] = $opponents[1]['user_id'];
        if (isset($opponents[2])) $humanPlayers[] = $opponents[2]['user_id'];

        $players = $humanPlayers;
        $botCount = 4 - count($players);
        for ($i = 1; $i <= $botCount; $i++) { $players[] = 'bot_' . $i; }

        $matchData = [
            'room_code' => strtoupper(substr(bin2hex(random_bytes(3)), 0, 6)),
            'status' => 'in_progress',
            'player_count' => 4,
            'players' => json_encode($players),
            'current_turn' => 0,
            'dice_value' => null,
            'positions' => json_encode([
                ['pos' => [-1,-1,-1,-1]],
                ['pos' => [-1,-1,-1,-1]],
                ['pos' => [-1,-1,-1,-1]],
                ['pos' => [-1,-1,-1,-1]]
            ]),
            'moves' => '[]',
            'winners' => '[]',
            'game_state' => json_encode(['turn_count' => 0]),
            'host_id' => $opponents[0]['user_id']
        ];

        $match = $sdb->insert('ludo_matches', $matchData);
        $matchId = $match[0]['id'] ?? $match['id'] ?? null;

        if ($matchId) {
            // Mark ALL opponents' queue entries with match_id
            foreach ($opponents as $opp) {
                $sdb->update('ludo_queue', ['match_id' => $matchId], ['id' => 'eq.' . $opp['id']]);
            }

            jsonResponse([
                'match_id' => $matchId,
                'player_index' => 1,
                'players' => $players
            ]);
        }
    }

    // No opponent found — add to queue
    $sdb->insert('ludo_queue', ['user_id' => $userId]);
    jsonResponse(['queued' => true]);
}

function handleLudoStatus(string $userId): void {
    $sdb = supabaseService();

    $entry = $sdb->get('ludo_queue', [
        'user_id' => 'eq.' . $userId,
        'select' => 'id,match_id',
        'limit' => 1
    ]);

    if (!empty($entry) && !isset($entry['error']) && !empty($entry[0]['match_id'])) {
        $matchId = $entry[0]['match_id'];
        // Clean queue
        $sdb->delete('ludo_queue', ['user_id' => 'eq.' . $userId]);

        // Get match to find player index
        $matches = $sdb->get('ludo_matches', ['id' => 'eq.' . $matchId, 'select' => 'players', 'limit' => 1]);
        $players = [];
        if (!empty($matches) && !isset($matches['error'])) {
            $players = json_decode($matches[0]['players'] ?? '[]', true);
        }
        $playerIndex = array_search($userId, $players);

        jsonResponse([
            'match_id' => $matchId,
            'player_index' => $playerIndex !== false ? $playerIndex : 0,
            'players' => $players
        ]);
    }

    jsonResponse(['waiting' => true]);
}

function handleLudoMove(string $userId, array $input): void {
    $matchId = $input['match_id'] ?? '';
    if (!$matchId) jsonError('match_id required');

    $sdb = supabaseService();
    $update = [];
    if (isset($input['positions'])) {
        $pos = $input['positions'];
        $update['positions'] = is_string($pos) ? $pos : json_encode($pos);
    }
    if (isset($input['current_turn'])) $update['current_turn'] = intval($input['current_turn']);
    if (isset($input['dice_value'])) $update['dice_value'] = intval($input['dice_value']);
    if (isset($input['game_state'])) {
        $gs = $input['game_state'];
        if (is_string($gs)) $gs = json_decode($gs, true);
        $gs['turn_started_at'] = date('c');
        $gs['last_mover'] = $userId;
        $update['game_state'] = json_encode($gs);
    }
    if (isset($input['winners'])) $update['winners'] = json_encode($input['winners']);
    if (isset($input['status'])) $update['status'] = $input['status'];

    $update['last_activity'] = date('c');

    if (!empty($update)) {
        $sdb->update('ludo_matches', $update, ['id' => 'eq.' . $matchId]);
    }
    jsonResponse(['success' => true]);
}

function handleLudoGet(string $userId, array $input): void {
    $matchId = $input['match_id'] ?? ($_GET['match_id'] ?? '');
    if (!$matchId) jsonError('match_id required');

    $sdb = supabaseService();
    $matches = $sdb->get('ludo_matches', ['id' => 'eq.' . $matchId, 'select' => '*', 'limit' => 1]);

    if (empty($matches) || isset($matches['error'])) jsonError('Not found', 404);

    $match = $matches[0];

    // Server-side turn timeout enforcement (20s)
    if ($match['status'] === 'in_progress') {
        $timeout = supabaseRpc('enforce_turn_timeout', [
            'p_game_key' => 'ludo',
            'p_match_id' => $matchId,
            'p_timeout_seconds' => 20
        ]);
        if (!empty($timeout['timeout'])) {
            $match['_turn_timed_out'] = true;
            $match['_timeout_player'] = $timeout['player_index'] ?? null;
            $match['_replace_with_bot'] = $timeout['replace_with_bot'] ?? false;
            // Re-fetch after timeout update
            $matches = $sdb->get('ludo_matches', ['id' => 'eq.' . $matchId, 'select' => '*', 'limit' => 1]);
            if (!empty($matches) && !isset($matches['error'])) {
                $match = $matches[0];
                $match['_turn_timed_out'] = true;
                $match['_timeout_player'] = $timeout['player_index'] ?? null;
                $match['_replace_with_bot'] = $timeout['replace_with_bot'] ?? false;
            }
        }
    }

    jsonResponse($match);
}

function handleLudoComplete(string $userId, array $input): void {
    $matchId = $input['match_id'] ?? '';
    if (!$matchId) jsonError('match_id required');
    $winners = $input['winners'] ?? [];
    $reason = $input['reason'] ?? 'normal';

    $sdb = supabaseService();

    // Mark match as completed
    $sdb->update('ludo_matches', [
        'status' => 'completed',
        'completed_at' => date('c'),
        'result' => $reason,
        'winners' => json_encode($winners)
    ], ['id' => 'eq.' . $matchId]);

    // Call universal rewards function
    $result = supabaseRpc('complete_match', [
        'p_game_key' => 'ludo',
        'p_match_id' => $matchId,
        'p_winners' => json_encode($winners),
        'p_reason' => $reason
    ]);

    jsonResponse($result ?: ['success' => true]);
}

function handleHeartbeat(string $userId, array $input): void {
    $matchId = $input['match_id'] ?? '';
    if (!$matchId) jsonError('match_id required');

    $result = supabaseRpc('match_heartbeat', [
        'p_game_key' => 'ludo',
        'p_match_id' => $matchId,
        'p_player_id' => $userId
    ]);

    jsonResponse($result ?: ['status' => 'ok']);
}

function handleLudoLeave(string $userId, array $input): void {
    $matchId = $input['match_id'] ?? '';
    if (!$matchId) jsonError('match_id required');
    $playerIndex = $input['player_index'] ?? null;

    $sdb = supabaseService();

    // Get current match state
    $matches = $sdb->get('ludo_matches', ['id' => 'eq.' . $matchId, 'select' => 'players,game_state', 'limit' => 1]);
    if (empty($matches) || isset($matches['error'])) jsonError('Not found');

    $players = json_decode($matches[0]['players'] ?? '[]', true);
    $gameState = json_decode($matches[0]['game_state'] ?? '{}', true);

    // Mark player as bot-replaced in game_state (reversible within 30s)
    $gameState['bot_replaced'] = $gameState['bot_replaced'] ?? [];
    $gameState['bot_replaced'][] = [
        'player_id' => $userId,
        'player_index' => $playerIndex,
        'replaced_at' => date('c'),
        'permanent' => false
    ];

    $sdb->update('ludo_matches', [
        'game_state' => json_encode($gameState),
        'last_activity' => date('c')
    ], ['id' => 'eq.' . $matchId]);

    jsonResponse(['success' => true, 'bot_replaced' => true]);
}

