<?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 'start':
        handleStart($db, $userId, $input);
        break;
    case 'move':
        handleGameMove($db, $userId, $input);
        break;
    case 'resign':
        handleResign($db, $userId, $input);
        break;
    case 'complete':
        handleComplete($db, $userId, $input);
        break;
    case 'get':
        handleGet($db, $userId, $input);
        break;
    default:
        jsonError('Invalid action');
}

function handleGet($db, string $userId, array $input): void {
    $matchId = $_GET['match_id'] ?? ($input['match_id'] ?? '');
    if (!$matchId) jsonError('match_id required');
    $matches = $db->get('matches', ['id' => 'eq.' . $matchId, 'limit' => 1]);
    $match = is_array($matches) && !empty($matches) && !isset($matches['error']) ? $matches[0] : null;
    if (!$match) jsonError('Match not found', 404);
    jsonResponse($match);
}

function handleStart($db, string $userId, array $input): void {
    $gameKey = $input['game_key'] ?? 'chess';
    $mode = $input['mode'] ?? 'bot';
    $timeControl = $input['time_control'] ?? 'rapid_10_0';
    $opponentId = $input['opponent_id'] ?? null;
    $botId = $input['bot_id'] ?? null;

    $data = [
        'game_key' => $gameKey,
        'white_player_id' => $userId,
        'black_player_id' => $opponentId,
        'status' => 'in_progress',
        'time_control' => $timeControl,
        'current_fen' => 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
        'moves' => '[]',
        'metadata' => json_encode(['mode' => $mode, 'bot_id' => $botId])
    ];

    $result = $db->insert('matches', $data);
    if (isset($result['error'])) jsonError($result['error']);
    jsonResponse($result[0] ?? $result);
}

function handleGameMove($db, string $userId, array $input): void {
    $matchId = $input['match_id'] ?? '';
    $moveData = $input['move'] ?? '';
    $fen = $input['fen'] ?? '';

    if (!$matchId || !$moveData || !$fen) {
        jsonError('match_id, move and fen are required');
    }

    $result = $db->update('matches', [
        'current_fen' => $fen,
        'moves' => $moveData
    ], ['id' => 'eq.' . $matchId]);

    if (isset($result['error'])) jsonError($result['error']);
    jsonResponse(['success' => true]);
}

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

    $match = $db->getOne('matches', ['id' => 'eq.' . $matchId]);
    if (!$match) jsonError('Match not found', 404);

    $isWhite = $match['white_player_id'] === $userId;
    $result = $isWhite ? 'black_wins' : 'white_wins';

    $db->update('matches', [
        'status' => 'completed',
        'result' => $result,
        'ended_at' => date('c')
    ], ['id' => 'eq.' . $matchId]);

    jsonResponse(['result' => $result]);
}

function handleComplete($db, string $userId, array $input): void {
    $matchId = $input['match_id'] ?? '';
    $result = $input['result'] ?? '';
    $fen = $input['fen'] ?? '';
    $pgn = $input['pgn'] ?? '';
    $opponentRating = intval($input['opponent_rating'] ?? 1200);
    $timeControl = $input['time_control'] ?? 'rapid_10_0';

    if (!$matchId || !$result) {
        jsonError('match_id and result are required');
    }

    $db->update('matches', [
        'status' => 'completed',
        'result' => $result,
        'current_fen' => $fen,
        'pgn' => $pgn,
        'ended_at' => date('c')
    ], ['id' => 'eq.' . $matchId]);

    // Calculate Elo rating change
    $ratingCol = getRatingColumn($timeControl);
    $profiles = $db->get('profiles', ['id' => 'eq.' . $userId, 'select' => $ratingCol . ',games_played,total_wins,total_draws,total_losses,coins,xp,level', 'limit' => 1]);
    $profile = is_array($profiles) && !empty($profiles) ? $profiles[0] : null;

    if ($profile) {
        $playerRating = $profile[$ratingCol] ?? 1200;
        $score = ($result === 'win') ? 1.0 : (($result === 'draw') ? 0.5 : 0.0);
        $newRating = calculateElo($playerRating, $opponentRating, $score);
        $ratingChange = $newRating - $playerRating;

        $updates = [$ratingCol => $newRating, 'games_played' => ($profile['games_played'] ?? 0) + 1];
        if ($result === 'win') $updates['total_wins'] = ($profile['total_wins'] ?? 0) + 1;
        elseif ($result === 'draw') $updates['total_draws'] = ($profile['total_draws'] ?? 0) + 1;
        else $updates['total_losses'] = ($profile['total_losses'] ?? 0) + 1;

        $db->update('profiles', $updates, ['id' => 'eq.' . $userId]);

        // Record rating history
        $sdb = supabaseService();
        $sdb->insert('rating_history', [
            'player_id' => $userId,
            'game_key' => 'chess',
            'time_control_type' => getTimeControlType($timeControl),
            'rating_before' => $playerRating,
            'rating_after' => $newRating,
            'rating_change' => $ratingChange,
            'match_id' => $matchId,
            'result' => $result
        ]);

        // Grant coins
        $coins = ($result === 'win') ? 50 : (($result === 'draw') ? 20 : 10);
        $currentCoins = $profile['coins'] ?? 0;
        $db->update('profiles', ['coins' => $currentCoins + $coins], ['id' => 'eq.' . $userId]);
        $sdb->insert('economy_transactions', [
            'player_id' => $userId,
            'type' => 'game_reward',
            'currency' => 'coins',
            'amount' => $coins,
            'balance_after' => $currentCoins + $coins,
            'reason' => 'Chess ' . $result
        ]);

        jsonResponse(['success' => true, 'result' => $result, 'rating_before' => $playerRating, 'rating_after' => $newRating, 'rating_change' => $ratingChange, 'coins_earned' => $coins]);
    }

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

function calculateElo(int $playerRating, int $opponentRating, float $score): int {
    $k = 32;
    if ($playerRating > 2400) $k = 16;
    elseif ($playerRating > 2000) $k = 24;

    $expected = 1.0 / (1.0 + pow(10, ($opponentRating - $playerRating) / 400.0));
    $newRating = round($playerRating + $k * ($score - $expected));
    return max(100, $newRating);
}

function getRatingColumn(string $timeControl): string {
    if (strpos($timeControl, 'bullet') !== false) return 'elo_bullet';
    if (strpos($timeControl, 'blitz') !== false) return 'elo_blitz';
    if (strpos($timeControl, 'classical') !== false) return 'elo_classical';
    return 'elo_rapid';
}

function getTimeControlType(string $timeControl): string {
    if (strpos($timeControl, 'bullet') !== false) return 'bullet';
    if (strpos($timeControl, 'blitz') !== false) return 'blitz';
    if (strpos($timeControl, 'classical') !== false) return 'classical';
    return 'rapid';
}
