extends Control

@onready var title_label: Label = $Center/Window/V/TitleBar/Title
@onready var body_label: RichTextLabel = $Center/Window/V/Body
@onready var input_field: LineEdit = $Center/Window/V/Input
@onready var input_hint: Label = $Center/Window/V/InputHint
@onready var btn_a: Button = $Center/Window/V/Buttons/BtnA
@onready var btn_b: Button = $Center/Window/V/Buttons/BtnB
@onready var error_label: Label = $Center/Window/V/ErrorLabel
@onready var checkbox_no_pwd: CheckBox = $Center/Window/V/CheckBoxNoPwd
@onready var tz_dropdown: OptionButton = $Center/Window/V/TimeZone
@onready var progress_bar: ProgressBar = $Center/Window/V/Progress
@onready var four_squares: Control = $FourSquares
@onready var welcome_screen: Control = $WelcomeScreen
@onready var welcome_text: Label = $WelcomeScreen/V/WelcomeText

enum Step { BOOT, LICENSE_INTRO, LICENSE_FULL, DISK, USERNAME, PASSWORD, TIMEZONE, INSTALLING, COMPLETE }
var current_step: Step = Step.BOOT
var license_read_clicked: bool = false

const BANNED_TITLES: Array[String] = ["повелитель", "владыка", "бог", "лорд", "царь", "хозяин"]
const BANNED_MAT: Array[String] = ["хуй", "пизд", "ебал", "ебан", "бля", "сук", "блять"]

const USERNAME_PLACEHOLDERS: Array[String] = [
	"bossiara13",
	"fr3sh_n3kit",
	"Vasyok_07",
	"neoLich",
	"Дима_за_рулём",
	"p1ano",
]

const TIMEZONES: Array[String] = [
	"UTC+2 (Калининград)",
	"UTC+3 (С., страна Р)",
	"UTC+4 (Самара)",
	"UTC+5 (Екатеринбург)",
	"UTC+7 (Новосибирск)",
	"UTC+9 (Иркутск)",
	"UTC+10 (Владивосток)",
]

const LICENSE_SHORT: String = "[center][b]Лицензионное соглашение Шиндовс 9[/b][/center]\n\nНажимая «Принять», Вы соглашаетесь с условиями использования операционной системы Шиндовс-Корп.\n\nДля просмотра полного текста нажмите «Читать»."

