extends Node3D

const ROOM_COUNT := 8
const INTERACT_DISTANCE := 2.5

var _modifier: int = 0
var _roll_log: RichTextLabel
var _spore_mat: ShaderMaterial


func _ready() -> void:
	var args := OS.get_cmdline_args() + OS.get_cmdline_user_args()
	if OS.has_feature("dedicated_server") or "--server" in args:
		return
	var role: String = NetworkManager.players.get(NetworkManager.my_id, {}).get("role", "player")
	if role == "dm":
		return  # DM lädt tavern.tscn nur für Top-Down-Ansicht, kein PlayerController
	var room_index := SceneManager.pending_room_index
	_spawn_player(room_index)
	# Kamera-Transform-Broadcast alle 0.1s an DM-Peer
	var timer := Timer.new()
	timer.wait_time = 0.1
	timer.autostart = true
	timer.timeout.connect(_broadcast_camera_transform)
	add_child(timer)
	_setup_dice_ui()
	_setup_spore_overlay()


func _get_dm_peer_id() -> int:
	for peer_id in NetworkManager.players.keys():
		if NetworkManager.players[peer_id].get("role", "") == "dm":
			return peer_id
	return 0


func _broadcast_camera_transform() -> void:
	var dm_id := _get_dm_peer_id()
	if dm_id == 0:
		return
	var controller := get_node_or_null("PlayerController") as Node3D
	if controller == null:
		return
	var cam := controller.get_node_or_null("Camera3D") as Camera3D
	var pos: Vector3 = cam.global_position if cam != null else controller.global_position
	var rot: Vector3 = cam.global_rotation if cam != null else controller.global_rotation
	NetworkManager.sync_player_position.rpc_id(dm_id, NetworkManager.my_id, pos, rot)


func _spawn_player(room_index: int) -> void:
	var room_name := "Room%d" % (room_index % ROOM_COUNT + 1)
	var spawn := get_node("UpperFloor/%s/SpawnPoint" % room_name) as Marker3D
	if spawn == null:
		push_error("[Tavern] SpawnPoint nicht gefunden: %s" % room_name)
		return

	var controller := CharacterBody3D.new()
	controller.name = "PlayerController"
	controller.set_script(load("res://scripts/player_controller.gd"))

	var shape := CollisionShape3D.new()
	var capsule := CapsuleShape3D.new()
	capsule.radius = 0.3
	capsule.height = 1.8
	shape.shape = capsule
	shape.position = Vector3(0, 0.9, 0)
	controller.add_child(shape)

	var camera := Camera3D.new()
	camera.name = "Camera3D"
	camera.current = true
	camera.position = Vector3(0, 1.6, 0)
	controller.add_child(camera)

	var ray := RayCast3D.new()
	ray.name = "InteractRay"
	ray.target_position = Vector3(0, 0, -INTERACT_DISTANCE)
	ray.enabled = true
	camera.add_child(ray)

	add_child(controller)
	controller.global_position = spawn.global_position
	controller.global_rotation = spawn.global_rotation
	print("[Tavern] Spieler gespawnt in %s" % room_name)


func _setup_dice_ui() -> void:
	var canvas := CanvasLayer.new()
	canvas.name = "DiceUI"
	add_child(canvas)

	var panel := PanelContainer.new()
	panel.set_anchors_and_offsets_preset(Control.PRESET_BOTTOM_LEFT)
	panel.offset_top = -120
	panel.offset_right = 400
	canvas.add_child(panel)

	var vbox := VBoxContainer.new()
	panel.add_child(vbox)

	_roll_log = RichTextLabel.new()
	_roll_log.custom_minimum_size = Vector2(380, 60)
	_roll_log.bbcode_enabled = true
	vbox.add_child(_roll_log)

	var hbox := HBoxContainer.new()
	vbox.add_child(hbox)

	var roll_btn := Button.new()
	roll_btn.text = "d20 Würfeln"
	roll_btn.pressed.connect(_on_roll_pressed)
	hbox.add_child(roll_btn)

	var mod_label := Label.new()
	mod_label.text = "  Mod:"
	hbox.add_child(mod_label)

	var mod_display := Label.new()
	mod_display.text = "0"
	mod_display.custom_minimum_size = Vector2(30, 0)
	mod_display.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER

	var mod_minus := Button.new()
	mod_minus.text = "-"
	mod_minus.pressed.connect(func() -> void: _modifier -= 1; _update_mod_display(mod_display))
	hbox.add_child(mod_minus)

	hbox.add_child(mod_display)

	var mod_plus := Button.new()
	mod_plus.text = "+"
	mod_plus.pressed.connect(func() -> void: _modifier += 1; _update_mod_display(mod_display))
	hbox.add_child(mod_plus)

	NetworkManager.roll_received.connect(_on_roll_received)


func _update_mod_display(label: Label) -> void:
	label.text = "%+d" % _modifier if _modifier != 0 else "0"


func _on_roll_pressed() -> void:
	var d20 := randi() % 20 + 1
	NetworkManager.broadcast_roll.rpc_id(1, NetworkManager.my_id, d20, _modifier)


func _setup_spore_overlay() -> void:
	var canvas := CanvasLayer.new()
	canvas.name = "SporeOverlay"
	canvas.layer = 10
	add_child(canvas)

	var rect := ColorRect.new()
	rect.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
	rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
	_spore_mat = ShaderMaterial.new()
	_spore_mat.shader = load("res://shaders/spore_overlay.gdshader") as Shader
	rect.material = _spore_mat
	canvas.add_child(rect)

	NetworkManager.overlay_changed.connect(_on_overlay_changed)
	SporeLevel.level_changed.connect(_on_spore_level_changed)


func _on_overlay_changed(_overlay_name: String) -> void:
	_apply_spore_intensity()


func _on_spore_level_changed(_level: float) -> void:
	_apply_spore_intensity()


func _apply_spore_intensity() -> void:
	var overlay_name := GameState.get_overlay(NetworkManager.my_id)
	var intensity := SporeLevel.current_level if overlay_name == "spore_active" else 0.0
	_spore_mat.set_shader_parameter("intensity", intensity)


func _on_roll_received(roller_peer_id: int, player_name: String, d20_result: int, modifier: int, total: int) -> void:
	var mod_str := " %+d" % modifier if modifier != 0 else ""
	var line := "[b]%s[/b] würfelt %d%s = [b]%d[/b]" % [player_name, d20_result, mod_str, total]
	if d20_result == 20:
		line = "[color=gold]" + line + " ★ NAT 20![/color]"
	elif d20_result == 1:
		line = "[color=red]" + line + " ☠ NAT 1[/color]"
	_roll_log.append_text(line + "\n")
