<?php

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, DELETE, 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);

$method = $_SERVER['REQUEST_METHOD'];

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

if ($method === 'GET') {
    $action = $_GET['action'] ?? 'list';

    if ($action === 'list') {
        $friends = $sdb->get('friendships', [
            'or' => "(requester_id.eq.{$userId},addressee_id.eq.{$userId})",
            'status' => 'eq.accepted',
            'select' => 'id,requester_id,addressee_id'
        ]);

        if (!is_array($friends) || isset($friends['error'])) {
            jsonResponse(['friends' => []]);
        }

        $friendIds = [];
        foreach ($friends as $f) {
            $friendIds[] = $f['requester_id'] === $userId ? $f['addressee_id'] : $f['requester_id'];
        }

        if (empty($friendIds)) {
            jsonResponse(['friends' => []]);
        }

        $idList = implode(',', $friendIds);
        $profiles = $sdb->get('profiles', [
            'id' => "in.({$idList})",
            'select' => 'id,username,display_name,avatar_url,is_online,level'
        ]);

        jsonResponse(['friends' => is_array($profiles) && !isset($profiles['error']) ? $profiles : []]);
    }

    if ($action === 'pending') {
        $pending = $sdb->get('friendships', [
            'addressee_id' => 'eq.' . $userId,
            'status' => 'eq.pending',
            'select' => 'id,requester_id,created_at'
        ]);
        jsonResponse(['pending' => is_array($pending) && !isset($pending['error']) ? $pending : []]);
    }

    if ($action === 'sent') {
        $sent = $sdb->get('friendships', [
            'requester_id' => 'eq.' . $userId,
            'status' => 'eq.pending',
            'select' => 'id,addressee_id,created_at'
        ]);
        jsonResponse(['sent' => is_array($sent) && !isset($sent['error']) ? $sent : []]);
    }

    if ($action === 'search') {
        $query = $_GET['query'] ?? '';
        if (strlen($query) < 2) jsonError('Query too short');

        $results = $sdb->get('profiles', [
            'or' => "(username.ilike.*{$query}*,display_name.ilike.*{$query}*)",
            'id' => 'neq.' . $userId,
            'select' => 'id,username,display_name,avatar_url,level,is_online',
            'limit' => 15
        ]);

        jsonResponse(['players' => is_array($results) && !isset($results['error']) ? $results : []]);
    }

    if ($action === 'profiles') {
        $ids = $_GET['ids'] ?? '';
        if (!$ids) jsonResponse(['profiles' => []]);
        $idList = implode(',', array_map('trim', explode(',', $ids)));
        $profiles = $sdb->get('profiles', [
            'id' => "in.({$idList})",
            'select' => 'id,username,display_name,avatar_url,level,is_online'
        ]);
        jsonResponse(['profiles' => is_array($profiles) && !isset($profiles['error']) ? $profiles : []]);
    }

    jsonError('Invalid action');
}

