<?php
require_once __DIR__ . '/../config/database.php';

header('Content-Type: application/json');

if (!check_feature_flag('matchmaking_enabled')) {
    http_response_code(403);
    echo json_encode(['error' => 'feature_disabled', 'message' => 'البحث عن مباريات معطل حالياً']);
    exit;
}

$token = get_auth_token();

if (!$token) {
    http_response_code(401);
    echo json_encode(['error' => 'unauthorized']);
    exit;
}

/**
 * Helper: query Supabase REST API with the service role key (bypasses RLS).
 */
function supabase_service(string $method, string $endpoint, array $data = []): array {
    return supabase_rest($method, $endpoint, $data, SUPABASE_SERVICE_KEY);
}

/**
 * Get the appropriate ELO column name for a given time_control enum.
 */
function elo_column_for_time_control(string $timeControl): string {
    if (str_starts_with($timeControl, 'bullet')) {
        return 'elo_bullet';
    }
    if (str_starts_with($timeControl, 'blitz')) {
        return 'elo_blitz';
    }
    return 'elo_rapid';
}

// Authenticate the user
$userRes = supabase_auth('user', [], $token, 'GET');
$userId = $userRes['data']['id'] ?? null;

if (!$userId) {
    http_response_code(401);
    echo json_encode(['error' => 'invalid token']);
    exit;
}

$method = $_SERVER['REQUEST_METHOD'];

if ($method !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => 'method not allowed']);
    exit;
}

$input = json_decode(file_get_contents('php://input'), true);
$action = $input['action'] ?? '';