const LICENSE_FULL: String = "[center][b]Лицензионное соглашение Шиндовс 9 (полная версия)[/b][/center]\n\n[i]п. 1.1[/i]  Настоящее Лицензионное соглашение (далее — Соглашение) является обязывающим юридическим документом между Вами (далее — Пользователь) и корпорацией Шиндовс-Корп (далее — Корпорация).\n\n[i]п. 1.2[/i]  Установив, скопировав, загрузив или иным образом используя ПО Шиндовс 9, Пользователь подтверждает согласие с условиями настоящего Соглашения в полном объёме.\n\n[i]п. 1.3[/i]  Соглашение вступает в силу с момента нажатия кнопки «Принять» и действует бессрочно, либо до момента расторжения по инициативе Корпорации.\n\n[i]п. 2.1[/i]  Корпорация предоставляет Пользователю неисключительную, непередаваемую, отзываемую лицензию на использование ПО на одном персональном устройстве, принадлежащем Пользователю на законных основаниях.\n\n[i]п. 2.4[/i]  Пользователь не имеет права передавать, сдавать в аренду, продавать или иным образом распространять ПО третьим лицам без письменного согласия Корпорации.\n\n[i]п. 3.4[/i]  Запрещается дизассемблировать, декомпилировать, реверс-инжинирить или иным образом изучать внутреннюю работу ПО, кроме случаев, прямо разрешённых императивными нормами законодательства.\n\n[i]п. 3.7[/i]  Пользователь обязуется не использовать ПО для разработки конкурирующих программных продуктов в течение 99 лет с момента установки.\n\n[i]п. 4.2[/i]  Корпорация оставляет за собой право обновлять, модифицировать или прекращать поддержку ПО в любое время без предварительного уведомления Пользователя.\n\n[i]п. 4.5[/i]  В случае обновления Пользователь автоматически соглашается с любыми изменёнными условиями Соглашения, даже если такие изменения существенно ухудшают права Пользователя.\n\n[i]п. 5.1[/i]  ПО предоставляется «как есть» («AS IS»). Корпорация не предоставляет никаких гарантий, ни явных, ни подразумеваемых, включая, но не ограничиваясь, гарантиями пригодности для конкретной цели.\n\n[i]п. 5.3[/i]  Корпорация не несёт ответственности за любые прямые, косвенные, случайные, специальные или сопутствующие убытки, включая упущенную выгоду, потерю данных или деловой репутации.\n\n[i]п. 6.1[/i]  Пользователь обязуется не использовать ПО для деятельности, противоречащей действующему законодательству страны проживания Пользователя, либо страны нахождения серверов Корпорации.\n\n[i]п. 6.8[/i]  В случае нарушения условий Соглашения Корпорация вправе расторгнуть лицензию в одностороннем порядке без возврата уплаченных средств.\n\n[i]п. 7.3.2[/i]  Этот персональный компьютер, на который Вы устанавливаете ПО, формально остаётся собственностью корпорации Шиндовс-Корп до момента окончательной выплаты Вашей души (далее — Душа).\n\n[i]п. 8.2[/i]  Пользователь предоставляет Корпорации неисключительное право собирать, обрабатывать и хранить телеметрические данные о работе ПО на устройстве Пользователя.\n\n[i]п. 9.4[/i]  Корпорация не гарантирует совместимость ПО с оборудованием, выпущенным позднее даты выпуска ПО, либо ранее даты выпуска предыдущей версии ПО.\n\n[i]п. 10.1[/i]  Пользователь обязуется не предъявлять Корпорации никаких претензий за неудобства, вызванные обязательной перезагрузкой устройства в произвольное время.\n\n[i]п. 11.4[/i]  Корпорация оставляет за собой право в любой момент запустить процесс «svchost.exe» с приоритетом «realtime». Жалобы не принимаются.\n\n[i]п. 12.1[/i]  Все ваши скриншоты могут быть использованы в обучении ИИ, который заменит Вас на работе к 2027 году. Согласие подразумевается.\n\n[i]п. 13.6[/i]  Корпорация имеет право демонстрировать рекламу третьих лиц в любой части интерфейса ПО, включая, но не ограничиваясь, экраном блокировки, меню «Пуск», уведомлениями и обновлениями.\n\n[i]п. 14.2[/i]  В случае конфликта между настоящим Соглашением и любыми устными договорённостями преимущественную силу имеет настоящее Соглашение.\n\n[i]п. 15.7[/i]  Корпорация молча переустановит Защитник раз в сутки, если установлен сторонний антивирус.\n\n[i]п. 16.9[/i]  Пользователь признаёт, что любая попытка отключить телеметрию является нарушением Соглашения и может привести к блокировке учётной записи.\n\n[i]п. 18.0[/i]  Раз в год Ваш рабочий стол может быть перемещён в облако. Восстановление платное.\n\n[i]п. 19.3[/i]  Корпорация имеет право использовать вычислительные мощности устройства Пользователя для нужд распределённых вычислений в фоновом режиме.\n\n[i]п. 21.3[/i]  Корпорация не несёт ответственности за случаи, когда после обновления у Вас перестаёт работать звук, мышь или Wi-Fi. Это нормально. Перезагрузитесь.\n\n[i]п. 22.5[/i]  Споры, возникающие из настоящего Соглашения, подлежат разрешению в Арбитражном суде юрисдикции, выбранной Корпорацией по её усмотрению.\n\n[i]п. 23.9[/i]  Все приложения могут наблюдать друг за другом и отправлять телеметрию в Облако. Облако — это не место, а состояние ума.\n\n[i]п. 25.1[/i]  Корпорация оставляет за собой право в одностороннем порядке изменять, дополнять или удалять любые положения настоящего Соглашения без предварительного уведомления Пользователя.\n\n[i]п. 26.4[/i]  Если какое-либо положение настоящего Соглашения признано недействительным, остальные положения сохраняют полную силу. Недействительное положение заменяется аналогичным действительным.\n\n[i]п. 27.1[/i]  Нажав «Принять», Вы соглашаетесь не читать это соглашение. Если Вы дочитали до этого пункта — Вы нарушили условия. Закройте окно и попробуйте снова.\n\n[i]п. 28.0[/i]  Настоящее Соглашение составлено на русском языке и имеет преимущественную силу над любыми переводами на иные языки. В случае разночтений принимается русская версия. Спасибо за внимание."


