extends Node3D

@onready var player: FPVController = $PlayerFPV
@onready var gift_box: Interactable = $GiftBox
@onready var system_unit: Node3D = $SystemUnit
@onready var note: Interactable = $SystemUnit/Note
@onready var flash_drive: Interactable = $Desk/FlashDrive
@onready var door: Interactable = $WallE/Door
@onready var father: Node3D = $FatherNPC

enum State { INTRO, EXPLORE_GIFT, INSIDE_GIFT, NOTE_READ, FATHER_FAREWELL, SEEK_DRIVE, ENDING }
var state: State = State.INTRO


func _ready() -> void:
	_hide_noise_items()
	_apply_textures()

	player.interactable_focused.connect(_on_player_focused)
	player.interactable_unfocused.connect(_on_player_unfocused)

	DialogManager.set_date_time(GameState.game_date, GameState.game_time)
	DialogManager.set_crosshair_visible(true)
	DialogManager.set_controls_hint("WASD ходить · мышь смотреть · ЛКМ взаимодействие · ESC меню · Q сохранить и выйти")


func _hide_noise_items() -> void:
	# Убираем только то что без модели выглядит как мусор.
	# Bookcase теперь Kenney модель — Shelf видим.
	for path in [
		"Sock1",
		"Sock2",
		"Desk/AdrenalineCan",
		"Desk/LaysWrapper",
		"WallN/Plant",
		"WallN/Cup",
	]:
		if has_node(path):
			get_node(path).visible = false

	# Если возвращаемся из кухни — пропускаем интро
	if GameState.act1_father_left:
		_setup_post_intro_state()
	else:
		await _play_intro()


func _apply_textures() -> void:
	var floor_mat: BaseMaterial3D = ($Floor/Mesh as MeshInstance3D).material_override
	TextureGen.apply_to_material(floor_mat, TextureGen.linoleum(), Vector3(8, 8, 8))

	var ceiling_mat: BaseMaterial3D = ($Ceiling/Mesh as MeshInstance3D).material_override
	TextureGen.apply_to_material(ceiling_mat, TextureGen.ceiling(), Vector3(6, 6, 6))

	for wall_path in ["WallN", "WallS", "WallE", "WallW"]:
		var wall_node: Node = get_node(wall_path)
		var wall_mat: BaseMaterial3D = (wall_node.get_node("Mesh") as MeshInstance3D).material_override
		TextureGen.apply_to_material(wall_mat, TextureGen.wallpaper(), Vector3(8, 5, 8))

	var carpet_mat: BaseMaterial3D = ($WallS/WallCarpet as MeshInstance3D).material_override
	TextureGen.apply_to_material(carpet_mat, TextureGen.wall_carpet(), Vector3(1, 1, 1))

	var blanket_mat: BaseMaterial3D = ($Bed/Blanket as MeshInstance3D).material_override
	TextureGen.apply_to_material(blanket_mat, TextureGen.blanket(), Vector3(2, 2, 2))

	var csgo_mat: BaseMaterial3D = ($WallN/PosterCSGO as MeshInstance3D).material_override
	TextureGen.apply_to_material(csgo_mat, TextureGen.poster_csgo(), Vector3(1, 1, 1))

	var morgen_mat: BaseMaterial3D = ($WallN/PosterMorgen as MeshInstance3D).material_override
	TextureGen.apply_to_material(morgen_mat, TextureGen.poster_morgen(), Vector3(1, 1, 1))

	var desk_mat: BaseMaterial3D = ($Desk/Mesh as MeshInstance3D).material_override
	TextureGen.apply_to_material(desk_mat, TextureGen.desk_white(), Vector3(2, 2, 2))

	var door_panel_mat: BaseMaterial3D = ($WallE/DoorPanel as MeshInstance3D).material_override
	TextureGen.apply_to_material(door_panel_mat, TextureGen.door(), Vector3(1, 1, 1))

	# Книги/носки/Adrenaline/Lay's скрыты в _hide_noise_items —
	# текстуры на них не применяем (они невидимы)


func _play_intro() -> void:
	system_unit.visible = false
	note.visible = false
	gift_box.set_interactable(false)
	flash_drive.set_interactable(false)
	door.set_interactable(false)

	DialogManager.set_objective("Распакуй подарок от бати")

	await get_tree().create_timer(0.8).timeout
	await DialogManager.say("ОТЕЦ", "Ну? Чё стоишь. Распаковывай давай. Сам собирал, между прочим — полночи не спал.")
	await DialogManager.think("Так… новый пека? Серьёзно? После моего динозавра?")

	state = State.EXPLORE_GIFT
	gift_box.set_interactable(true)