switch ($action) {

    // ─── JOIN QUEUE ─────────────────────────────────────────────────────────────
    case 'join':
        $timeControl = $input['time_control'] ?? '';
        $isRated = (bool)($input['is_rated'] ?? true);

        if (!$timeControl) {
            http_response_code(400);
            echo json_encode(['error' => 'time_control is required']);
            exit;
        }

        // Check if player already has a waiting entry
        $existing = supabase_service('GET', "matchmaking_queue?player_id=eq.{$userId}&status=eq.waiting&select=id,status");
        if (!empty($existing['data'])) {
            http_response_code(409);
            echo json_encode(['error' => 'already_in_queue', 'queue_id' => $existing['data'][0]['id']]);
            exit;
        }

        // Get player's rating for this time control
        $eloCol = elo_column_for_time_control($timeControl);
        $profileRes = supabase_service('GET', "players?id=eq.{$userId}&select={$eloCol}");
        $playerRating = $profileRes['data'][0][$eloCol] ?? 1200;

        $ratingRangeMin = $playerRating - 200;
        $ratingRangeMax = $playerRating + 200;

        // Look for a compatible waiting opponent
        $opponents = supabase_service('GET',
            "matchmaking_queue?status=eq.waiting"
            . "&time_control=eq.{$timeControl}"
            . "&player_id=neq.{$userId}"
            . "&rating=gte.{$ratingRangeMin}"
            . "&rating=lte.{$ratingRangeMax}"
            . "&select=id,player_id,rating"
            . "&order=queued_at.asc"
            . "&limit=1"
        );

        if (!empty($opponents['data'])) {
            // Found an opponent - create a match
            $opponent = $opponents['data'][0];

            // Randomly assign white/black
            $whitePlayerId = random_int(0, 1) === 0 ? $userId : $opponent['player_id'];
            $blackPlayerId = $whitePlayerId === $userId ? $opponent['player_id'] : $userId;

            // Determine initial time from time_control enum
            $timeMs = match($timeControl) {
                'bullet_1_0' => 60000,
                'bullet_1_1' => 60000,
                'bullet_2_1' => 120000,
                'blitz_3_0' => 180000,
                'blitz_3_2' => 180000,
                'blitz_5_0' => 300000,
                'blitz_5_3' => 300000,
                'rapid_10_0' => 600000,
                'rapid_10_5' => 600000,
                'rapid_15_10' => 900000,
                'rapid_30_0' => 1800000,
                default => 600000,
            };
            $incrementMs = match($timeControl) {
                'bullet_1_1' => 1000,
                'bullet_2_1' => 1000,
                'blitz_3_2' => 2000,
                'blitz_5_3' => 3000,
                'rapid_10_5' => 5000,
                'rapid_15_10' => 10000,
                default => 0,
            };

            // Create the match
            $matchData = [
                'game_key' => 'chess',
                'white_player_id' => $whitePlayerId,
                'black_player_id' => $blackPlayerId,
                'match_type' => 'human',
                'status' => 'ready',
                'time_control' => $timeControl,
                'initial_time_ms' => $timeMs,
                'increment_ms' => $incrementMs,
                'white_time_remaining_ms' => $timeMs,
                'black_time_remaining_ms' => $timeMs,
                'starting_fen' => 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
                'current_fen' => 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
                'moves' => json_encode([]),
                'move_count' => 0,
                'is_rated' => $isRated,
            ];

            $matchRes = supabase_service('POST', 'matches', $matchData);

            if ($matchRes['status'] < 200 || $matchRes['status'] >= 300 || empty($matchRes['data'])) {
                http_response_code(500);
                echo json_encode(['error' => 'failed to create match']);
                exit;
            }

            $matchId = $matchRes['data'][0]['id'];

            // Update the opponent's queue entry
            supabase_service('PATCH', "matchmaking_queue?id=eq.{$opponent['id']}", [
                'status' => 'matched',
                'matched_with' => $userId,
                'match_id' => $matchId,
            ]);

            // Insert our own queue entry as already matched
            $queueEntry = [
                'player_id' => $userId,
                'game_key' => 'chess',
                'time_control' => $timeControl,
                'rating' => $playerRating,
                'rating_range_min' => $ratingRangeMin,
                'rating_range_max' => $ratingRangeMax,
                'is_rated' => $isRated,
                'status' => 'matched',
                'matched_with' => $opponent['player_id'],
                'match_id' => $matchId,
            ];

            supabase_service('POST', 'matchmaking_queue', $queueEntry);

            // Notify both players about the match
            $playerProfileRes = supabase_service('GET', "players?id=eq.{$userId}&select=display_name,username");
            $opponentProfileRes = supabase_service('GET', "players?id=eq.{$opponent['player_id']}&select=display_name,username");
            $playerName = $playerProfileRes['data'][0]['display_name'] ?? $playerProfileRes['data'][0]['username'] ?? 'لاعب';
            $opponentName = $opponentProfileRes['data'][0]['display_name'] ?? $opponentProfileRes['data'][0]['username'] ?? 'لاعب';

            supabase_service('POST', 'notifications', [
                'user_id' => $opponent['player_id'],
                'type' => 'match_found',
                'title' => 'تم إيجاد مباراة',
                'title_ar' => 'تم إيجاد مباراة',
                'body' => "مباراة جديدة ضد {$playerName}",
                'body_ar' => "مباراة جديدة ضد {$playerName}",
                'data' => json_encode(['match_id' => $matchId, 'opponent_id' => $userId]),
            ]);
            supabase_service('POST', 'notifications', [
                'user_id' => $userId,
                'type' => 'match_found',
                'title' => 'تم إيجاد مباراة',
                'title_ar' => 'تم إيجاد مباراة',
                'body' => "مباراة جديدة ضد {$opponentName}",
                'body_ar' => "مباراة جديدة ضد {$opponentName}",
                'data' => json_encode(['match_id' => $matchId, 'opponent_id' => $opponent['player_id']]),
            ]);

            echo json_encode([
                'status' => 'matched',
                'match_id' => $matchId,
                'opponent_id' => $opponent['player_id'],
                'color' => $whitePlayerId === $userId ? 'white' : 'black',
            ]);

        } else {
            // No opponent found - insert into queue as waiting
            $queueEntry = [
                'player_id' => $userId,
                'game_key' => 'chess',
                'time_control' => $timeControl,
                'rating' => $playerRating,
                'rating_range_min' => $ratingRangeMin,
                'rating_range_max' => $ratingRangeMax,
                'is_rated' => $isRated,
                'status' => 'waiting',
            ];

            $insertRes = supabase_service('POST', 'matchmaking_queue', $queueEntry);

            if ($insertRes['status'] >= 200 && $insertRes['status'] < 300 && !empty($insertRes['data'])) {
                echo json_encode([
                    'status' => 'waiting',
                    'queue_id' => $insertRes['data'][0]['id'],
                    'rating' => $playerRating,
                ]);
            } else {
                http_response_code(500);
                echo json_encode(['error' => 'failed to join queue']);
            }
        }
        break;

    // ─── LEAVE QUEUE ────────────────────────────────────────────────────────────
    case 'leave':
        $res = supabase_service('PATCH', "matchmaking_queue?player_id=eq.{$userId}&status=eq.waiting", [
            'status' => 'cancelled',
        ]);

        if ($res['status'] >= 200 && $res['status'] < 300) {
            echo json_encode(['status' => 'cancelled']);
        } else {
            http_response_code(500);
            echo json_encode(['error' => 'failed to leave queue']);
        }
        break;

    // ─── CHECK STATUS ───────────────────────────────────────────────────────────
    case 'status':
        $res = supabase_service('GET',
            "matchmaking_queue?player_id=eq.{$userId}"
            . "&status=in.(waiting,matched)"
            . "&select=id,status,time_control,rating,matched_with,match_id,queued_at"
            . "&order=queued_at.desc"
            . "&limit=1"
        );

        if (!empty($res['data'])) {
            $entry = $res['data'][0];
            $response = [
                'status' => $entry['status'],
                'queue_id' => $entry['id'],
                'time_control' => $entry['time_control'],
                'rating' => $entry['rating'],
                'queued_at' => $entry['queued_at'],
            ];

            if ($entry['status'] === 'matched') {
                $response['match_id'] = $entry['match_id'];
                $response['opponent_id'] = $entry['matched_with'];
            }

            echo json_encode($response);
        } else {
            echo json_encode(['status' => 'idle']);
        }
        break;

    default:
        http_response_code(400);
        echo json_encode(['error' => 'invalid action']);
}
