<?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'] ?? '';
$db = supabase($token);

switch ($action) {
    case 'queue':
        handleQueue($db, $userId, $input);
        break;
    case 'dequeue':
        handleDequeue($db, $userId, $input);
        break;
    case 'status':
        handleStatus($db, $userId, $input);
        break;
    default:
        jsonError('Invalid action');
}

function handleQueue($db, string $userId, array $input): void {
    $gameKey = $input['game_key'] ?? 'chess';
    $timeControl = $input['time_control'] ?? 'rapid_10_0';

    // Anti-abuse: check if player can queue (cooldown after repeated abandons)
    $canQueue = supabaseRpc('can_player_queue', ['p_player_id' => $userId]);
    if (is_array($canQueue) && isset($canQueue['allowed']) && !$canQueue['allowed']) {
        jsonResponse(['error' => 'cooldown', 'seconds_remaining' => $canQueue['seconds_remaining'] ?? 60]);
        return;
    }

    // Use service key to bypass RLS for matchmaking operations
    $sdb = supabaseService();

    // Get player rating
    $profiles = $sdb->get('profiles', ['id' => 'eq.' . $userId, 'select' => 'elo_rapid,elo_blitz,elo_bullet', 'limit' => 1]);
    $profile = is_array($profiles) && !empty($profiles) ? $profiles[0] : [];
    $rating = $profile['elo_rapid'] ?? $profile['elo_blitz'] ?? 1200;

    // Check if already in queue
    $existing = $sdb->get('matchmaking_queue', [
        'player_id' => 'eq.' . $userId,
        'status' => 'eq.waiting',
        'select' => 'id'
    ]);
    if (!empty($existing) && !isset($existing['error'])) {
        // Already waiting — just check for opponent again
    } else {
        // Insert into queue first
        $sdb->insert('matchmaking_queue', [
            'player_id' => $userId,
            'game_key' => $gameKey,
            'time_control' => $timeControl,
            'rating' => $rating,
            'status' => 'waiting'
        ]);
    }

    // Get block list for this player (both directions)
    $blockedIds = [];
    $blocks = $sdb->get('player_blocks', [
        'or' => "(player_id.eq.{$userId},blocked_id.eq.{$userId})",
        'type' => 'eq.block',
        'select' => 'player_id,blocked_id'
    ]);
    if (is_array($blocks) && !isset($blocks['error'])) {
        foreach ($blocks as $b) {
            $blockedIds[] = ($b['player_id'] === $userId) ? $b['blocked_id'] : $b['player_id'];
        }
    }

    // Search for available opponent (service key bypasses RLS — can see ALL waiting players)
    $excludeIds = array_merge([$userId], $blockedIds);
    $searchUrl = SUPABASE_REST . '/matchmaking_queue'
        . '?game_key=eq.' . urlencode($gameKey)
        . '&time_control=eq.' . urlencode($timeControl)
        . '&status=eq.waiting'
        . '&player_id=not.in.(' . implode(',', $excludeIds) . ')'
        . '&select=id,player_id,rating'
        . '&order=queued_at.asc'
        . '&limit=1';

    $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);
    $searchResult = curl_exec($ch);
    curl_close($ch);
    $opponents = json_decode($searchResult, true);

    if (!empty($opponents) && !isset($opponents['error']) && isset($opponents[0])) {
        $opponent = $opponents[0];

        // Randomly assign colors
        $isWhite = rand(0, 1) === 0;
        $whiteId = $isWhite ? $userId : $opponent['player_id'];
        $blackId = $isWhite ? $opponent['player_id'] : $userId;

        // Create match
        $initialTime = 600000; // default 10 min
        if (strpos($timeControl, 'bullet') !== false) $initialTime = 60000;
        elseif (strpos($timeControl, 'blitz') !== false) $initialTime = 300000;
        elseif (strpos($timeControl, 'classical') !== false) $initialTime = 3600000;

        $matchData = [
            'game_key' => $gameKey,
            'match_type' => 'rated',
            'white_player_id' => $whiteId,
            'black_player_id' => $blackId,
            'status' => 'in_progress',
            'time_control' => $timeControl,
            'initial_time_ms' => $initialTime,
            'white_time_remaining_ms' => $initialTime,
            'black_time_remaining_ms' => $initialTime,
            'current_fen' => 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
            'moves' => '[]',
            'move_count' => 0,
            'game_state' => '{}',
            'is_rated' => true,
            'started_at' => date('c')
        ];

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

        if ($matchId) {
            // Mark OPPONENT as matched
            $sdb->update('matchmaking_queue', [
                'status' => 'matched',
                'matched_with' => $userId,
                'match_id' => $matchId
            ], ['id' => 'eq.' . $opponent['id']]);

            // Remove self from queue
            $sdb->delete('matchmaking_queue', [
                'player_id' => 'eq.' . $userId,
                'status' => 'eq.waiting'
            ]);

            $myColor = $isWhite ? 'w' : 'b';
            jsonResponse(['match_id' => $matchId, 'color' => $myColor, 'opponent_id' => $opponent['player_id']]);
        }
    }

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


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

    $entry = $sdb->get('matchmaking_queue', [
        'player_id' => 'eq.' . $userId,
        'status' => 'eq.matched',
        'select' => 'match_id,matched_with',
        'limit' => 1
    ]);

    if (!empty($entry) && !isset($entry['error']) && isset($entry[0]['match_id'])) {
        // Found match! Get match details to know our color
        $matchId = $entry[0]['match_id'];
        $match = $sdb->get('matches', ['id' => 'eq.' . $matchId, 'select' => 'white_player_id,black_player_id', 'limit' => 1]);
        $color = 'b';
        if (!empty($match) && !isset($match['error'])) {
            $color = ($match[0]['white_player_id'] === $userId) ? 'w' : 'b';
        }

        // Clean up queue
        $sdb->delete('matchmaking_queue', ['player_id' => 'eq.' . $userId]);

        jsonResponse(['match_id' => $matchId, 'color' => $color]);
    }

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

function handleDequeue($db, string $userId, array $input): void {
    $sdb = supabaseService();
    $sdb->delete('matchmaking_queue', [
        'player_id' => 'eq.' . $userId,
        'status' => 'eq.waiting'
    ]);
    jsonResponse(['success' => true]);
}