func _setup_post_intro_state() -> void:
	# Возвращение из кухни — отец уже ушёл
	system_unit.visible = true
	note.visible = false
	gift_box.visible = false
	gift_box.set_interactable(false)
	note.set_interactable(false)
	father.visible = false
	state = State.SEEK_DRIVE
	flash_drive.set_interactable(true)
	door.set_interactable(true)
	DialogManager.set_objective("Возьми флешку с Шиндовс")


func _on_player_focused(obj: Node) -> void:
	if obj.has_method("get_prompt"):
		DialogManager.set_prompt(obj.get_prompt())


func _on_player_unfocused() -> void:
	DialogManager.clear_prompt()


func _on_gift_interacted(_p: Node) -> void:
	if state != State.EXPLORE_GIFT:
		return
	state = State.NOTE_READ
	GameState.act1_gift_opened = true
	GameState.act1_note_read = true
	gift_box.set_interactable(false)
	note.set_interactable(false)
	DialogManager.clear_prompt()

	# Коробка съёживается в 0 (как будто открылась и пропала)
	var shrink: Tween = create_tween()
	shrink.tween_property(gift_box, "scale", Vector3.ZERO, 0.3)
	await shrink.finished
	gift_box.visible = false

	# Новый системник появляется на столе под монитором
	system_unit.visible = true
	note.visible = true
	DialogManager.set_objective("Прочитай записку")

	# Авто-цепочка реплик
	await DialogManager.think("Ого. Реально новый системник.")
	await DialogManager.think("Поставлю на стол — монитор-то старый остаётся, подключим.")
	await DialogManager.think("А это записка на нём…")
	await DialogManager.show_note("«Не сожги. Пароль от Wi-Fi на холодильнике. — Бать»")
	await DialogManager.think("Бать ну ты красавчик конечно.")

	state = State.FATHER_FAREWELL
	await DialogManager.say("ОТЕЦ", "Флешка с Шиндой на столе. Ставь сам, не маленький. Если запорешь — сам и переставляй.")

	await _walk_father_out()
	father.visible = false
	GameState.act1_father_left = true

	state = State.SEEK_DRIVE
	flash_drive.set_interactable(true)
	door.set_interactable(true)
	DialogManager.set_objective("Возьми флешку с Шиндовс")


func _on_note_interacted(_p: Node) -> void:
	# Auto-flow в _on_gift_interacted делает записку автоматически.
	# Эта callback оставлена для совместимости signal connections.
	pass


func _walk_father_out() -> void:
	# Отец — Kenney glb. Поворот на 180° (спиной к игроку, лицом к двери),
	# затем шагание с покачиванием тела (legs/arms внутри glb статичны
	# пока не подключим AnimationPlayer).

	# Поворот корпуса
	var turn_tween: Tween = create_tween()
	turn_tween.tween_property(father, "rotation:y", father.rotation.y + PI, 0.4)
	await turn_tween.finished

	# Шагание: короткий путь до двери (0.35м, остаётся в комнате)
	var initial_x: float = father.position.x
	var walk_duration: float = 1.4
	var walk_distance: float = 0.35
	var steps: int = 4

	var walk_tween: Tween = create_tween()
	walk_tween.set_parallel(true)
	walk_tween.tween_property(father, "position:x", initial_x + walk_distance, walk_duration)
	walk_tween.tween_method(
		func(t: float) -> void:
			father.position.y = abs(sin(t * PI * float(steps))) * 0.04,
		0.0, 1.0, walk_duration
	)
	await walk_tween.finished

	# Попробовать сыграть animation из glb если есть
	var anim_player: AnimationPlayer = father.find_child("AnimationPlayer", true, false) as AnimationPlayer
	if anim_player != null:
		anim_player.stop()


func _on_door_interacted(_p: Node) -> void:
	if state != State.SEEK_DRIVE:
		return
	SceneManager.go_kitchen()


func _on_drive_interacted(_p: Node) -> void:
	if state != State.SEEK_DRIVE:
		return
	state = State.ENDING
	GameState.act1_drive_taken = true
	flash_drive.set_interactable(false)
	door.set_interactable(false)
	DialogManager.clear_prompt()
	DialogManager.set_objective("")

	await DialogManager.think("Ну ладно. Андрюхино так Андрюхино. Поехали.")
	await DialogManager.say("СИСТЕМА", "Конец Акта 1. Запускаю Акт 2 — Установка Шиндовс…")
	GameState.game_time = "10:42"
	SceneManager.go_install()
