<?php

header('Content-Type: application/json');
require_once __DIR__ . '/../includes/cors.php';

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'];
$sdb = supabaseService();

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

    if ($action === 'list') {
        $memberships = $sdb->get('group_members', [
            'user_id' => 'eq.' . $userId,
            'select' => 'group_id,role,joined_at,groups(id,name,avatar_url,owner_id,member_count,created_at)'
        ]);
        if (!is_array($memberships) || isset($memberships['error'])) {
            jsonResponse(['groups' => []]);
        }
        $groups = array_map(function($m) {
            $g = $m['groups'] ?? [];
            $g['my_role'] = $m['role'];
            return $g;
        }, $memberships);
        jsonResponse(['groups' => $groups]);
    }

    if ($action === 'detail') {
        $groupId = $_GET['group_id'] ?? '';
        if (!$groupId) jsonError('group_id required');

        // Verify membership
        $membership = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $userId,
            'limit' => 1
        ]);
        if (!is_array($membership) || isset($membership['error']) || empty($membership)) {
            jsonError('Not a member of this group', 403);
        }

        $group = $sdb->get('groups', ['id' => 'eq.' . $groupId, 'select' => '*', 'limit' => 1]);
        if (!is_array($group) || isset($group['error']) || empty($group)) {
            jsonError('Group not found', 404);
        }

        $members = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'select' => 'user_id,role,joined_at,profiles(id,display_name,avatar_url,is_online)'
        ]);

        jsonResponse([
            'group' => $group[0],
            'members' => is_array($members) && !isset($members['error']) ? $members : [],
            'my_role' => $membership[0]['role']
        ]);
    }

    if ($action === 'chat-history') {
        $groupId = $_GET['group_id'] ?? '';
        if (!$groupId) jsonError('group_id required');

        // Verify membership
        $membership = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $userId,
            'limit' => 1
        ]);
        if (!is_array($membership) || isset($membership['error']) || empty($membership)) {
            jsonError('Not a member', 403);
        }

        $limit = min(intval($_GET['limit'] ?? 50), 100);
        $before = $_GET['before'] ?? null;

        $params = [
            'channel_type' => 'eq.group',
            'channel_id' => 'eq.' . $groupId,
            'select' => 'id,sender_id,content,message_type,metadata,created_at,profiles(display_name,avatar_url)',
            'order' => 'created_at.desc',
            'limit' => $limit
        ];
        if ($before) $params['created_at'] = 'lt.' . $before;

        $messages = $sdb->get('chat_messages', $params);
        if (!is_array($messages) || isset($messages['error'])) {
            jsonResponse(['messages' => []]);
        }

        // Filter muted users client-side info
        $blocks = $sdb->get('player_blocks', [
            'player_id' => 'eq.' . $userId,
            'type' => 'eq.mute',
            'select' => 'blocked_id'
        ]);
        $mutedIds = [];
        if (is_array($blocks) && !isset($blocks['error'])) {
            $mutedIds = array_column($blocks, 'blocked_id');
        }

        jsonResponse([
            'messages' => array_reverse($messages),
            'muted_ids' => $mutedIds
        ]);
    }

    if ($action === 'check-group-invites') {
        $groupId = $_GET['group_id'] ?? '';
        if (!$groupId) jsonError('group_id required');

        // Look for waiting matches with group_invite in game_state
        $matches = $sdb->get('matches', [
            'status' => 'eq.waiting',
            'select' => 'id,game_key,white_player_id,game_state,created_at',
            'order' => 'created_at.desc',
            'limit' => 10
        ]);

        $invites = [];
        $now = time();
        if (is_array($matches) && !isset($matches['error'])) {
            foreach ($matches as $m) {
                $gs = is_string($m['game_state']) ? json_decode($m['game_state'], true) : ($m['game_state'] ?? []);
                if (($gs['group_id'] ?? '') !== $groupId) continue;
                $createdAt = strtotime($m['created_at']);
                if ($now - $createdAt > 120) continue;
                $invites[] = [
                    'match_id' => $m['id'],
                    'game_key' => $m['game_key'],
                    'inviter_id' => $m['white_player_id'],
                    'required_players' => $gs['required_players'] ?? 2,
                    'accepted' => $gs['accepted'] ?? [],
                    'created_at' => $m['created_at']
                ];
            }
        }

        // Also check ludo_matches
        $ludoMatches = $sdb->get('ludo_matches', [
            'status' => 'eq.waiting',
            'select' => 'id,game_state,created_at',
            'order' => 'created_at.desc',
            'limit' => 10
        ]);
        if (is_array($ludoMatches) && !isset($ludoMatches['error'])) {
            foreach ($ludoMatches as $m) {
                $gs = is_string($m['game_state']) ? json_decode($m['game_state'], true) : ($m['game_state'] ?? []);
                if (($gs['group_id'] ?? '') !== $groupId) continue;
                $createdAt = strtotime($m['created_at']);
                if ($now - $createdAt > 120) continue;
                $invites[] = [
                    'match_id' => $m['id'],
                    'game_key' => 'ludo',
                    'inviter_id' => $gs['accepted'][0] ?? null,
                    'required_players' => $gs['required_players'] ?? 2,
                    'accepted' => $gs['accepted'] ?? [],
                    'created_at' => $m['created_at']
                ];
            }
        }

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

    jsonError('Invalid action');
}

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

    if ($action === 'create') {
        $name = trim($input['name'] ?? '');
        $memberIds = $input['member_ids'] ?? [];

        if (!$name || mb_strlen($name) < 2 || mb_strlen($name) > 50) {
            jsonError('Group name must be 2-50 characters');
        }
        if (count($memberIds) > 19) jsonError('Maximum 19 initial members (20 including you)');

        // Filter out blocked users
        $blocks = $sdb->get('player_blocks', [
            'or' => "(player_id.eq.{$userId},blocked_id.eq.{$userId})",
            'type' => 'eq.block',
            'select' => 'player_id,blocked_id'
        ]);
        $blockedIds = [];
        if (is_array($blocks) && !isset($blocks['error'])) {
            foreach ($blocks as $b) {
                $blockedIds[] = ($b['player_id'] === $userId) ? $b['blocked_id'] : $b['player_id'];
            }
        }
        $memberIds = array_values(array_filter($memberIds, fn($id) => !in_array($id, $blockedIds)));

        // Create group
        $group = $sdb->insert('groups', [
            'name' => $name,
            'owner_id' => $userId,
            'member_count' => 1 + count($memberIds)
        ]);
        if (isset($group['error'])) jsonError($group['error']);
        $groupId = $group[0]['id'] ?? $group['id'] ?? null;
        if (!$groupId) jsonError('Failed to create group');

        // Add owner
        $sdb->insert('group_members', [
            'group_id' => $groupId,
            'user_id' => $userId,
            'role' => 'owner'
        ]);

        // Add initial members
        foreach ($memberIds as $memberId) {
            $sdb->insert('group_members', [
                'group_id' => $groupId,
                'user_id' => $memberId,
                'role' => 'member'
            ]);
            // Notify
            $sdb->insert('notifications', [
                'user_id' => $memberId,
                'type' => 'group_added',
                'title' => 'تمت إضافتك لمجموعة ' . $name,
                'title_ar' => 'تمت إضافتك لمجموعة ' . $name,
                'body' => 'You were added to group ' . $name,
                'data' => json_encode(['group_id' => $groupId])
            ]);
        }

        jsonResponse(['group' => $group[0] ?? $group, 'success' => true]);
    }

    if ($action === 'add-member') {
        $groupId = $input['group_id'] ?? '';
        $targetId = $input['user_id'] ?? '';
        if (!$groupId || !$targetId) jsonError('group_id and user_id required');

        // Check caller is owner/admin
        $myMembership = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $userId,
            'select' => 'role',
            'limit' => 1
        ]);
        if (!is_array($myMembership) || empty($myMembership) || !in_array($myMembership[0]['role'], ['owner', 'admin'])) {
            jsonError('Only owner/admin can add members', 403);
        }

        // Check blocks
        $blocked = $sdb->get('player_blocks', [
            'or' => "(and(player_id.eq.{$targetId},blocked_id.eq.{$userId}),and(player_id.eq.{$userId},blocked_id.eq.{$targetId}))",
            'type' => 'eq.block',
            'limit' => 1
        ]);
        if (is_array($blocked) && !isset($blocked['error']) && !empty($blocked)) {
            jsonError('Cannot add this player');
        }

        // Check not already member
        $existing = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $targetId,
            'limit' => 1
        ]);
        if (is_array($existing) && !isset($existing['error']) && !empty($existing)) {
            jsonError('Already a member');
        }

        // Check max members
        $group = $sdb->get('groups', ['id' => 'eq.' . $groupId, 'select' => 'member_count,max_members,name', 'limit' => 1]);
        if (is_array($group) && !empty($group) && $group[0]['member_count'] >= $group[0]['max_members']) {
            jsonError('Group is full');
        }

        $sdb->insert('group_members', [
            'group_id' => $groupId,
            'user_id' => $targetId,
            'role' => 'member'
        ]);

        // Increment member_count
        $newCount = ($group[0]['member_count'] ?? 0) + 1;
        $sdb->update('groups', ['member_count' => $newCount], ['id' => 'eq.' . $groupId]);

        // Notify
        $groupName = $group[0]['name'] ?? 'مجموعة';
        $sdb->insert('notifications', [
            'user_id' => $targetId,
            'type' => 'group_added',
            'title' => 'تمت إضافتك لمجموعة ' . $groupName,
            'title_ar' => 'تمت إضافتك لمجموعة ' . $groupName,
            'body' => 'You were added to group ' . $groupName,
            'data' => json_encode(['group_id' => $groupId])
        ]);

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

    if ($action === 'remove-member') {
        $groupId = $input['group_id'] ?? '';
        $targetId = $input['user_id'] ?? '';
        if (!$groupId || !$targetId) jsonError('group_id and user_id required');

        $myMembership = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $userId,
            'select' => 'role',
            'limit' => 1
        ]);
        if (!is_array($myMembership) || empty($myMembership) || !in_array($myMembership[0]['role'], ['owner', 'admin'])) {
            jsonError('Only owner/admin can remove members', 403);
        }

        // Can't remove owner
        $targetMembership = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $targetId,
            'select' => 'role',
            'limit' => 1
        ]);
        if (is_array($targetMembership) && !empty($targetMembership) && $targetMembership[0]['role'] === 'owner') {
            jsonError('Cannot remove group owner');
        }

        $sdb->delete('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $targetId
        ]);

        // Decrement count
        $group = $sdb->get('groups', ['id' => 'eq.' . $groupId, 'select' => 'member_count', 'limit' => 1]);
        $newCount = max(1, ($group[0]['member_count'] ?? 1) - 1);
        $sdb->update('groups', ['member_count' => $newCount], ['id' => 'eq.' . $groupId]);

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

    if ($action === 'leave') {
        $groupId = $input['group_id'] ?? '';
        if (!$groupId) jsonError('group_id required');

        $myMembership = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $userId,
            'select' => 'role',
            'limit' => 1
        ]);
        if (!is_array($myMembership) || empty($myMembership)) {
            jsonError('Not a member');
        }

        if ($myMembership[0]['role'] === 'owner') {
            // Transfer ownership to first admin, or delete group
            $admins = $sdb->get('group_members', [
                'group_id' => 'eq.' . $groupId,
                'role' => 'eq.admin',
                'user_id' => 'neq.' . $userId,
                'select' => 'user_id',
                'limit' => 1
            ]);
            if (is_array($admins) && !isset($admins['error']) && !empty($admins)) {
                $sdb->update('groups', ['owner_id' => $admins[0]['user_id']], ['id' => 'eq.' . $groupId]);
                $sdb->update('group_members', ['role' => 'owner'], [
                    'group_id' => 'eq.' . $groupId,
                    'user_id' => 'eq.' . $admins[0]['user_id']
                ]);
            } else {
                // Transfer to first member
                $members = $sdb->get('group_members', [
                    'group_id' => 'eq.' . $groupId,
                    'user_id' => 'neq.' . $userId,
                    'select' => 'user_id',
                    'order' => 'joined_at.asc',
                    'limit' => 1
                ]);
                if (is_array($members) && !isset($members['error']) && !empty($members)) {
                    $sdb->update('groups', ['owner_id' => $members[0]['user_id']], ['id' => 'eq.' . $groupId]);
                    $sdb->update('group_members', ['role' => 'owner'], [
                        'group_id' => 'eq.' . $groupId,
                        'user_id' => 'eq.' . $members[0]['user_id']
                    ]);
                } else {
                    // No other members — delete group
                    $sdb->delete('group_members', ['group_id' => 'eq.' . $groupId]);
                    $sdb->delete('groups', ['id' => 'eq.' . $groupId]);
                    jsonResponse(['success' => true, 'deleted' => true]);
                }
            }
        }

        $sdb->delete('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $userId
        ]);

        $group = $sdb->get('groups', ['id' => 'eq.' . $groupId, 'select' => 'member_count', 'limit' => 1]);
        if (is_array($group) && !empty($group)) {
            $newCount = max(0, ($group[0]['member_count'] ?? 1) - 1);
            $sdb->update('groups', ['member_count' => $newCount], ['id' => 'eq.' . $groupId]);
        }

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

    if ($action === 'update') {
        $groupId = $input['group_id'] ?? '';
        if (!$groupId) jsonError('group_id required');

        $myMembership = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $userId,
            'select' => 'role',
            'limit' => 1
        ]);
        if (!is_array($myMembership) || empty($myMembership) || !in_array($myMembership[0]['role'], ['owner', 'admin'])) {
            jsonError('Only owner/admin can update group', 403);
        }

        $data = [];
        if (isset($input['name']) && mb_strlen(trim($input['name'])) >= 2) {
            $data['name'] = trim($input['name']);
        }
        if (isset($input['avatar_url'])) {
            $data['avatar_url'] = $input['avatar_url'];
        }
        if (empty($data)) jsonError('Nothing to update');

        $sdb->update('groups', $data, ['id' => 'eq.' . $groupId]);
        jsonResponse(['success' => true]);
    }

    if ($action === 'chat-send') {
        $groupId = $input['group_id'] ?? '';
        $content = trim($input['content'] ?? '');
        $messageType = $input['message_type'] ?? 'text';

        if (!$groupId) jsonError('group_id required');
        if (!$content) jsonError('content required');
        if (mb_strlen($content) > 500) jsonError('Message too long');

        // Verify membership
        $membership = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $userId,
            'limit' => 1
        ]);
        if (!is_array($membership) || isset($membership['error']) || empty($membership)) {
            jsonError('Not a member', 403);
        }

        $msg = $sdb->insert('chat_messages', [
            'channel_type' => 'group',
            'channel_id' => $groupId,
            'sender_id' => $userId,
            'content' => $content,
            'message_type' => $messageType,
            'metadata' => new \stdClass()
        ]);

        if (isset($msg['error'])) jsonError($msg['error']);
        jsonResponse(['message' => $msg[0] ?? $msg, 'success' => true]);
    }

    if ($action === 'invite-game') {
        $groupId = $input['group_id'] ?? '';
        $gameKey = $input['game_key'] ?? 'chess';
        $timeControl = $input['time_control'] ?? 'rapid_10_0';
        $requiredPlayers = intval($input['required_players'] ?? 2);

        if (!$groupId) jsonError('group_id required');
        if ($requiredPlayers < 2 || $requiredPlayers > 4) jsonError('required_players must be 2-4');

        // Verify membership
        $membership = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'eq.' . $userId,
            'limit' => 1
        ]);
        if (!is_array($membership) || isset($membership['error']) || empty($membership)) {
            jsonError('Not a member', 403);
        }

        $gameState = [
            'group_id' => $groupId,
            'group_invite' => true,
            'required_players' => $requiredPlayers,
            'accepted' => [$userId],
            'invited_at' => gmdate('c')
        ];

        if ($gameKey === 'ludo') {
            $match = $sdb->insert('ludo_matches', [
                'status' => 'waiting',
                'player_count' => $requiredPlayers,
                'game_state' => json_encode($gameState),
                'players' => json_encode([['id' => $userId, 'color' => 'red']])
            ]);
        } else {
            $match = $sdb->insert('matches', [
                'game_key' => $gameKey,
                'match_type' => 'friendly',
                'white_player_id' => $userId,
                'status' => 'waiting',
                'time_control' => $timeControl,
                'game_state' => json_encode($gameState),
                'is_rated' => false
            ]);
        }

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

        // Notify all group members
        $members = $sdb->get('group_members', [
            'group_id' => 'eq.' . $groupId,
            'user_id' => 'neq.' . $userId,
            'select' => 'user_id'
        ]);
        $group = $sdb->get('groups', ['id' => 'eq.' . $groupId, 'select' => 'name', 'limit' => 1]);
        $groupName = $group[0]['name'] ?? 'مجموعة';

        if (is_array($members) && !isset($members['error'])) {
            foreach ($members as $m) {
                $sdb->insert('notifications', [
                    'user_id' => $m['user_id'],
                    'type' => 'group_game',
                    'title' => 'دعوة لعب في ' . $groupName,
                    'title_ar' => 'دعوة لعب في ' . $groupName,
                    'body' => 'Game invite in ' . $groupName,
                    'data' => json_encode(['group_id' => $groupId, 'match_id' => $matchId, 'game_key' => $gameKey])
                ]);
            }
        }

        // Post system message in group chat
        $sdb->insert('chat_messages', [
            'channel_type' => 'group',
            'channel_id' => $groupId,
            'sender_id' => $userId,
            'content' => '__system:game_invite',
            'message_type' => 'system',
            'metadata' => json_encode(['game_key' => $gameKey, 'match_id' => $matchId, 'required_players' => $requiredPlayers])
        ]);

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

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

        $table = $gameKey === 'ludo' ? 'ludo_matches' : 'matches';
        $match = $sdb->get($table, ['id' => 'eq.' . $matchId, 'select' => '*', 'limit' => 1]);
        if (!is_array($match) || isset($match['error']) || empty($match)) {
            jsonError('Match not found');
        }
        $match = $match[0];
        if ($match['status'] !== 'waiting') jsonError('Game already started or expired');

        $gs = is_string($match['game_state']) ? json_decode($match['game_state'], true) : ($match['game_state'] ?? []);
        $accepted = $gs['accepted'] ?? [];
        $required = $gs['required_players'] ?? 2;

        if (in_array($userId, $accepted)) jsonError('Already accepted');
        $accepted[] = $userId;
        $gs['accepted'] = $accepted;

        if (count($accepted) >= $required) {
            // Game starts
            if ($gameKey === 'ludo') {
                $colors = ['red', 'blue', 'green', 'yellow'];
                $players = [];
                foreach ($accepted as $i => $pid) {
                    $players[] = ['id' => $pid, 'color' => $colors[$i] ?? 'red'];
                }
                $sdb->update($table, [
                    'status' => 'in_progress',
                    'game_state' => json_encode($gs),
                    'players' => json_encode($players),
                    'current_player_index' => 0,
                    'started_at' => gmdate('c')
                ], ['id' => 'eq.' . $matchId]);

                jsonResponse(['started' => true, 'match_id' => $matchId, 'player_index' => array_search($userId, $accepted)]);
            } else {
                // Chess/domino — 2 players
                $whiteId = $accepted[0];
                $blackId = $accepted[1];
                $initialTime = 600000;
                $tc = $match['time_control'] ?? 'rapid_10_0';
                if (strpos($tc, 'bullet') !== false) $initialTime = 60000;
                elseif (strpos($tc, 'blitz') !== false) $initialTime = 300000;

                $sdb->update($table, [
                    'status' => 'in_progress',
                    'white_player_id' => $whiteId,
                    'black_player_id' => $blackId,
                    'game_state' => json_encode($gs),
                    '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,
                    'started_at' => gmdate('c')
                ], ['id' => 'eq.' . $matchId]);

                $color = ($userId === $whiteId) ? 'w' : 'b';
                jsonResponse(['started' => true, 'match_id' => $matchId, 'color' => $color]);
            }
        } else {
            // Still waiting for more players
            $sdb->update($table, [
                'game_state' => json_encode($gs)
            ], ['id' => 'eq.' . $matchId]);

            jsonResponse(['started' => false, 'accepted_count' => count($accepted), 'required' => $required]);
        }
    }

    if ($action === 'decline-group-invite') {
        $matchId = $input['match_id'] ?? '';
        $gameKey = $input['game_key'] ?? 'chess';
        if (!$matchId) jsonError('match_id required');
        // No-op for now — just acknowledge
        jsonResponse(['success' => true]);
    }

    jsonError('Invalid action');
}

jsonError('Method not allowed', 405);
