@tool
extends VBoxContainer

# ─── State ────────────────────────────────────────────────────────────────────
var _mpq = null  # MPQManager

const LOCALES := ["ruRU", "enUS", "enGB", "deDE", "frFR", "esES", "esMX",
                  "koKR", "zhCN", "zhTW", "ptBR", "ptPT"]

# ─── UI nodes (created in _ready) ─────────────────────────────────────────────
var _client_path_edit: LineEdit
var _locale_option:    OptionButton
var _filter_edit:      LineEdit
var _output_edit:      LineEdit
var _open_btn:         Button
var _extract_btn:      Button
var _list_btn:         Button
var _status_label:     Label
var _file_list:        ItemList
var _archive_list:     ItemList
var _progress:         ProgressBar

# ─── Build UI ─────────────────────────────────────────────────────────────────
func _ready() -> void:
	size_flags_horizontal = Control.SIZE_EXPAND_FILL
	add_theme_constant_override("separation", 6)

	_add_title()
	_add_separator()
	_add_client_row()
	_add_locale_row()
	_open_btn = _add_button("Open Client Archives", _on_open_pressed)
	_add_separator()
	_add_label("Loaded archives (highest priority first):")
	_archive_list = _add_item_list(100)
	_add_separator()
	_add_filter_row()
	_add_output_row()
	var btns := HBoxContainer.new(); add_child(btns)
	_list_btn    = _add_button_to("List Files", btns, _on_list_pressed)
	_extract_btn = _add_button_to("Extract",    btns, _on_extract_pressed)
	_progress = ProgressBar.new(); _progress.visible = false; add_child(_progress)
	_add_label("Files matching filter:")
	_file_list = _add_item_list(0, true)  # expand vertically
	_status_label = _add_label("Ready.")

	_extract_btn.disabled = true
	_list_btn.disabled    = true


# ─── UI helpers ───────────────────────────────────────────────────────────────
func _add_title() -> void:
	var lbl := Label.new()
	lbl.text = "MPQ Extractor  (WoW 3.3.5a)"
	lbl.add_theme_font_size_override("font_size", 14)
	add_child(lbl)

func _add_separator() -> void:
	add_child(HSeparator.new())

func _add_label(text: String) -> Label:
	var lbl := Label.new(); lbl.text = text
	add_child(lbl); return lbl

func _add_item_list(min_height: int, expand := false) -> ItemList:
	var il := ItemList.new()
	if min_height > 0:
		il.custom_minimum_size = Vector2(0, min_height)
	if expand:
		il.size_flags_vertical = Control.SIZE_EXPAND_FILL
	add_child(il); return il

func _add_button(text: String, cb: Callable) -> Button:
	var btn := Button.new(); btn.text = text
	btn.pressed.connect(cb); add_child(btn); return btn

func _add_button_to(text: String, parent: Control, cb: Callable) -> Button:
	var btn := Button.new()
	btn.text = text
	btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	btn.pressed.connect(cb); parent.add_child(btn); return btn

func _add_row(label_text: String) -> HBoxContainer:
	var row := HBoxContainer.new(); add_child(row)
	var lbl := Label.new()
	lbl.text = label_text
	lbl.custom_minimum_size = Vector2(90, 0)
	row.add_child(lbl); return row

func _add_client_row() -> void:
	var row := _add_row("Client path")
	_client_path_edit = LineEdit.new()
	_client_path_edit.text = "res://sources"
	_client_path_edit.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	_client_path_edit.placeholder_text = "res://sources"
	row.add_child(_client_path_edit)

func _add_locale_row() -> void:
	var row := _add_row("Locale")
	_locale_option = OptionButton.new()
	_locale_option.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	for loc in LOCALES:
		_locale_option.add_item(loc)
	row.add_child(_locale_option)

func _add_filter_row() -> void:
	var row := _add_row("Filter")
	_filter_edit = LineEdit.new()
	_filter_edit.text = "*"
	_filter_edit.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	_filter_edit.placeholder_text = "DBFilesClient\\*.dbc"
	row.add_child(_filter_edit)

func _add_output_row() -> void:
	var row := _add_row("Output dir")
	_output_edit = LineEdit.new()
	_output_edit.text = "res://data/extracted"
	_output_edit.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	row.add_child(_output_edit)


# ─── Handlers ─────────────────────────────────────────────────────────────────
func _on_open_pressed() -> void:
	if not ClassDB.class_exists("MPQManager"):
		_set_status("ERROR: MPQManager не найден. Собери GDExtension (build.bat Release).")
		return

	if _mpq:
		_mpq.call("close")
	_mpq = ClassDB.instantiate("MPQManager")

	var client_path: String = ProjectSettings.globalize_path(_client_path_edit.text)
	var locale: String      = LOCALES[_locale_option.selected]

	_set_status("Opening archives…")
	var count: int = _mpq.call("open_client", client_path, locale)

	if count == 0:
		_set_status("ERROR: no archives opened. Check client path / locale.")
		_extract_btn.disabled = true
		_list_btn.disabled    = true
		return

	_archive_list.clear()
	var info_list: Array = _mpq.call("get_archive_info")
	for info in info_list:
		var lbl_text := "[%d] %s  (%d files)" % [
			info["priority"],
			(info["path"] as String).get_file(),
			info["file_count"]
		]
		_archive_list.add_item(lbl_text)

	_set_status("Opened %d archives. Locale: %s" % [count, locale])
	_extract_btn.disabled = false
	_list_btn.disabled    = false


func _on_list_pressed() -> void:
	if not _mpq: return
	_file_list.clear()
	_set_status("Listing files…")

	var filter: String            = _filter_edit.text if not _filter_edit.text.is_empty() else "*"
	var files: PackedStringArray  = _mpq.call("list_files", filter)
	for f in files:
		_file_list.add_item(f)
	_set_status("Found %d files matching '%s'" % [files.size(), filter])


func _on_extract_pressed() -> void:
	if not _mpq: return

	var filter: String     = _filter_edit.text if not _filter_edit.text.is_empty() else "*"
	var output_dir: String = ProjectSettings.globalize_path(_output_edit.text)

	_set_status("Extracting…")
	_progress.visible = true
	_progress.value   = 0

	var count: int = _mpq.call("extract_files", filter, output_dir)

	_progress.value   = 100
	_progress.visible = false
	_set_status("Extracted %d files → %s" % [count, output_dir])


# ─── Helpers ──────────────────────────────────────────────────────────────────
func _set_status(text: String) -> void:
	_status_label.text = text
	print("[MPQTool] ", text)