func _ready() -> void:
	Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
	DialogManager.clear_prompt()
	DialogManager.set_controls_hint("")
	DialogManager.set_crosshair_visible(false)
	DialogManager.set_date_time(GameState.game_date, GameState.game_time)
	DialogManager.set_objective("Установи Шиндовс 9")

	welcome_screen.visible = false
	progress_bar.visible = false
	input_field.visible = false
	input_hint.visible = false
	checkbox_no_pwd.visible = false
	tz_dropdown.visible = false
	error_label.visible = false
	btn_a.pressed.connect(_on_btn_a)
	btn_b.pressed.connect(_on_btn_b)

	for tz in TIMEZONES:
		tz_dropdown.add_item(tz)
	tz_dropdown.select(1)  # UTC+3 по умолчанию

	# BOOT: 4 квадратика на 1.5 сек
	four_squares.visible = true
	await get_tree().create_timer(1.6).timeout
	four_squares.visible = false
	_to_license_intro()


func _set_body_compact() -> void:
	body_label.fit_content = true
	body_label.custom_minimum_size = Vector2(540, 0)


func _set_body_scrollable(min_h: int) -> void:
	body_label.fit_content = false
	body_label.custom_minimum_size = Vector2(540, min_h)
	body_label.scroll_to_line(0)


func _to_license_intro() -> void:
	current_step = Step.LICENSE_INTRO
	title_label.text = "Шиндовс 9 — Шаг 1 из 5"
	_set_body_compact()
	body_label.text = LICENSE_SHORT
	body_label.visible = true
	btn_a.text = "Принять"
	btn_a.visible = true
	btn_b.text = "Читать"
	btn_b.visible = true
	input_field.visible = false
	input_hint.visible = false
	checkbox_no_pwd.visible = false
	tz_dropdown.visible = false
	error_label.visible = false


func _to_license_full() -> void:
	current_step = Step.LICENSE_FULL
	license_read_clicked = true
	title_label.text = "Шиндовс 9 — Полный текст соглашения (прокрути колесом мыши)"
	_set_body_scrollable(220)
	body_label.text = LICENSE_FULL
	btn_a.text = "Принять"
	btn_a.visible = true
	btn_b.visible = false


func _to_disk() -> void:
	current_step = Step.DISK
	title_label.text = "Шиндовс 9 — Шаг 2 из 5"
	_set_body_compact()
	body_label.text = "[center][b]Выбор диска для установки[/b][/center]\n\n[•] Диск C:\\\\ (250 ГБ свободно)\n\nДругие диски не обнаружены."
	btn_a.text = "Далее"
	btn_a.visible = true
	btn_b.visible = false


func _to_username() -> void:
	current_step = Step.USERNAME
	title_label.text = "Шиндовс 9 — Шаг 3 из 5"
	_set_body_compact()
	body_label.text = "[center][b]Введите имя пользователя[/b][/center]\n\nЭто имя будет использоваться в системе. Минимум 2 символа, максимум 24. Только буквы и цифры."
	var rng: RandomNumberGenerator = RandomNumberGenerator.new()
	rng.randomize()
	input_field.placeholder_text = USERNAME_PLACEHOLDERS[rng.randi() % USERNAME_PLACEHOLDERS.size()]
	input_field.text = ""
	input_field.visible = true
	input_field.editable = true
	input_field.grab_focus()
	input_hint.text = "Например: bossiara13, fr3sh_n3kit, Vasyok_07, neoLich, КошкоПовелитель… ой, нет, этот нельзя"
	input_hint.visible = true
	error_label.visible = false
	btn_a.text = "Далее"
	btn_a.visible = true
	btn_b.visible = false


func _to_password() -> void:
	current_step = Step.PASSWORD
	title_label.text = "Шиндовс 9 — Шаг 4 из 5"
	_set_body_compact()
	body_label.text = "[center][b]Введите пароль[/b][/center]\n\nИли оставьте поле пустым / отметьте «Без пароля». Можно потом изменить в настройках."
	input_field.text = ""
	input_field.secret = true
	input_field.placeholder_text = "********"
	input_field.visible = true
	input_field.editable = true
	input_field.grab_focus()
	input_hint.text = "Совет: запиши себе на бумажку. Минимум 4 символа, если ставишь."
	input_hint.visible = true
	checkbox_no_pwd.visible = true
	checkbox_no_pwd.button_pressed = false
	error_label.visible = false
	btn_a.text = "Далее"
	btn_a.visible = true
	btn_b.visible = false


func _to_timezone() -> void:
	current_step = Step.TIMEZONE
	title_label.text = "Шиндовс 9 — Шаг 5 из 5"
	_set_body_compact()
	body_label.text = "[center][b]Выберите часовой пояс[/b][/center]\n\nЭто повлияет на время в системе. По умолчанию — UTC+3 (С., страна Р)."
	input_field.visible = false
	input_field.secret = false
	input_hint.visible = false
	checkbox_no_pwd.visible = false
	tz_dropdown.visible = true
	btn_a.text = "Готово"
	btn_a.visible = true
	btn_b.visible = false


