## MapBrowserRPC — Client-Server RPC Bridge for Workshop Map Browser
##
## Autoload candidate (or child of NetworkManager) that provides ENet RPC
## methods for the workshop map browser system.
##
## ## Architecture
##
##   ┌──────────────┐   request_map_list()    ┌──────────────┐
##   │   Client     │ ──────────────────────► │   Server     │
##   │              │ ◄────────────────────── │              │
##   │              │   send_map_list()        │              │
##   │              │                          │              │
##   │              │   request_map_change()   │              │
##   │              │ ──────────────────────► │              │
##   └──────────────┘                          └──────────────┘
##
## ## Signals
##
##   map_list_received(map_list: Array) — emitted on client when map list arrives
##   map_change_requested(map_id: String, peer_id: int) — emitted on server
##     when a client requests a map change
##   map_vote_started(map_id: String) — emitted on server when vote begins
##
## ## Integration
##
##   Add as an autoload in project.godot:
##     MapBrowserRPC="*res://scripts/network/map_browser_rpc.gd"
##
##   Or add as a child of NetworkManager at runtime.
##
## ## RPC Visibility
##
##   - Server → Client:  send_map_list (authority, call_remote)
##   - Client → Server:  request_map_list (any_peer, call_remote)
##   - Client → Server:  request_map_change (any_peer, call_remote)
##
## =============================================================================

extends Node

# ---------------------------------------------------------------------------
# Signals
# ---------------------------------------------------------------------------

## Emitted on the client when the server sends the map list.
signal map_list_received(map_list: Array)

## Emitted on the server when a client requests a map change.
signal map_change_requested(map_id: String, peer_id: int)

## Emitted on the server when a map vote is initiated by a client request.
signal map_vote_started(map_id: String)

## Emitted on the client when the vote result is sent back.
signal map_vote_result(map_id: String, passed: bool, yes_count: int, no_count: int)

# ---------------------------------------------------------------------------
# RPC: Server → Client
# ---------------------------------------------------------------------------

## Server sends the serialized map list to a specific client.
## Called by server code after receiving request_map_list().
@rpc("authority", "call_remote", "reliable")
func send_map_list(map_list: Array) -> void:
	if multiplayer.is_server():
		return
	map_list_received.emit(map_list)
	print("[MapBrowserRPC] Received map list with %d maps" % map_list.size())

## Server broadcasts the final vote result to all clients.
@rpc("authority", "call_remote", "reliable")
func broadcast_vote_result(map_id: String, passed: bool, yes_count: int, no_count: int) -> void:
	if multiplayer.is_server():
		return
	map_vote_result.emit(map_id, passed, yes_count, no_count)
	print("[MapBrowserRPC] Vote result for %s: passed=%s (%d yes, %d no)" % [map_id, passed, yes_count, no_count])

# ---------------------------------------------------------------------------
# RPC: Client → Server
# ---------------------------------------------------------------------------

## Client requests the current map list from the server.
## The server should call send_map_list(peer_id, map_list) in response.
@rpc("any_peer", "call_remote", "reliable")
func request_map_list() -> void:
	if not multiplayer.is_server():
		return

	var peer_id: int = multiplayer.get_remote_sender_id()
	print("[MapBrowserRPC] Map list requested by peer %d" % peer_id)

	# Delegate to WorkshopBrowser if available
	var list: Array = []
	if WorkshopBrowser and WorkshopBrowser.has_method(&"get_map_list"):
		list = WorkshopBrowser.get_map_list()
	else:
		push_warning("[MapBrowserRPC] WorkshopBrowser singleton not available — returning empty list")

	# Send the map list back to the requesting client
	send_map_list.rpc_id(peer_id, list)

## Client requests a map change (initiates a vote or signals admin).
## Emits map_change_requested on the server for handling.
@rpc("any_peer", "call_remote", "reliable")
func request_map_change(map_id: String) -> void:
	if not multiplayer.is_server():
		return

	var peer_id: int = multiplayer.get_remote_sender_id()
	print("[MapBrowserRPC] Map change requested by peer %d: %s" % [peer_id, map_id])

	# Validate the map exists via WorkshopBrowser
	if WorkshopBrowser and WorkshopBrowser.has_method(&"has_map"):
		if not WorkshopBrowser.has_map(map_id):
			print("[MapBrowserRPC] Peer %d requested unknown map: %s" % [peer_id, map_id])
			return

	map_change_requested.emit(map_id, peer_id)
	map_vote_started.emit(map_id)
