from __future__ import annotations

from typing import Final


DEFAULT_LANGUAGE = "en"

MESSAGE_CATALOGS: Final[dict[str, dict[str, str]]] = {
	"en": {
		"common.empty": "—",
		"common.ok": "OK",
		"common.fail": "FAIL",
		"common.yes": "yes",
		"common.no": "no",
		"common.running": "running",
		"common.stopped": "stopped",
		"common.loop": "loop",
		"common.tmux_session": "tmux: {session_name}",
		"common.unknown": "unknown",
		"common.manual_unknown": "manual / unknown",
		"common.apply": "Apply",
		"common.cancel": "Cancel",
		"common.close": "Close",
		"common.save": "Save",
		"common.open": "Open",
		"common.refresh": "Refresh",
		"common.quit": "Quit",
		"common.back": "Back",
		"common.create": "Create",
		"common.register": "Register",
		"common.change": "Change",
		"common.doctor": "Doctor",
		"common.attach": "Attach",
		"common.stop": "Stop",
		"common.kill": "Kill",
		"common.upgrade": "Upgrade",
		"common.start_stop": "Start/Stop",
		"common.default_server_name": "{core_name} Server",
		"common.manual_server_name": "Manual Server",
		"common.wait_current_operation": "Wait for the current operation to finish.",
		"common.error_prefix": "Error: {error}",
		"panel.info_title": "Info",
		"panel.error_title": "Error",
		"panel.success_title": "Success",
		"label.component": "Component",
		"label.status": "Status",
		"label.description": "Description",
		"label.name": "Name",
		"label.tag": "Tag",
		"label.core": "Core",
		"label.core_id": "Core ID",
		"label.core_version": "Core Version",
		"label.new_core": "New Core",
		"label.jar": "JAR",
		"label.path": "Path",
		"label.directory": "Directory",
		"label.server_directory": "Server Directory",
		"label.jar_path": "Path to JAR",
		"label.server": "Server",
		"label.action": "Action",
		"label.signal": "Signal",
		"label.pid": "PID",
		"label.server_pid": "Server PID",
		"label.uptime": "Uptime",
		"label.last_start": "Last Start",
		"label.last_stop": "Last Stop",
		"label.last_exit_code": "Last Exit Code",
		"label.current_selection": "Current Selection",
		"label.recent_activity": "Recent Activity",
		"label.server_snapshot": "Server Snapshot",
		"label.live_console": "Live Console",
		"label.servers": "Servers",
		"label.version": "Version",
		"label.field": "Field",
		"rich.gradient.missing": "rich-gradient is not installed. Install it with `uv add rich-gradient`.",
		"rich.gradient.empty": "Gradient must contain at least one color.",
		"config.validation.tag_empty": "Server tag must not be empty.",
		"config.validation.text_empty": "Server text fields must not be empty.",
		"config.server.not_found": "Server with tag '{tag}' was not found.",
		"downloads.unsupported_provider_type": "Unsupported core provider type '{type_name}' for '{core_id}'.",
		"maven.fetch_xml_http": "Failed to fetch XML from {url}: HTTP {status_code}",
		"maven.fetch_xml_error": "Failed to fetch XML from {url}: {error}",
		"maven.invalid_xml": "Invalid XML at {url}",
		"maven.versioning_missing": "Maven metadata is missing the versioning section.",
		"maven.latest_version_missing": "Failed to determine the latest core version.",
		"maven.snapshot_versioning_missing": "Snapshot metadata is missing the versioning section.",
		"maven.snapshot_classifier_missing": "Snapshot metadata does not contain a JAR with classifier '{classifier}'.",
		"maven.snapshot_version_missing": "Failed to determine the snapshot artifact version.",
		"maven.group_id_missing": "Core '{core_id}' is missing group_id.",
		"maven.artifact_id_missing": "Core '{core_id}' is missing artifact_id.",
		"maven.url_missing": "Core '{core_id}' is missing url.",
		"jenkins.artifacts_missing": "Jenkins did not return artifacts for core '{core_id}'.",
		"jenkins.fetch_json_http": "Failed to fetch JSON from {url}: HTTP {status_code}",
		"jenkins.fetch_json_error": "Failed to fetch JSON from {url}: {error}",
		"jenkins.invalid_json": "Invalid JSON at {url}",
		"jenkins.no_jar_artifacts": "No JAR artifacts were found in the Jenkins build.",
		"jenkins.classifier_missing": "No JAR with classifier '{classifier}' was found in the Jenkins build.",
		"jenkins.primary_jar_missing": "No primary JAR artifact was found in the Jenkins build.",
		"jenkins.url_missing": "Core '{core_id}' is missing url.",
		"github.assets_missing": "The GitHub release does not contain assets for core '{core_id}'.",
		"github.fetch_release_http": "Failed to fetch GitHub release from {url}: HTTP {status_code}",
		"github.fetch_release_error": "Failed to fetch GitHub release from {url}: {error}",
		"github.invalid_json": "Invalid JSON at {url}",
		"github.asset_missing": "No GitHub release asset matched pattern '{pattern}'.",
		"github.asset_ambiguous": "Pattern '{pattern}' is ambiguous: found {count} matches.",
		"github.invalid_url": "Invalid GitHub URL: '{url}'.",
		"tmux.not_found": "tmux was not found.",
		"tmux.send_keys_failed": "tmux send-keys failed.",
		"tmux.send_enter_failed": "tmux send-keys Enter failed.",
		"launcher.tmux_not_found": "tmux was not found in PATH. Run `nesk doctor`.",
		"doctor.tmux_missing": "tmux was not found. The TUI cannot launch attachable sessions.",
		"doctor.tmux_detected": "tmux detected",
		"doctor.component.tmux": "tmux",
		"doctor.component.java_runtime": "Java Runtime",
		"doctor.component.java_version": "Java Version",
		"doctor.java_missing": "Java was not found. Install Java 21+.",
		"doctor.unknown_version": "Unknown version",
		"doctor.java_too_old": "Version is too old: {version_line}. Java 21+ is required.",
		"doctor.source_ok": "200 OK",
		"doctor.source_name": "{core_name} Source",
		"manager.directory_missing": "Directory '{directory}' does not exist.",
		"manager.path_not_server_directory": "Path '{directory}' is not a server directory.",
		"manager.path_exists_not_directory": "Path '{directory}' already exists and is not a directory. Use --force to overwrite it.",
		"manager.directory_not_empty": "Directory '{directory}' is not empty. Use --force to overwrite it.",
		"manager.server_config_header": "# This file will be generated automatically when the server starts for the first time.\n",
		"manager.download_core_http": "Failed to download core '{core_name}': HTTP {status_code}",
		"manager.download_core_error": "Failed to download core '{core_name}': {error}",
		"manager.download_progress": "Downloading {core_name}",
		"manager.server_not_found_by_tag": "Server with tag '{tag}' was not found.",
		"manager.server_not_found_for_directory": "No server was found for directory '{directory}'. Pass --tag.",
		"manager.pid_not_owned": "PID {pid} does not belong to any LumiNESK server.",
		"manager.server_not_running": "Server '{tag}' is not running.",
		"manager.loop_controller_not_found": "Could not determine the loop controller process for server '{tag}'.",
		"manager.loop_waiting_force": "Server '{tag}' is in loop mode and currently waiting to restart. Use --force to stop it permanently.",
		"manager.manual_server_upgrade": "Server '{tag}' was registered manually. Use `change_core` instead of `upgrade_core`.",
		"manager.core_not_in_registry": "Core '{core_id}' was not found in the LumiNESK registry.",
		"manager.server_already_running": "Server '{tag}' is already running (PID {pid}).",
		"manager.java_not_in_path": "Java was not found in PATH. Run `nesk doctor`.",
		"manager.jar_not_found": "Core JAR was not found: '{jar_path}'. Recreate the server or download the core again.",
		"manager.launching_server": "[cyan]Starting[/] server [bold]{name}[/bold] ([cyan]{tag}[/cyan], PID {pid})",
		"manager.loop_restart": "[yellow]Server exited with code {exit_code}. Restarting in {delay} seconds.[/yellow]",
		"manager.tag_in_use": "Tag '{tag}' is already in use.",
		"manager.directory_already_registered": "Directory '{directory}' is already registered as server '{tag}'.",
		"manager.jar_must_be_inside_directory": "JAR '{jar_path}' must be inside server directory '{directory}'.",
		"manager.core_file_missing": "Core file '{jar_path}' does not exist.",
		"manager.path_not_file": "Path '{path}' is not a file.",
		"manager.file_not_jar": "File '{file_name}' is not a JAR archive.",
		"manager.server_must_be_stopped_for_core_change": "Server '{tag}' must be stopped before changing or upgrading the core.",
		"manager.using_cached_core": "[cyan]Using cached core[/] [bold]{core_name}[/bold] [dim]({version})[/dim]",
		"manager.pid_undefined": "Process PID is not defined.",
		"manager.process_missing": "Process with PID {pid} no longer exists.",
		"manager.signal_permission_denied": "Permission denied while sending a signal to process PID {pid}.",
		"cli.version.banner": "LumiNESK v{version} by Taskov1ch. License: GPL-3.0.",
		"cli.option.version": "Show the LumiNESK version.",
		"cli.command.doctor": "Run system diagnostics for Nukkit-compatible cores.",
		"cli.doctor.checking_requirements": "Checking system requirements...",
		"cli.doctor.checking_java": "Checking Java...",
		"cli.doctor.checking_tmux": "Checking tmux...",
		"cli.doctor.checking_sources": "Checking download sources...",
		"cli.doctor.critical_error": "[bold]Critical error![/]\nServer operations cannot continue.",
		"cli.doctor.success": "Diagnostics finished. No critical issues were found.",
		"cli.command.cores": "List available cores.",
		"cli.cores.title": "Available Cores",
		"cli.cores.tip": "\n[bold]Tip:[/] use [cyan]nesk doctor[/cyan] to verify repository availability.",
		"cli.command.tui": "Launch the LumiNESK text UI.",
		"cli.tui.textual_missing": "The TUI requires the [cyan]textual[/cyan] dependency. Reinstall LumiNESK with the full dependency set.",
		"cli.tui.tmux_missing": "tmux was not found. The TUI requires tmux to be installed.",
		"cli.command.create": "Create a new server.",
		"cli.create.option.name": "Server name (not MOTD).",
		"cli.create.option.directory": "Path to the directory where the server will be created.",
		"cli.create.option.core": "Core used to create the server.",
		"cli.create.option.tag": "LumiNESK server tag.",
		"cli.create.option.force": "Force overwrite the existing directory.",
		"cli.create.prompt.core": "Enter the core to use for server creation",
		"cli.create.prompt.name": "Enter the server name",
		"cli.create.prompt.tag": "Enter the server tag for quick access with `nesk start <tag>`",
		"cli.create.prompt.directory": "Enter the path to the directory where the server will be created",
		"cli.create.core_not_found": "Core [red]{core_id}[/red] was not found in the registry. Check available cores with `nesk cores`.",
		"cli.create.success_title": "[bold]Server created[/]",
		"cli.command.register": "Register an existing server that was created manually.",
		"cli.register.option.directory": "Path to the existing server directory.",
		"cli.register.option.jar": "Path to the core JAR inside the server directory.",
		"cli.register.option.name": "Server name.",
		"cli.register.option.tag": "LumiNESK server tag.",
		"cli.register.prompt.jar": "Enter the path to the core JAR inside the server directory",
		"cli.register.prompt.name": "Enter the server name",
		"cli.register.prompt.tag": "Enter the server tag for quick access with `nesk start <tag>`",
		"cli.register.success_title": "[bold]Server registered[/]",
		"cli.command.start": "Start a server.",
		"cli.start.option.loop": "Restart the server automatically when it stops.",
		"cli.start.option.tag": "Server tag.",
		"cli.command.upgrade_core": "Upgrade the server core to the latest available version.",
		"cli.upgrade.option.tag": "Server tag.",
		"cli.upgrade.success_title": "[bold]Core upgraded[/]",
		"cli.command.change_core": "Change the server core.",
		"cli.change.option.tag": "Server tag.",
		"cli.change.option.core": "New server core.",
		"cli.change.prompt.core": "Enter the new server core",
		"cli.change.success_title": "[bold]Core changed[/]",
		"cli.command.stop": "Gracefully stop a server by tag or PID.",
		"cli.stop.argument.target": "Server tag or server process PID.",
		"cli.stop.option.force": "Stop loop mode together with the server.",
		"cli.command.kill": "Force-kill a server by tag or PID.",
		"cli.kill.argument.target": "Server tag or server process PID.",
		"cli.kill.option.force": "Stop loop mode together with the server.",
		"cli.command.list": "List servers and their status.",
		"cli.list.option.tag": "Filter by tag.",
		"cli.list.option.status": "Filter by status: running or stopped.",
		"cli.list.option.core": "Filter by core.",
		"cli.list.no_servers": "No servers are registered yet. Use `nesk create`.",
		"cli.list.no_matches": "No servers matched the selected filters.",
		"cli.list.title": "LumiNESK Servers",
		"cli.version.only_version": "Show only the numeric version.",
		"cli.control.loop_warning": "Server [cyan]{tag}[/cyan] is running in loop mode. It will restart automatically. Use `--force` if you need to stop it permanently.",
		"cli.status.invalid": "Allowed values for --status: running, stopped.",
		"tui.app.title": "LumiNESK",
		"tui.app.subtitle": "TUI Mode",
		"tui.selection.empty": "No servers yet.\n\nCreate a new server or register an existing instance.",
		"tui.selection.title": "{name} [{tag}]",
		"tui.snapshot.unavailable": "This server page can no longer fetch runtime data.\nReturn to the home page and refresh the list.",
		"tui.doctor.summary": "OK: {ok_count}  FAIL: {fail_count}  critical_fail: {critical_fail}",
		"tui.log.read_failed": "Failed to read log: {error}",
		"tui.doctor.report_title": "Doctor Report",
		"tui.home.open_server": "Open Server",
		"tui.home.create_server": "Create Server",
		"tui.home.register_existing": "Register Existing",
		"tui.home.servers_table.last_start": "Last Start",
		"tui.server.command_placeholder": "Enter a command for the server and press Enter",
		"tui.server.log_meta": "{log_path}  |  encoding: UTF-8",
		"tui.server.log_meta_missing": "Log file not found yet. encoding: UTF-8",
		"tui.server.unavailable": "Server is unavailable.",
		"tui.server.commands_locked": "Commands are temporarily locked while another operation is running.",
		"tui.server.stopped_placeholder": "The server is stopped. Start it to send commands.",
		"tui.server.tmux_missing": "tmux session not found. Commands and console are unavailable.",
		"tui.app.started": "TUI started.",
		"tui.refresh.failed_status": "Failed to refresh server list: {error}",
		"tui.refresh.failed_log": "Server list refresh failed: {error}",
		"tui.doctor.home_only": "Doctor can only be started from the home screen.",
		"tui.doctor.running": "Running diagnostics...",
		"tui.create.home_only": "Server creation is only available from the home screen.",
		"tui.create.description": "Available cores: {core_ids}",
		"tui.create.title": "Create Server",
		"tui.register.home_only": "Server registration is only available from the home screen.",
		"tui.register.title": "Register Server",
		"tui.register.description": "The JAR must be inside the server directory.",
		"tui.kill.running": "Force-stopping server '{tag}'...",
		"tui.kill.complete": "killed",
		"tui.upgrade.running": "Upgrading server '{tag}' core...",
		"tui.change.title": "Change Core: {tag}",
		"tui.change.description": "Available cores: {core_ids}",
		"tui.attach.unavailable_status": "Attach is unavailable: the server is not running or the tmux session is missing.",
		"tui.attach.unavailable_log": "Attach for '{tag}' is unavailable: the server is off or the tmux session is missing.",
		"tui.attach.exit_log": "Shutting down TUI and attaching: {command}",
		"tui.log.runtime_missing": "Log unavailable: runtime data was not found.",
		"tui.log.not_created": "The log has not appeared yet. Start the server or wait for a file to be created in .luminesk/logs.",
		"tui.log.empty": "Log file is empty.",
		"tui.activity.empty": "Activity log is empty.",
		"tui.selection.required_status": "Select a server on the home screen.",
		"tui.selection.required_log": "This action requires a selected server.",
		"tui.server_page.required": "Open a dedicated server page first.",
		"tui.background.error_status": "Error: {error}",
		"tui.background.error_log": "Error: {error}",
		"tui.stop.running": "Stopping server '{tag}'...",
		"tui.stop.complete": "stopped",
		"tui.launch.not_found": "Server '{tag}' was not found.",
		"tui.launch.already_running": "Server '{tag}' is already running.",
		"tui.launch.failed_status": "Failed to start server: {error}",
		"tui.launch.failed_log": "Failed to start '{tag}': {error}",
		"tui.launch.mode.single": "single-shot",
		"tui.launch.mode.loop": "loop",
		"tui.launch.created_status": "tmux session '{session_name}' created ({mode}).",
		"tui.launch.created_log": "Server '{tag}' started in tmux session '{session_name}' (mode={mode}).",
		"tui.launch.attach_log": "Attach command: {command}",
		"tui.launch.log_path": "Launch log: {path}",
		"tui.create.cancelled": "Server creation was cancelled.",
		"tui.create.running": "Creating server '{tag}'...",
		"tui.register.cancelled": "Server registration was cancelled.",
		"tui.register.running": "Registering server '{tag}'...",
		"tui.change.cancelled": "Core change was cancelled.",
		"tui.change.running": "Changing server '{tag}' core to '{core_id}'...",
		"tui.core.not_found": "Core '{core_id}' was not found. Available: {core_ids}.",
		"tui.doctor.check_java": "Checking Java...",
		"tui.doctor.check_tmux_sources": "Checking tmux and download sources...",
		"tui.create.complete_status": "Server '{tag}' created.",
		"tui.create.complete_log": "Server '{tag}' created: core={core_id}, jar={jar_name}, path={path}",
		"tui.register.complete_status": "Server '{tag}' registered.",
		"tui.register.complete_log": "Server '{tag}' registered: core={core_id}, jar={jar_name}, path={path}",
		"tui.upgrade.complete_status": "Server '{tag}' core upgraded.",
		"tui.upgrade.complete_log": "Server '{tag}' upgraded to version {version}.",
		"tui.change.complete_status": "Server '{tag}' core changed to '{core_id}'.",
		"tui.change.complete_log": "Server '{tag}' now uses core '{core_id}' ({version}).",
		"tui.signal.complete_status": "Server '{tag}' {label}.",
		"tui.signal.complete_log": "Signal {signal_name} sent to server '{tag}' (server_pid={server_pid}).",
		"tui.doctor.complete_status": "Diagnostics complete. {summary}",
		"tui.doctor.complete_log": "[{status}] {name}: {message}",
		"tui.field.required": "Field '{label}' must not be empty.",
		"tui.command.server_not_running": "Server '{tag}' is not running. Command was not sent.",
		"tui.command.tmux_missing": "tmux session '{session_name}' was not found. Command was not sent.",
		"tui.command.failed_status": "Failed to send command: {error}",
		"tui.command.failed_log": "Failed to send command '{command}': {error}",
		"tui.command.sent_status": "Command sent to '{tag}': {command}",
		"tui.command.sent_log": "Console command: {command}",
	},
}

_current_language = DEFAULT_LANGUAGE


def normalize_language(language: str | None) -> str:
	if language is None:
		return DEFAULT_LANGUAGE

	normalized_language = language.strip().lower()
	if normalized_language in MESSAGE_CATALOGS:
		return normalized_language

	return DEFAULT_LANGUAGE


def set_language(language: str | None) -> str:
	global _current_language

	_current_language = normalize_language(language)
	return _current_language


def t(key: str, /, **kwargs: object) -> str:
	catalog = MESSAGE_CATALOGS.get(_current_language, MESSAGE_CATALOGS[DEFAULT_LANGUAGE])
	template = catalog.get(key) or MESSAGE_CATALOGS[DEFAULT_LANGUAGE].get(key)

	if template is None:
		raise KeyError(f"Unknown message key: {key}")

	if not kwargs:
		return template

	return template.format(**kwargs)