func _to_installing() -> void:
	current_step = Step.INSTALLING
	title_label.text = "Шиндовс 9 — Установка"
	_set_body_compact()
	body_label.text = "[center]Подождите, пока система устанавливается.\nЭто займёт пару минут.[/center]"
	input_field.visible = false
	input_hint.visible = false
	checkbox_no_pwd.visible = false
	tz_dropdown.visible = false
	btn_a.visible = false
	btn_b.visible = false
	progress_bar.visible = true
	progress_bar.value = 0
	_run_install_progress()


func _run_install_progress() -> void:
	var stages: Array = [
		["Распаковка файлов…", 0.25],
		["Установка драйверов…", 0.5],
		["Настройка реестра…", 0.75],
		["Применение конфигурации…", 0.95],
		["Готово!", 1.0],
	]
	for stage in stages:
		body_label.text = "[center]" + stage[0] + "[/center]"
		var tween: Tween = create_tween()
		tween.tween_property(progress_bar, "value", stage[1] * 100.0, 0.6)
		await tween.finished
	await get_tree().create_timer(0.4).timeout
	_to_complete()


func _to_complete() -> void:
	current_step = Step.COMPLETE
	$Center.visible = false
	welcome_screen.visible = true
	welcome_text.text = "Добро пожаловать, %s." % GameState.player_name
	DialogManager.set_objective("")


func _on_btn_a() -> void:
	match current_step:
		Step.LICENSE_INTRO:
			if license_read_clicked:
				GameState.unlock_achievement("Юрист")
				GameState.unlock_achievement("Нарушитель ЛС")
			_to_disk()
		Step.LICENSE_FULL:
			GameState.unlock_achievement("Юрист")
			GameState.unlock_achievement("Нарушитель ЛС")
			_to_disk()
		Step.DISK:
			_to_username()
		Step.USERNAME:
			_validate_and_set_username()
		Step.PASSWORD:
			_validate_and_set_password()
		Step.TIMEZONE:
			GameState.act2_timezone = TIMEZONES[tz_dropdown.selected]
			_to_installing()


func _on_btn_b() -> void:
	match current_step:
		Step.LICENSE_INTRO:
			_to_license_full()


func _validate_and_set_username() -> void:
	var name: String = input_field.text.strip_edges()
	var result: Dictionary = _validate_name(name)
	if not result.get("valid", false):
		error_label.text = result.get("error", "Ошибка")
		error_label.visible = true
		return
	GameState.player_name = name
	_to_password()


func _validate_name(name: String) -> Dictionary:
	if name.length() < 2:
		return {"valid": false, "error": "Минимум 2 символа"}
	if name.length() > 24:
		return {"valid": false, "error": "Максимум 24 символа"}
	var re: RegEx = RegEx.new()
	re.compile("^[\\wа-яёА-ЯЁ_]+$")
	if not re.search(name):
		return {"valid": false, "error": "Только буквы, цифры и подчёркивания"}
	var lower: String = name.to_lower()
	for t in BANNED_TITLES:
		if t in lower:
			return {"valid": false, "error": "Без громких титулов, ок?"}
	for m in BANNED_MAT:
		if m in lower:
			return {"valid": false, "error": "Эээ, давай прилично"}
	return {"valid": true}


func _validate_and_set_password() -> void:
	if checkbox_no_pwd.button_pressed:
		GameState.act2_password_set = false
		GameState.unlock_achievement("Главное чтоб удобно")
		_to_timezone()
		return
	var pwd: String = input_field.text
	if pwd.is_empty() or pwd in ["123", "qwerty", "password", "1234"]:
		GameState.act2_password_set = false
		GameState.unlock_achievement("Главное чтоб удобно")
		_to_timezone()
		return
	if pwd.length() >= 12 and _has_special(pwd):
		GameState.unlock_achievement("Параноик")
	GameState.act2_password_set = true
	_to_timezone()


func _has_special(s: String) -> bool:
	var specials: String = "!@#$%^&*()-_+=<>?/.,"
	for c in s:
		if c in specials:
			return true
	return false


func _on_launch_steme() -> void:
	# Акт 3 пока не реализован — выходим
	GameState.unlock_achievement("Конец альфа-сессии")
	await DialogManager.say("СИСТЕМА", "Акт 3 (стеме Big Picture) — TBD в следующей итерации. Игрок: %s. Спасибо за тест!" % GameState.player_name)
	get_tree().quit()