if ($method === 'POST') {
    $input = getInput();
    $action = $input['action'] ?? '';

    if ($action === 'request') {
        $targetId = $input['target_id'] ?? '';
        if (!$targetId) jsonError('target_id required');
        if ($targetId === $userId) jsonError('Cannot add yourself');

        // Check for existing friendship or pending request in EITHER direction
        $existing = $sdb->get('friendships', [
            'or' => "(and(requester_id.eq.{$userId},addressee_id.eq.{$targetId}),and(requester_id.eq.{$targetId},addressee_id.eq.{$userId}))",
            'select' => 'id,status',
            'limit' => 1
        ]);

        if (is_array($existing) && !isset($existing['error']) && !empty($existing)) {
            $status = $existing[0]['status'] ?? '';
            if ($status === 'accepted') jsonError('Already friends');
            if ($status === 'pending') jsonError('Request already pending');
        }

        $result = $sdb->insert('friendships', [
            'requester_id' => $userId,
            'addressee_id' => $targetId,
            'status' => 'pending'
        ]);
        if (isset($result['error'])) jsonError($result['error']);
        jsonResponse(['success' => true]);
    }

    if ($action === 'accept') {
        $friendshipId = $input['friendship_id'] ?? '';
        if (!$friendshipId) jsonError('friendship_id required');

        // Verify this request is addressed to the current user
        $friendship = $sdb->get('friendships', [
            'id' => 'eq.' . $friendshipId,
            'addressee_id' => 'eq.' . $userId,
            'status' => 'eq.pending',
            'select' => 'id,requester_id',
            'limit' => 1
        ]);

        if (!is_array($friendship) || isset($friendship['error']) || empty($friendship)) {
            jsonError('Friend request not found or already handled');
        }

        $result = $sdb->update('friendships', [
            'status' => 'accepted',
            'updated_at' => gmdate('c')
        ], ['id' => 'eq.' . $friendshipId]);

        if (isset($result['error'])) jsonError($result['error']);

        jsonResponse(['success' => true, 'friend_id' => $friendship[0]['requester_id']]);
    }

    if ($action === 'reject') {
        $friendshipId = $input['friendship_id'] ?? '';
        if (!$friendshipId) jsonError('friendship_id required');

        // Verify this request is addressed to the current user
        $friendship = $sdb->get('friendships', [
            'id' => 'eq.' . $friendshipId,
            'addressee_id' => 'eq.' . $userId,
            'status' => 'eq.pending',
            'limit' => 1
        ]);

        if (!is_array($friendship) || isset($friendship['error']) || empty($friendship)) {
            jsonError('Friend request not found');
        }

        $sdb->delete('friendships', ['id' => 'eq.' . $friendshipId]);
        jsonResponse(['success' => true]);
    }

    if ($action === 'remove') {
        $targetId = $input['target_id'] ?? '';
        if (!$targetId) jsonError('target_id required');

        $sdb->delete('friendships', [
            'or' => "(and(requester_id.eq.{$userId},addressee_id.eq.{$targetId}),and(requester_id.eq.{$targetId},addressee_id.eq.{$userId}))"
        ]);
        jsonResponse(['success' => true]);
    }

    if ($action === 'report') {
        $targetId = $input['target_id'] ?? '';
        $reason = $input['reason'] ?? 'other';
        if (!$targetId) jsonError('target_id required');
        // Just acknowledge — in future, store reports in a table
        jsonResponse(['success' => true]);
    }

    if ($action === 'invite') {
        $targetId = $input['target_id'] ?? '';
        $gameKey = $input['game_key'] ?? 'chess';
        $timeControl = $input['time_control'] ?? 'rapid_10_0';
        if (!$targetId) jsonError('target_id required');

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

        // Randomly assign colors
        $isWhite = rand(0, 1) === 0;
        $whiteId = $isWhite ? $userId : $targetId;
        $blackId = $isWhite ? $targetId : $userId;

        $match = $sdb->insert('matches', [
            'game_key' => $gameKey,
            'match_type' => 'friendly',
            'white_player_id' => $whiteId,
            'black_player_id' => $blackId,
            'status' => 'waiting',
            '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' => json_encode(['invite_from' => $userId, 'invite_to' => $targetId, 'invite_t' => time()]),
            'is_rated' => false,
            'created_at' => gmdate('c')
        ]);

        if (isset($match['error'])) jsonError($match['error']);
        $matchId = $match[0]['id'] ?? null;

        jsonResponse([
            'match_id' => $matchId,
            'color' => $isWhite ? 'w' : 'b',
            'game_key' => $gameKey,
            'time_control' => $timeControl
        ]);
    }

    if ($action === 'check-invites') {
        // Check if there are pending invites for this user
        $invites = $sdb->get('matches', [
            'or' => "(white_player_id.eq.{$userId},black_player_id.eq.{$userId})",
            'status' => 'eq.waiting',
            'match_type' => 'eq.friendly',
            'select' => 'id,game_key,time_control,white_player_id,black_player_id,game_state,created_at',
            'order' => 'created_at.desc',
            'limit' => 5
        ]);

        if (!is_array($invites) || isset($invites['error'])) {
            jsonResponse(['invites' => []]);
        }

        // Filter: only show invites TO this user (not ones I sent) and recent (< 2 min)
        $result = [];
        $now = time();
        foreach ($invites as $inv) {
            $gs = is_array($inv['game_state']) ? $inv['game_state'] : json_decode($inv['game_state'] ?? '{}', true);
            $inviteTo = $gs['invite_to'] ?? null;
            $inviteT = $gs['invite_t'] ?? 0;
            if ($inviteTo !== $userId) continue;
            if ($now - $inviteT > 120) continue; // Expired after 2 min
            $inviteFrom = $gs['invite_from'] ?? null;
            $result[] = [
                'match_id' => $inv['id'],
                'game_key' => $inv['game_key'],
                'time_control' => $inv['time_control'],
                'from_id' => $inviteFrom,
                'created_at' => $inv['created_at']
            ];
        }

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

    if ($action === 'accept-invite') {
        $matchId = $input['match_id'] ?? '';
        if (!$matchId) jsonError('match_id required');

        // Verify the match is for this user and is still waiting
        $matches = $sdb->get('matches', [
            'id' => 'eq.' . $matchId,
            'status' => 'eq.waiting',
            'or' => "(white_player_id.eq.{$userId},black_player_id.eq.{$userId})",
            'select' => 'id,white_player_id,black_player_id',
            'limit' => 1
        ]);

        if (!is_array($matches) || isset($matches['error']) || empty($matches)) {
            jsonError('Invite not found or expired');
        }

        // Start the match
        $sdb->update('matches', [
            'status' => 'in_progress',
            'started_at' => gmdate('c')
        ], ['id' => 'eq.' . $matchId]);

        $match = $matches[0];
        $color = ($match['white_player_id'] === $userId) ? 'w' : 'b';

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

    if ($action === 'decline-invite') {
        $matchId = $input['match_id'] ?? '';
        if (!$matchId) jsonError('match_id required');

        $sdb->update('matches', [
            'status' => 'completed',
            'result' => 'declined'
        ], ['id' => 'eq.' . $matchId, 'status' => 'eq.waiting']);

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

    jsonError('Invalid action');
}

if ($method === 'DELETE') {
    $input = getInput();
    $targetId = $input['target_id'] ?? '';
    if (!$targetId) jsonError('target_id required');

    $sdb->delete('friendships', [
        'or' => "(and(requester_id.eq.{$userId},addressee_id.eq.{$targetId}),and(requester_id.eq.{$targetId},addressee_id.eq.{$userId}))"
    ]);
    jsonResponse(['success' => true]);
}

jsonError('Invalid request', 400);
