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

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

$token = get_auth_token();

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

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => 'method_not_allowed']);
    exit;
}

// Authenticate 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;
}

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

if (!$matchId) {
    http_response_code(400);
    echo json_encode(['error' => 'match_id_required']);
    exit;
}

// Fetch the match and validate player membership
$matchRes = supabase_rest('GET', "matches?id=eq.{$matchId}&select=*", [], $token);

if (empty($matchRes['data'])) {
    http_response_code(404);
    echo json_encode(['error' => 'match_not_found']);
    exit;
}

$match = $matchRes['data'][0];

$isWhite = ($match['white_player_id'] === $userId);
$isBlack = ($match['black_player_id'] === $userId);

if (!$isWhite && !$isBlack) {
    http_response_code(403);
    echo json_encode(['error' => 'not_in_match']);
    exit;
}

$gameState = is_string($match['game_state']) ? json_decode($match['game_state'], true) : ($match['game_state'] ?? []);
$moves = is_string($match['moves']) ? json_decode($match['moves'], true) : ($match['moves'] ?? []);

switch ($action) {
    case 'ready':
        if ($match['status'] !== 'ready') {
            http_response_code(400);
            echo json_encode(['error' => 'match_not_in_ready_state']);
            break;
        }

        if ($isWhite) {
            $gameState['white_ready'] = true;
        } else {
            $gameState['black_ready'] = true;
        }

        $update = ['game_state' => json_encode($gameState)];

        // If both players are now ready, start the match
        if (!empty($gameState['white_ready']) && !empty($gameState['black_ready'])) {
            $update['status'] = 'in_progress';
            $update['started_at'] = date('c');
        }

        $res = supabase_rest('PATCH', "matches?id=eq.{$matchId}", $update, $token);

        if ($res['status'] >= 200 && $res['status'] < 300) {
            $started = isset($update['status']) && $update['status'] === 'in_progress';
            echo json_encode(['ok' => true, 'started' => $started]);
        } else {
            http_response_code(500);
            echo json_encode(['error' => 'update_failed']);
        }
        break;

    case 'move':
        if ($match['status'] !== 'in_progress') {
            http_response_code(400);
            echo json_encode(['error' => 'match_not_in_progress']);
            break;
        }

        $moveSan = $input['move'] ?? '';
        $fen = $input['fen'] ?? '';
        $clockRemainingMs = $input['clock_remaining_ms'] ?? null;

        if (!$moveSan || !$fen) {
            http_response_code(400);
            echo json_encode(['error' => 'move_and_fen_required']);
            break;
        }

        // Determine whose turn it is from current FEN
        $fenParts = explode(' ', $match['current_fen']);
        $turnColor = $fenParts[1] ?? 'w'; // 'w' or 'b'

        if ($turnColor === 'w' && !$isWhite) {
            http_response_code(400);
            echo json_encode(['error' => 'not_your_turn']);
            break;
        }
        if ($turnColor === 'b' && !$isBlack) {
            http_response_code(400);
            echo json_encode(['error' => 'not_your_turn']);
            break;
        }

        // Append the move
        $moves[] = [
            'san' => $moveSan,
            'fen' => $fen,
            'at' => date('c'),
        ];

        $gameState['last_move_at'] = date('c');

        $update = [
            'current_fen' => $fen,
            'moves' => json_encode($moves),
            'move_count' => count($moves),
            'game_state' => json_encode($gameState),
        ];

        if ($isWhite && $clockRemainingMs !== null) {
            $update['white_time_remaining_ms'] = (int) $clockRemainingMs;
        } elseif ($isBlack && $clockRemainingMs !== null) {
            $update['black_time_remaining_ms'] = (int) $clockRemainingMs;
        }

        $res = supabase_rest('PATCH', "matches?id=eq.{$matchId}", $update, $token);

        if ($res['status'] >= 200 && $res['status'] < 300) {
            echo json_encode(['ok' => true, 'move_count' => count($moves)]);
        } else {
            http_response_code(500);
            echo json_encode(['error' => 'update_failed']);
        }
        break;

    case 'resign':
        if ($match['status'] !== 'in_progress') {
            http_response_code(400);
            echo json_encode(['error' => 'match_not_in_progress']);
            break;
        }

        $result = $isWhite ? 'black_wins' : 'white_wins';

        $update = [
            'status' => 'completed',
            'result' => $isWhite ? 'white_resign' : 'black_resign',
            'completed_at' => date('c'),
        ];

        $res = supabase_rest('PATCH', "matches?id=eq.{$matchId}", $update, $token);

        if ($res['status'] >= 200 && $res['status'] < 300) {
            echo json_encode(['ok' => true, 'result' => $update['result']]);
        } else {
            http_response_code(500);
            echo json_encode(['error' => 'update_failed']);
        }
        break;

    case 'draw_offer':
        if ($match['status'] !== 'in_progress') {
            http_response_code(400);
            echo json_encode(['error' => 'match_not_in_progress']);
            break;
        }

        $gameState['draw_offered_by'] = $userId;

        $update = ['game_state' => json_encode($gameState)];
        $res = supabase_rest('PATCH', "matches?id=eq.{$matchId}", $update, $token);

        if ($res['status'] >= 200 && $res['status'] < 300) {
            echo json_encode(['ok' => true, 'draw_offered_by' => $userId]);
        } else {
            http_response_code(500);
            echo json_encode(['error' => 'update_failed']);
        }
        break;

    case 'draw_accept':
        if ($match['status'] !== 'in_progress') {
            http_response_code(400);
            echo json_encode(['error' => 'match_not_in_progress']);
            break;
        }

        $offeredBy = $gameState['draw_offered_by'] ?? null;

        if (!$offeredBy) {
            http_response_code(400);
            echo json_encode(['error' => 'no_draw_offer_pending']);
            break;
        }

        // The accepting player must be the one who did NOT offer
        if ($offeredBy === $userId) {
            http_response_code(400);
            echo json_encode(['error' => 'cannot_accept_own_draw_offer']);
            break;
        }

        unset($gameState['draw_offered_by']);

        $update = [
            'status' => 'completed',
            'result' => 'mutual_draw',
            'completed_at' => date('c'),
            'game_state' => json_encode($gameState),
        ];

        $res = supabase_rest('PATCH', "matches?id=eq.{$matchId}", $update, $token);

        if ($res['status'] >= 200 && $res['status'] < 300) {
            echo json_encode(['ok' => true, 'result' => 'mutual_draw']);
        } else {
            http_response_code(500);
            echo json_encode(['error' => 'update_failed']);
        }
        break;

    case 'draw_decline':
        if ($match['status'] !== 'in_progress') {
            http_response_code(400);
            echo json_encode(['error' => 'match_not_in_progress']);
            break;
        }

        $offeredBy = $gameState['draw_offered_by'] ?? null;

        if (!$offeredBy) {
            http_response_code(400);
            echo json_encode(['error' => 'no_draw_offer_pending']);
            break;
        }

        // The declining player must be the one who did NOT offer
        if ($offeredBy === $userId) {
            http_response_code(400);
            echo json_encode(['error' => 'cannot_decline_own_draw_offer']);
            break;
        }

        unset($gameState['draw_offered_by']);

        $update = ['game_state' => json_encode($gameState)];
        $res = supabase_rest('PATCH', "matches?id=eq.{$matchId}", $update, $token);

        if ($res['status'] >= 200 && $res['status'] < 300) {
            echo json_encode(['ok' => true, 'draw_declined' => true]);
        } else {
            http_response_code(500);
            echo json_encode(['error' => 'update_failed']);
        }
        break;

    case 'timeout':
        if ($match['status'] !== 'in_progress') {
            http_response_code(400);
            echo json_encode(['error' => 'match_not_in_progress']);
            break;
        }

        // The player is flagging their opponent's timeout
        if ($isWhite) {
            $opponentTimeMs = (int) ($match['black_time_remaining_ms'] ?? 0);
            $result = 'black_timeout';
        } else {
            $opponentTimeMs = (int) ($match['white_time_remaining_ms'] ?? 0);
            $result = 'white_timeout';
        }

        if ($opponentTimeMs > 0) {
            http_response_code(400);
            echo json_encode(['error' => 'opponent_has_time_remaining', 'remaining_ms' => $opponentTimeMs]);
            break;
        }

        $update = [
            'status' => 'completed',
            'result' => $result,
            'completed_at' => date('c'),
        ];

        $res = supabase_rest('PATCH', "matches?id=eq.{$matchId}", $update, $token);

        if ($res['status'] >= 200 && $res['status'] < 300) {
            echo json_encode(['ok' => true, 'result' => $result]);
        } else {
            http_response_code(500);
            echo json_encode(['error' => 'update_failed']);
        }
        break;

    case 'abort':
        if ($match['status'] !== 'in_progress' && $match['status'] !== 'ready') {
            http_response_code(400);
            echo json_encode(['error' => 'match_cannot_be_aborted']);
            break;
        }

        $moveCount = (int) ($match['move_count'] ?? 0);

        if ($moveCount >= 2) {
            http_response_code(400);
            echo json_encode(['error' => 'too_many_moves_to_abort', 'move_count' => $moveCount]);
            break;
        }

        $update = [
            'status' => 'aborted',
            'result' => 'aborted',
            'completed_at' => date('c'),
        ];

        $res = supabase_rest('PATCH', "matches?id=eq.{$matchId}", $update, $token);

        if ($res['status'] >= 200 && $res['status'] < 300) {
            echo json_encode(['ok' => true, 'result' => 'aborted']);
        } else {
            http_response_code(500);
            echo json_encode(['error' => 'update_failed']);
        }
        break;

    default:
        http_response_code(400);
        echo json_encode(['error' => 'invalid_action', 'valid_actions' => [
            'ready', 'move', 'resign', 'draw_offer', 'draw_accept', 'draw_decline', 'timeout', 'abort'
        ]]);
}
