<?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;
}

$method = $_SERVER['REQUEST_METHOD'];

if ($method === 'GET') {
    $action = $_GET['action'] ?? '';
    if ($action === 'recent') {
        $res = supabase_rest('GET', 'matches?select=id,bot_id,result,time_control,completed_at&status=eq.completed&order=completed_at.desc&limit=10', [], $token);
        echo json_encode(['games' => $res['data'] ?? []]);
    } elseif ($action === 'get') {
        $id = $_GET['id'] ?? '';
        $res = supabase_rest('GET', "matches?id=eq.{$id}&select=*", [], $token);
        if (!empty($res['data'])) {
            echo json_encode(['game' => $res['data'][0]]);
        } else {
            http_response_code(404);
            echo json_encode(['error' => 'not found']);
        }
    } else {
        echo json_encode(['error' => 'invalid action']);
    }
    exit;
}

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

switch ($action) {
    case 'start':
        $botId = $input['bot_id'] ?? 'nour';
        $color = $input['color'] ?? 'w';
        $timeControl = $input['time_control'] ?? 600;
        $increment = $input['increment'] ?? 0;
        $rated = $input['rated'] ?? true;

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

        $tcMap = [
            '60_0' => 'bullet_1_0', '60_1' => 'bullet_1_1', '120_1' => 'bullet_2_1',
            '180_0' => 'blitz_3_0', '180_2' => 'blitz_3_2', '300_0' => 'blitz_5_0',
            '300_3' => 'blitz_5_3', '600_0' => 'rapid_10_0', '600_5' => 'rapid_10_5',
            '900_10' => 'rapid_15_10', '1800_0' => 'rapid_30_0',
        ];
        $tcKey = $timeControl . '_' . $increment;
        $tcEnum = $tcMap[$tcKey] ?? 'custom';

        $matchData = [
            'match_type' => 'bot',
            'bot_id' => $botId,
            'bot_difficulty' => $botId,
            'status' => 'in_progress',
            'time_control' => $tcEnum,
            'initial_time_ms' => $timeControl * 1000,
            'increment_ms' => $increment * 1000,
            'white_time_remaining_ms' => $timeControl * 1000,
            'black_time_remaining_ms' => $timeControl * 1000,
            'is_rated' => $rated,
            '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',
            'move_count' => 0,
            'moves' => json_encode([]),
            'game_state' => json_encode([]),
            'started_at' => date('c'),
        ];

        if ($color === 'w') {
            $matchData['white_player_id'] = $userId;
        } else {
            $matchData['black_player_id'] = $userId;
        }

        $res = supabase_rest('POST', 'matches', $matchData, $token);

        if ($res['status'] >= 200 && $res['status'] < 300 && !empty($res['data'])) {
            echo json_encode(['game_id' => $res['data'][0]['id'] ?? null, 'status' => 'started']);
        } else {
            echo json_encode(['game_id' => uniqid('game_'), 'status' => 'started']);
        }
        break;

    case 'bot_move':
        $botId = $input['bot_id'] ?? 'nour';
        $fen = $input['fen'] ?? '';
        $wtime = $input['wtime'] ?? 60000;
        $btime = $input['btime'] ?? 60000;

        $apiUrl = STOCKFISH_API . '/api/chess/move';
        $payload = json_encode([
            'bot_id' => $botId,
            'fen' => $fen,
            'wtime' => $wtime,
            'btime' => $btime
        ]);

        $ch = curl_init($apiUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'X-API-Key: ' . STOCKFISH_MGMT_KEY
        ]);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        unset($ch);

        if ($httpCode === 200) {
            $data = json_decode($response, true);
            echo json_encode(['move' => $data['best_move'] ?? null, 'eval' => $data['evaluation'] ?? null]);
        } else {
            http_response_code(502);
            echo json_encode(['error' => 'bot_unavailable', 'status' => $httpCode]);
        }
        break;

    case 'move':
        $gameId = $input['game_id'] ?? '';
        $move = $input['move'] ?? '';
        $fen = $input['fen'] ?? '';
        $moves = $input['moves'] ?? null;

        if ($gameId && !str_starts_with($gameId, 'game_')) {
            $update = [
                'current_fen' => $fen,
                'white_time_remaining_ms' => ($input['clock_white'] ?? 0) * 1000,
                'black_time_remaining_ms' => ($input['clock_black'] ?? 0) * 1000,
            ];
            if ($moves !== null) {
                $update['moves'] = json_encode($moves);
                $update['move_count'] = count($moves);
            }
            supabase_rest('PATCH', "matches?id=eq.{$gameId}", $update, $token);
        }
        echo json_encode(['ok' => true]);
        break;

    case 'end':
        $gameId = $input['game_id'] ?? '';
        $result = $input['result'] ?? '';
        $reason = $input['reason'] ?? '';
        $pgn = $input['pgn'] ?? '';
        $finalFen = $input['final_fen'] ?? '';
        $moves = $input['moves'] ?? null;
        $botId = $input['bot_id'] ?? '';
        $timeControl = $input['time_control'] ?? 600;
        $increment = $input['increment'] ?? 0;
        $rated = $input['rated'] ?? true;

        $resultMap = ['win' => 'white_wins', 'loss' => 'black_wins', 'draw' => 'draw'];

        if ($gameId && !str_starts_with($gameId, 'game_')) {
            $update = [
                'status' => 'completed',
                'result' => $resultMap[$result] ?? $result,
                'pgn' => $pgn,
                'current_fen' => $finalFen,
                'completed_at' => date('c'),
            ];
            if ($moves !== null) {
                if (is_array($moves)) {
                    $update['moves'] = json_encode($moves);
                    $update['move_count'] = count($moves);
                } else {
                    $update['moves'] = $moves;
                }
            }
            if (!empty($input['move_count'])) {
                $update['move_count'] = (int)$input['move_count'];
            }
            supabase_rest('PATCH', "matches?id=eq.{$gameId}", $update, SUPABASE_SERVICE_KEY);
        }

        // --- Get player profile for ELO/XP/coins updates ---
        $userRes = supabase_auth('user', [], $token, 'GET');
        $userId = $userRes['data']['id'] ?? null;

        if ($userId) {
            $profileRes = supabase_rest('GET', "profiles?id=eq.{$userId}&select=id,elo_bullet,elo_blitz,elo_rapid,elo_classical,xp,level,coins,games_played,total_games_played,total_wins,total_draws,total_losses", [], SUPABASE_SERVICE_KEY);
            $profile = $profileRes['data'][0] ?? null;

            if ($profile) {
                // --- Load system_config values ---
                $cfgRes = supabase_rest('GET', 'system_config?select=key,value&key=in.(elo_k_factor_new,elo_k_factor_established,xp_per_game,xp_per_win_bonus,coins_per_win_casual,coins_per_win_ranked)', [], SUPABASE_SERVICE_KEY);
                $cfg = [];
                if (!empty($cfgRes['data'])) {
                    foreach ($cfgRes['data'] as $c) {
                        $cfg[$c['key']] = $c['value'];
                    }
                }
                $kNew = (int)($cfg['elo_k_factor_new'] ?? 40);
                $kEstablished = (int)($cfg['elo_k_factor_established'] ?? 20);
                $xpPerGame = (int)($cfg['xp_per_game'] ?? 50);
                $xpPerWinBonus = (int)($cfg['xp_per_win_bonus'] ?? 30);
                $coinsPerWinCasual = (int)($cfg['coins_per_win_casual'] ?? 10);
                $coinsPerWinRanked = (int)($cfg['coins_per_win_ranked'] ?? 25);

                // Determine time control type for ELO field
                $tcSeconds = (int)$timeControl;
                if ($tcSeconds < 180) {
                    $eloField = 'elo_bullet';
                    $tcType = 'bullet';
                } elseif ($tcSeconds < 600) {
                    $eloField = 'elo_blitz';
                    $tcType = 'blitz';
                } else {
                    $eloField = 'elo_rapid';
                    $tcType = 'rapid';
                }

                $playerElo = (int)($profile[$eloField] ?? 0);
                $gamesPlayed = (int)($profile['games_played'] ?? $profile['total_games_played'] ?? 0);
                $kFactor = ($gamesPlayed < 30) ? $kNew : $kEstablished;

                // Bot ELO mapping (average of elo_min/elo_max from Stockfish API bots)
                $botEloMap = [
                    'nour' => 400,
                    'salma' => 600,
                    'amr' => 800,
                    'yasmine' => 1000,
                    'omar' => 1200,
                    'layla' => 1400,
                    'karim' => 1600,
                    'farida' => 1800,
                    'tarek' => 2000,
                    'maha' => 2200,
                    'ziad' => 2500,
                    'grandmaster' => 2800,
                ];
                $botElo = $botEloMap[$botId] ?? 1200;

                // --- ELO Calculation (standard formula) ---
                $profileUpdate = [];
                $ratingChange = 0;
                $newElo = $playerElo;

                if ($rated) {
                    $expected = 1.0 / (1.0 + pow(10, ($botElo - $playerElo) / 400.0));
                    $actual = ($result === 'win') ? 1.0 : (($result === 'draw') ? 0.5 : 0.0);
                    $ratingChange = (int)round($kFactor * ($actual - $expected));
                    $newElo = max(0, $playerElo + $ratingChange);
                    $profileUpdate[$eloField] = $newElo;

                    // INSERT into rating_history
                    supabase_rest('POST', 'rating_history', [
                        'player_id' => $userId,
                        'game_key' => 'chess',
                        'time_control_type' => $tcType,
                        'rating_before' => $playerElo,
                        'rating_after' => $newElo,
                        'rating_change' => $ratingChange,
                        'match_id' => (!str_starts_with($gameId, 'game_')) ? $gameId : null,
                        'opponent_id' => null,
                        'opponent_rating' => $botElo,
                        'result' => $result,
                        'k_factor' => $kFactor,
                    ], SUPABASE_SERVICE_KEY);

                    // DUAL-WRITE: Update player_game_ratings table
                    $winInc = ($result === 'win') ? 1 : 0;
                    $lossInc = ($result === 'loss') ? 1 : 0;
                    $drawInc = ($result === 'draw') ? 1 : 0;

                    $existingRating = supabase_rest('GET', "player_game_ratings?player_id=eq.{$userId}&game_key=eq.chess&mode=eq.{$tcType}&select=id,games_played,wins,losses,draws,win_streak,best_win_streak", [], SUPABASE_SERVICE_KEY);

                    if (!empty($existingRating['data'])) {
                        $pgr = $existingRating['data'][0];
                        $newWinStreak = ($result === 'win') ? ($pgr['win_streak'] + 1) : 0;
                        $bestStreak = max($pgr['best_win_streak'], $newWinStreak);
                        supabase_rest('PATCH', "player_game_ratings?id=eq.{$pgr['id']}", [
                            'rating' => $newElo,
                            'games_played' => $pgr['games_played'] + 1,
                            'wins' => $pgr['wins'] + $winInc,
                            'losses' => $pgr['losses'] + $lossInc,
                            'draws' => $pgr['draws'] + $drawInc,
                            'win_streak' => $newWinStreak,
                            'best_win_streak' => $bestStreak,
                            'last_played_at' => date('c'),
                            'updated_at' => date('c'),
                        ], SUPABASE_SERVICE_KEY);
                    } else {
                        supabase_rest('POST', 'player_game_ratings', [
                            'player_id' => $userId,
                            'game_key' => 'chess',
                            'mode' => $tcType,
                            'rating' => $newElo,
                            'games_played' => 1,
                            'wins' => $winInc,
                            'losses' => $lossInc,
                            'draws' => $drawInc,
                            'win_streak' => $winInc,
                            'best_win_streak' => $winInc,
                            'last_played_at' => date('c'),
                        ], SUPABASE_SERVICE_KEY);
                    }
                }

                // --- XP Awards ---
                $xpAwarded = $xpPerGame;
                if ($result === 'win') {
                    $xpAwarded += $xpPerWinBonus;
                }
                $newXp = (int)($profile['xp'] ?? 0) + $xpAwarded;
                $currentLevel = (int)($profile['level'] ?? 1);
                $profileUpdate['xp'] = $newXp;

                // Check for level up
                $levelRes = supabase_rest('GET', "xp_levels?level=eq." . ($currentLevel + 1) . "&select=level,xp_required,reward_coins", [], SUPABASE_SERVICE_KEY);
                $levelUpCoinsBonus = 0;
                if (!empty($levelRes['data']) && $newXp >= (int)$levelRes['data'][0]['xp_required']) {
                    $newLevel = (int)$levelRes['data'][0]['level'];
                    $levelUpCoinsBonus = (int)($levelRes['data'][0]['reward_coins'] ?? 0);
                    $profileUpdate['level'] = $newLevel;
                }

                // --- Coins Awards ---
                $coinsAwarded = 0;
                if ($result === 'win') {
                    $coinsAwarded = $rated ? $coinsPerWinRanked : $coinsPerWinCasual;
                }
                $totalCoinsAwarded = $coinsAwarded + $levelUpCoinsBonus;
                $newCoins = (int)($profile['coins'] ?? 0) + $totalCoinsAwarded;
                if ($totalCoinsAwarded > 0) {
                    $profileUpdate['coins'] = $newCoins;
                }

                // Update games played count
                $profileUpdate['total_games_played'] = $gamesPlayed + 1;
                if (isset($profile['games_played'])) {
                    $profileUpdate['games_played'] = $gamesPlayed + 1;
                }
                if ($result === 'win') {
                    $profileUpdate['total_wins'] = (int)($profile['total_wins'] ?? 0) + 1;
                } elseif ($result === 'draw') {
                    $profileUpdate['total_draws'] = (int)($profile['total_draws'] ?? 0) + 1;
                } else {
                    $profileUpdate['total_losses'] = (int)($profile['total_losses'] ?? 0) + 1;
                }

                // Apply profile updates
                if (!empty($profileUpdate)) {
                    supabase_rest('PATCH', "profiles?id=eq.{$userId}", $profileUpdate, SUPABASE_SERVICE_KEY);
                }

                // --- Log economy_transactions for coins earned ---
                if ($coinsAwarded > 0) {
                    supabase_rest('POST', 'economy_transactions', [
                        'player_id' => $userId,
                        'type' => 'game_reward',
                        'currency' => 'coins',
                        'amount' => $coinsAwarded,
                        'balance_after' => $newCoins - $levelUpCoinsBonus,
                        'reason' => 'Win reward vs bot ' . $botId,
                        'source_id' => $gameId,
                    ], SUPABASE_SERVICE_KEY);
                }
                if ($levelUpCoinsBonus > 0) {
                    supabase_rest('POST', 'economy_transactions', [
                        'player_id' => $userId,
                        'type' => 'level_up_reward',
                        'currency' => 'coins',
                        'amount' => $levelUpCoinsBonus,
                        'balance_after' => $newCoins,
                        'reason' => 'Level up reward',
                        'source_id' => $gameId,
                    ], SUPABASE_SERVICE_KEY);
                }
            }
        }

        echo json_encode([
            'ok' => true,
            'result' => $result,
            'game_id' => $gameId,
            'elo_change' => $ratingChange ?? 0,
            'new_elo' => $newElo ?? null,
            'xp_awarded' => $xpAwarded ?? 0,
            'coins_awarded' => $totalCoinsAwarded ?? 0,
        ]);
        break;

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