type Locale = 'en' | 'zh-CN';

const LOCALE_STORAGE_KEY = 'nodewarden.locale';

const messages: Record<Locale, Record<string, string>> = {
  en: {
    nav_account_settings: "Account Settings",
    nav_admin_panel: "Admin Panel",
    nav_device_management: "Device Management",
    nav_my_vault: "My Vault",
    nav_sends: "Sends",
    nav_support_center: "Support Center",
    support_title: "Support Center",
    support_under_construction: "Under construction.",
    txt_access_count: "Access Count",
    txt_accessed_count_times: "Accessed {count} times",
    txt_actions: "Actions",
    txt_add: "Add",
    txt_add_field: "Add Field",
    txt_add_website: "Add Website",
    txt_added: "Added",
    txt_additional_options: "Additional Options",
    txt_address: "Address",
    txt_address_1: "Address 1",
    txt_address_2: "Address 2",
    txt_address_3: "Address 3",
    txt_all_device_authorizations_revoked: "All device authorizations revoked",
    txt_all_invites_deleted: "All invites deleted",
    txt_all_items: "All Items",
    txt_all_sends: "All Sends",
    txt_android: "Android",
    txt_are_you_sure_you_want_to_delete_count_selected_items: "Are you sure you want to delete {count} selected items?",
    txt_are_you_sure_you_want_to_delete_this_item: "Are you sure you want to delete this item?",
    txt_are_you_sure_you_want_to_log_out: "Are you sure you want to log out?",
    txt_authenticator_key: "Authenticator Key",
    txt_authorized_devices: "Authorized Devices",
    txt_auto_copy_link_after_save: "Auto copy link after save",
    txt_autofill_options: "Autofill Options",
    txt_back_to_login: "Back To Login",
    txt_ban: "Ban",
    txt_boolean: "Boolean",
    txt_brand: "Brand",
    txt_bulk_delete_failed: "Bulk delete failed",
    txt_bulk_delete_sends_failed: "Bulk delete sends failed",
    txt_bulk_move_failed: "Bulk move failed",
    txt_cancel: "Cancel",
    txt_card: "Card",
    txt_card_details: "Card Details",
    txt_cardholder_name: "Cardholder Name",
    txt_change_master_password: "Change Master Password",
    txt_change_password: "Change Password",
    txt_change_password_failed: "Change password failed",
    txt_checked: "Checked",
    txt_choose_destination_folder: "Choose destination folder.",
    txt_chrome_browser: "Chrome Browser",
    txt_chrome_extension: "Chrome Extension",
    txt_city_town: "City / Town",
    txt_code: "Code",
    txt_company: "Company",
    txt_configure_custom_field_values: "Configure custom field values.",
    txt_confirm: "Confirm",
    txt_confirm_master_password: "Confirm Master Password",
    txt_confirm_password: "Confirm Password",
    txt_copy: "Copy",
    txt_copy_code: "Copy Code",
    txt_copy_link: "Copy Link",
    txt_copy_secret: "Copy Secret",
    txt_country: "Country",
    txt_create: "Create",
    txt_create_account: "Create Account",
    txt_create_folder: "Create Folder",
    txt_create_folder_failed: "Create folder failed",
    txt_create_item_failed: "Create item failed",
    txt_create_send_failed: "Create send failed",
    txt_create_timed_invite: "Create Timed Invite",
    txt_created_value: "Created: {value}",
    txt_current_new_password_is_required: "Current/new password is required",
    txt_current_password: "Current Password",
    txt_custom_fields: "Custom Fields",
    txt_decrypt_failed: "(Decrypt failed)",
    txt_decrypt_failed_2: "Decrypt failed",
    txt_delete: "Delete",
    txt_delete_all: "Delete All",
    txt_delete_all_invite_codes_active_inactive: "Delete all invite codes (active/inactive)?",
    txt_delete_all_invites: "Delete all invites",
    txt_delete_item: "Delete Item",
    txt_delete_item_failed: "Delete item failed",
    txt_delete_selected: "Delete Selected",
    txt_delete_selected_items: "Delete Selected Items",
    txt_delete_send_failed: "Delete send failed",
    txt_delete_this_user_and_all_user_data: "Delete this user and all user data?",
    txt_delete_user: "Delete user",
    txt_deleted_selected_items: "Deleted selected items",
    txt_deleted_selected_sends: "Deleted selected sends",
    txt_deletion_date: "Deletion Date",
    txt_deletion_days: "Deletion Days",
    txt_device: "Device",
    txt_device_authorization_revoked: "Device authorization revoked",
    txt_device_management: "Device Management",
    txt_device_removed: "Device removed",
    txt_disable_this_send: "Disable this send",
    txt_disable_totp: "Disable TOTP",
    txt_disable_totp_failed: "Disable TOTP failed",
    txt_download: "Download",
    txt_download_failed: "Download failed",
    txt_edge_browser: "Edge Browser",
    txt_edge_extension: "Edge Extension",
    txt_edit: "Edit",
    txt_edit_send: "Edit Send",
    txt_email: "Email",
    txt_email_password_and_recovery_code_are_required: "Email, password and recovery code are required",
    txt_enable_totp: "Enable TOTP",
    txt_enable_totp_failed: "Enable TOTP failed",
    txt_enabled: "Enabled",
    txt_encrypted_file: "Encrypted File",
    txt_encrypted_file_2: "Encrypted file",
    txt_enter_a_folder_name: "Enter a folder name.",
    txt_enter_master_password_to_disable_two_step_verification: "Enter master password to disable two-step verification.",
    txt_enter_master_password_to_view_this_item: "Enter master password to view this item.",
    txt_expiration_date: "Expiration Date",
    txt_expiration_days_0_never: "Expiration Days (0 = never)",
    txt_expires_at: "Expires At",
    txt_expires_at_value: "Expires at: {value}",
    txt_expiry: "Expiry",
    txt_expiry_month: "Expiry Month",
    txt_expiry_year: "Expiry Year",
    txt_failed_to_open_send: "Failed to open send",
    txt_favorite: "Favorite",
    txt_favorites: "Favorites",
    txt_field: "Field",
    txt_field_label: "Field Label",
    txt_field_label_is_required: "Field label is required.",
    txt_field_type: "Field Type",
    txt_field_value: "Field Value",
    txt_file: "File",
    txt_file_name: "File Name",
    txt_file_send: "File Send",
    txt_file_size: "File Size",
    txt_fingerprint: "Fingerprint",
    txt_firefox_browser: "Firefox Browser",
    txt_firefox_extension: "Firefox Extension",
    txt_first_name: "First Name",
    txt_folder: "Folder",
    txt_folder_created: "Folder created",
    txt_folder_name: "Folder Name",
    txt_folder_name_is_required: "Folder name is required",
    txt_folders: "Folders",
    txt_hidden: "Hidden",
    txt_hide: "Hide",
    txt_identity: "Identity",
    txt_identity_details: "Identity Details",
    txt_ie_browser: "IE Browser",
    txt_invite_code_optional: "Invite Code (Optional)",
    txt_invite_created: "Invite created",
    txt_invite_revoked: "Invite revoked",
    txt_invite_validity_hours: "Invite validity (hours)",
    txt_invites: "Invites",
    txt_ios: "iOS",
    txt_item: "Item",
    txt_item_created: "Item created",
    txt_item_deleted: "Item deleted",
    txt_item_history: "Item History",
    txt_item_name_is_required: "Item name is required.",
    txt_item_updated: "Item updated",
    txt_last_edited_value: "Last edited: {value}",
    txt_last_name: "Last Name",
    txt_last_seen: "Last Seen",
    txt_license_number: "License Number",
    txt_link_copied: "Link copied",
    txt_linked: "Linked",
    txt_linux_desktop: "Linux Desktop",
    txt_loading: "Loading...",
    txt_loading_nodewarden: "Loading NodeWarden...",
    txt_jwt_warning_title: "Server Security Warning",
    txt_jwt_warning_subtitle: "JWT secret is not configured safely.",
    txt_jwt_title_missing: "JWT_SECRET is missing",
    txt_jwt_title_too_short: "JWT_SECRET is too short",
    txt_jwt_title_default: "JWT_SECRET is using the default value",
    txt_jwt_reason_missing: "JWT secret is missing.",
    txt_jwt_reason_default: "JWT secret is still the default/sample value.",
    txt_jwt_reason_too_short: "JWT secret is too short. Minimum length is {min}.",
    txt_jwt_how_to_fix_add: "How to add JWT_SECRET",
    txt_jwt_how_to_fix_replace: "How to replace JWT_SECRET",
    txt_jwt_add_step_1: "Use the 32-character generator below and copy a new key.",
    txt_jwt_add_step_2: "Cloudflare Dashboard -> Workers & Pages -> Your Service -> Settings -> Variables and Secrets, add JWT_SECRET.",
    txt_jwt_add_step_3: "Save and wait for redeploy, then refresh this page.",
    txt_jwt_replace_step_1: "Use the 32-character generator below and create a stronger key (minimum {min} characters).",
    txt_jwt_replace_step_2: "Cloudflare Dashboard -> Workers & Pages -> Your Service -> Settings -> Variables and Secrets, replace JWT_SECRET.",
    txt_jwt_replace_step_3: "Save and wait for redeploy, then refresh this page.",
    txt_how_to_fix: "How to fix",
    txt_jwt_fix_step_1: "Open your deployment environment variables.",
    txt_jwt_fix_step_2: "If your current key is not random enough, use the 32-character generator below.",
    txt_jwt_fix_step_3: "Cloudflare Dashboard -> Workers & Pages -> Your Service -> Settings -> Variables and Secrets, update JWT_SECRET.",
    txt_jwt_fix_step_4: "Save and wait for redeploy, then refresh this page to verify.",
    txt_random_secret_generator: "Random Secret Generator",
    txt_copied: "Copied",
    txt_log_in: "Log In",
    txt_log_out: "Log Out",
    txt_lock: "Lock",
    txt_login: "Login",
    txt_login_credentials: "Login Credentials",
    txt_login_failed: "Login failed",
    txt_login_success: "Login success",
    txt_macos_desktop: "macOS Desktop",
    txt_manage_authorized_devices_and_30_day_totp_trusted_sessions: "Manage authorized devices and 30-day TOTP trusted sessions.",
    txt_master_password: "Master Password",
    txt_master_password_changed_please_login_again: "Master password changed. Please login again.",
    txt_master_password_is_required: "Master password is required",
    txt_master_password_is_required_2: "Master password is required.",
    txt_master_password_must_be_at_least_12_chars: "Master password must be at least 12 chars",
    txt_master_password_reprompt: "Master password reprompt",
    txt_master_password_reprompt_2: "Master Password Reprompt",
    txt_max_access_count: "Max Access Count",
    txt_middle_name: "Middle Name",
    txt_move: "Move",
    txt_move_selected_items: "Move Selected Items",
    txt_moved_selected_items: "Moved selected items",
    txt_name: "Name",
    txt_name_is_required: "Name is required",
    txt_new_password: "New Password",
    txt_new_password_must_be_at_least_12_chars: "New password must be at least 12 chars",
    txt_new_passwords_do_not_match: "New passwords do not match",
    txt_new_send: "New Send",
    txt_next: "Next",
    txt_no: "No",
    txt_no_devices_found: "No devices found.",
    txt_no_folder: "No Folder",
    txt_no_items: "No items",
    txt_no_name: "(No Name)",
    txt_no_sends: "No sends",
    txt_nodewarden_send: "NodeWarden Send",
    txt_not_trusted: "Not trusted",
    txt_note: "Note",
    txt_notes: "Notes",
    txt_number: "Number",
    txt_open: "Open",
    txt_opera_browser: "Opera Browser",
    txt_opera_extension: "Opera Extension",
    txt_or: "or",
    txt_options: "Options",
    txt_passport_number: "Passport Number",
    txt_password: "Password",
    txt_password_is_already_verified: "Password is already verified.",
    txt_passwords_do_not_match: "Passwords do not match",
    txt_phone: "Phone",
    txt_please_input_email_and_password: "Please input email and password",
    txt_please_input_master_password: "Please input master password",
    txt_please_input_totp_code: "Please input TOTP code",
    txt_please_select_a_file: "Please select a file",
    txt_postal_code: "Postal Code",
    txt_prev: "Prev",
    txt_private_key: "Private Key",
    txt_profile: "Profile",
    txt_profile_unavailable: "Profile unavailable",
    txt_profile_updated: "Profile updated",
    txt_public_key: "Public Key",
    txt_recover_2fa_failed: "Recover 2FA failed",
    txt_recover_two_step_login: "Recover Two-step Login",
    txt_recovered_but_auto_login_failed_please_sign_in: "Recovered but auto-login failed, please sign in.",
    txt_recovery_code: "Recovery Code",
    txt_recovery_code_copied: "Recovery code copied",
    txt_recovery_code_is_empty: "Recovery code is empty",
    txt_recovery_code_loaded: "Recovery code loaded",
    txt_refresh: "Refresh",
    txt_refresh_in_seconds_s: "Refresh in {seconds}s",
    txt_regenerate: "Regenerate",
    txt_registration_succeeded_please_sign_in: "Registration succeeded. Please sign in.",
    txt_remove: "Remove",
    txt_remove_device: "Remove device",
    txt_remove_device_2: "Remove Device",
    txt_remove_device_name_and_clear_its_2fa_trust: "Remove device \"{name}\" and clear its 2FA trust?",
    txt_reveal: "Reveal",
    txt_revoke: "Revoke",
    txt_revoke_30_day_totp_trust_for_name: "Revoke 30-day TOTP trust for \"{name}\"?",
    txt_revoke_30_day_totp_trust_from_all_devices: "Revoke 30-day TOTP trust from all devices?",
    txt_revoke_all_trusted: "Revoke All Trusted",
    txt_revoke_all_trusted_devices: "Revoke all trusted devices",
    txt_revoke_device_authorization: "Revoke device authorization",
    txt_revoke_trust: "Revoke Trust",
    txt_role: "Role",
    txt_save: "Save",
    txt_save_profile: "Save Profile",
    txt_save_profile_failed: "Save profile failed",
    txt_search_sends: "Search sends...",
    txt_search_your_secure_vault: "Search your secure vault...",
    txt_secret_and_code_are_required: "Secret and code are required",
    txt_secret_copied: "Secret copied",
    txt_secure_note: "Secure Note",
    txt_security_code: "Security Code",
    txt_security_code_cvv: "Security Code (CVV)",
    txt_select_all: "Select All",
    txt_select_an_item: "Select an item",
    txt_send_created: "Send created",
    txt_send_deleted: "Send deleted",
    txt_send_details: "Send Details",
    txt_send_file: "send-file",
    txt_send_unavailable: "Send unavailable.",
    txt_send_updated: "Send updated",
    txt_sign_out: "Sign Out",
    txt_ssh_key: "SSH Key",
    txt_ssn: "SSN",
    txt_state_province: "State / Province",
    txt_status: "Status",
    txt_submit: "Submit",
    txt_sync: "Sync",
    txt_sync_vault: "Sync Vault",
    txt_dash: "-",
    txt_text: "Text",
    txt_text_2fa_recovered: "2FA recovered",
    txt_text_2fa_recovered_new_recovery_code_code: "2FA recovered. New recovery code: {code}",
    txt_text_3: "------",
    txt_text_is_required: "Text is required",
    txt_text_send: "Text Send",
    txt_this_is_a_one_time_code_after_it_is_used_a_new_code_is_generated_automatically: "This is a one-time code. After it is used, a new code is generated automatically.",
    txt_this_item_requires_master_password_every_time_before_viewing_details: "This item requires master password every time before viewing details.",
    txt_this_link_is_missing_decryption_key: "This link is missing decryption key.",
    txt_this_send_is_password_protected: "This send is password protected.",
    txt_title: "Title",
    txt_totp: "TOTP",
    txt_totp_code: "TOTP Code",
    txt_totp_disabled: "TOTP disabled",
    txt_totp_enabled: "TOTP enabled",
    txt_totp_is_enabled_for_this_account: "TOTP is enabled for this account.",
    txt_totp_secret: "TOTP Secret",
    txt_totp_verify_failed: "TOTP verify failed",
    txt_trash: "Trash",
    txt_trust_this_device_for_30_days: "Trust this device for 30 days",
    txt_trusted_until: "Trusted Until",
    txt_two_step_verification: "Two-step verification",
    txt_type: "Type",
    txt_type_type: "Type {type}",
    txt_unban: "Unban",
    txt_unchecked: "Unchecked",
    txt_unknown_device: "Unknown device",
    txt_unlock: "Unlock",
    txt_unlock_details: "Unlock Details",
    txt_unlock_failed: "Unlock failed",
    txt_unlock_failed_master_password_is_incorrect: "Unlock failed. Master password is incorrect.",
    txt_unlock_item: "Unlock Item",
    txt_unlock_send: "Unlock Send",
    txt_unlock_vault: "Unlock Vault",
    txt_unlocked: "Unlocked",
    txt_update_item_failed: "Update item failed",
    txt_update_send_failed: "Update send failed",
    txt_use_recovery_code: "Use Recovery Code",
    txt_use_your_one_time_recovery_code_to_disable_two_step_verification: "Use your one-time recovery code to disable two-step verification.",
    txt_user_deleted: "User deleted",
    txt_user_status_updated: "User status updated",
    txt_username: "Username",
    txt_users: "Users",
    txt_vault_synced: "Vault synced",
    txt_verification_code: "Verification Code",
    txt_verify: "Verify",
    txt_view_recovery_code: "View Recovery Code",
    txt_web: "Web",
    txt_website: "Website",
    txt_websites: "Websites",
    txt_windows_desktop: "Windows Desktop",
    txt_yes: "Yes",
  },
  'zh-CN': {},
};

const zhCNOverrides: Record<string, string> = {
  nav_my_vault: '我的保险库',
  nav_sends: 'Send',
  nav_admin_panel: '管理面板',
  nav_account_settings: '账户设置',
  nav_device_management: '设备管理',
  nav_support_center: '支持中心',
  support_title: '支持中心',
  support_under_construction: '正在搭建中',
  txt_sign_out: '退出登录',
  txt_log_in: '登录',
  txt_log_out: '退出',
  txt_create_account: '创建账户',
  txt_back_to_login: '返回登录',
  txt_unlock: '解锁',
  txt_unlock_vault: '解锁保险库',
  txt_master_password: '主密码',
  txt_email: '邮箱',
  txt_name: '名称',
  txt_password: '密码',
  txt_confirm_password: '确认密码',
  txt_confirm_master_password: '确认主密码',
  txt_submit: '提交',
  txt_cancel: '取消',
  txt_yes: '是',
  txt_no: '否',
  txt_loading: '加载中...',
  txt_loading_nodewarden: '正在加载 NodeWarden...',
  txt_search_sends: '搜索发送...',
  txt_search_your_secure_vault: '搜索你的保险库...',
  txt_refresh: '刷新',
  txt_sync: '同步',
  txt_sync_vault: '同步',
  txt_add: '新增',
  txt_edit: '编辑',
  txt_delete: '删除',
  txt_save: '保存',
  txt_confirm: '确认',
  txt_move: '移动',
  txt_copy: '复制',
  txt_copy_link: '复制链接',
  txt_select_all: '全选',
  txt_delete_selected: '删除所选',
  txt_all_items: '所有项目',
  txt_favorites: '收藏',
  txt_trash: '回收站',
  txt_folder: '文件夹',
  txt_folders: '文件夹',
  txt_no_folder: '无文件夹',
  txt_no_items: '没有项目',
  txt_no_sends: '没有发送',
  txt_select_an_item: '请选择一个项目',
  txt_login: '登录',
  txt_card: '银行卡',
  txt_identity: '身份',
  txt_note: '笔记',
  txt_secure_note: '安全笔记',
  txt_ssh_key: 'SSH 密钥',
  txt_login_credentials: '登录信息',
  txt_card_details: '银行卡详情',
  txt_identity_details: '身份详情',
  txt_autofill_options: '自动填充选项',
  txt_additional_options: '附加选项',
  txt_custom_fields: '自定义字段',
  txt_notes: '备注',
  txt_item_history: '项目历史',
  txt_last_edited_value: '最后编辑：{value}',
  txt_created_value: '创建于：{value}',
  txt_username: '用户名',
  txt_website: '网站',
  txt_websites: '网站',
  txt_open: '打开',
  txt_hide: '隐藏',
  txt_reveal: '显示',
  txt_favorite: '收藏',
  txt_field: '字段',
  txt_field_type: '字段类型',
  txt_field_label: '字段标签',
  txt_field_value: '字段值',
  txt_add_field: '添加字段',
  txt_remove: '移除',
  txt_enabled: '已启用',
  txt_checked: '已勾选',
  txt_unchecked: '未勾选',
  txt_profile: '资料',
  txt_save_profile: '保存资料',
  txt_change_master_password: '修改主密码',
  txt_current_password: '当前密码',
  txt_new_password: '新密码',
  txt_change_password: '修改密码',
  txt_totp: 'TOTP',
  txt_enable_totp: '启用 TOTP',
  txt_disable_totp: '停用 TOTP',
  txt_totp_code: 'TOTP 验证码',
  txt_totp_secret: 'TOTP 密钥',
  txt_verification_code: '验证码',
  txt_recovery_code: '恢复代码',
  txt_view_recovery_code: '查看恢复代码',
  txt_copy_code: '复制代码',
  txt_device_management: '设备管理',
  txt_authorized_devices: '已授权设备',
  txt_device: '设备',
  txt_last_seen: '最后在线',
  txt_trusted_until: '信任至',
  txt_revoke_trust: '撤销信任',
  txt_remove_device_2: '移除设备',
  txt_not_trusted: '未信任',
  txt_unknown_device: '未知设备',
  txt_users: '用户',
  txt_invites: '邀请码',
  txt_ban: '封禁',
  txt_unban: '解封',
  txt_create_timed_invite: '创建时效邀请码',
  txt_invite_validity_hours: '邀请码有效期（小时）',
  txt_delete_all: '全部删除',
  txt_prev: '上一页',
  txt_next: '下一页',
  txt_send_details: '发送详情',
  txt_new_send: '新建发送',
  txt_edit_send: '编辑发送',
  txt_file_send: '文件发送',
  txt_text_send: '文本发送',
  txt_file: '文件',
  txt_text: '文本',
  txt_file_name: '文件名',
  txt_file_size: '文件大小',
  txt_access_count: '访问次数',
  txt_deletion_date: '删除日期',
  txt_expiration_date: '过期日期',
  txt_deletion_days: '删除天数',
  txt_expiration_days_0_never: '过期天数（0 表示不过期）',
  txt_max_access_count: '最大访问次数',
  txt_options: '选项',
  txt_disable_this_send: '禁用此发送',
  txt_auto_copy_link_after_save: '保存后自动复制链接',
  txt_unlock_send: '解锁发送',
  txt_nodewarden_send: 'NodeWarden 发送',
  txt_send_unavailable: '发送不可用。',
  txt_download: '下载',
  txt_expires_at: '过期时间',
  txt_expires_at_value: '过期于：{value}',
  txt_dash: '-',
  txt_or: '或',
  txt_no_name: '（无名称）',
  txt_are_you_sure_you_want_to_log_out: '确认要退出登录吗？',
  txt_delete_item: '删除项目',
  txt_delete_selected_items: '删除所选项目',
  txt_move_selected_items: '移动所选项目',
  txt_create_folder: '创建文件夹',
  txt_folder_name: '文件夹名称',
  txt_unlock_item: '解锁项目',
  txt_use_recovery_code: '使用恢复代码',
  txt_two_step_verification: '两步验证',
  txt_recover_two_step_login: '恢复两步登录',
  txt_title: '称谓',
  txt_first_name: '名',
  txt_middle_name: '中间名',
  txt_last_name: '姓',
  txt_company: '公司',
  txt_ssn: '社保号',
  txt_passport_number: '护照号',
  txt_license_number: '证件号',
  txt_private_key: '私钥',
  txt_public_key: '公钥',
  txt_fingerprint: '指纹',
  txt_master_password_reprompt: '主密码二次确认',
  txt_master_password_reprompt_2: '主密码二次确认',
  txt_configure_custom_field_values: '配置自定义字段值。',
  txt_hidden: '隐藏',
  txt_boolean: '布尔',
  txt_regenerate: '重新生成',
  txt_copy_secret: '复制密钥',
  txt_this_is_a_one_time_code_after_it_is_used_a_new_code_is_generated_automatically: '这是一次性恢复代码，使用后将自动生成新的恢复代码。',
  txt_manage_authorized_devices_and_30_day_totp_trusted_sessions: '管理已授权设备和 30 天 TOTP 受信会话。',
  txt_role: '角色',
  txt_status: '状态',
  txt_actions: '操作',
  txt_type: '类型',
  txt_revoke_all_trusted: '撤销全部受信任设备',
  txt_revoke_all_trusted_devices: '撤销所有受信任设备',
  txt_revoke_30_day_totp_trust_from_all_devices: '确认撤销所有设备的 30 天 TOTP 信任吗？',
  txt_revoke_30_day_totp_trust_for_name: '确认撤销“{name}”的 30 天 TOTP 信任吗？',
  txt_remove_device_name_and_clear_its_2fa_trust: '确认移除设备“{name}”并清除其 2FA 信任吗？',
  txt_role_admin: '管理员',
  txt_role_user: '用户',
  txt_status_active: '正常',
  txt_status_banned: '已封禁',
  txt_status_inactive: '未激活',
  txt_accessed_count_times: '已访问 {count} 次',
  txt_add_website: '添加网站',
  txt_added: '已添加',
  txt_address: '地址',
  txt_address_1: '地址 1',
  txt_address_2: '地址 2',
  txt_address_3: '地址 3',
  txt_all_device_authorizations_revoked: '已撤销所有设备授权',
  txt_all_invites_deleted: '已删除所有邀请码',
  txt_all_sends: '所有发送',
  txt_android: '安卓',
  txt_are_you_sure_you_want_to_delete_count_selected_items: '确认删除所选的 {count} 个项目？',
  txt_are_you_sure_you_want_to_delete_this_item: '确认删除此项目？',
  txt_authenticator_key: '验证器密钥',
  txt_brand: '品牌',
  txt_bulk_delete_failed: '批量删除失败',
  txt_bulk_delete_sends_failed: '批量删除发送失败',
  txt_bulk_move_failed: '批量移动失败',
  txt_cardholder_name: '持卡人姓名',
  txt_change_password_failed: '修改密码失败',
  txt_choose_destination_folder: '选择目标文件夹。',
  txt_chrome_browser: 'Chrome 浏览器',
  txt_chrome_extension: 'Chrome 扩展',
  txt_city_town: '城市 / 城镇',
  txt_code: '代码',
  txt_country: '国家',
  txt_create: '创建',
  txt_create_folder_failed: '创建文件夹失败',
  txt_create_item_failed: '创建项目失败',
  txt_create_send_failed: '创建发送失败',
  txt_current_new_password_is_required: '需要输入当前密码和新密码',
  txt_decrypt_failed: '（解密失败）',
  txt_decrypt_failed_2: '解密失败',
  txt_delete_all_invite_codes_active_inactive: '删除所有邀请码（有效/无效）？',
  txt_delete_all_invites: '删除所有邀请码',
  txt_delete_item_failed: '删除项目失败',
  txt_delete_send_failed: '删除发送失败',
  txt_delete_this_user_and_all_user_data: '删除此用户及其所有数据？',
  txt_delete_user: '删除用户',
  txt_deleted_selected_items: '已删除所选项目',
  txt_deleted_selected_sends: '已删除所选发送',
  txt_device_authorization_revoked: '已撤销设备授权',
  txt_device_removed: '设备已移除',
  txt_disable_totp_failed: '禁用 TOTP 失败',
  txt_download_failed: '下载失败',
  txt_edge_browser: 'Edge 浏览器',
  txt_edge_extension: 'Edge 扩展',
  txt_email_password_and_recovery_code_are_required: '需要输入邮箱、密码和恢复代码',
  txt_enable_totp_failed: '启用 TOTP 失败',
  txt_encrypted_file: '加密文件',
  txt_encrypted_file_2: '加密文件',
  txt_enter_a_folder_name: '请输入文件夹名称',
  txt_enter_master_password_to_disable_two_step_verification: '输入主密码以禁用两步验证',
  txt_enter_master_password_to_view_this_item: '输入主密码以查看此项目',
  txt_expiry: '有效期',
  txt_expiry_month: '有效期月',
  txt_expiry_year: '有效期年',
  txt_failed_to_open_send: '打开发送失败',
  txt_field_label_is_required: '字段标签不能为空',
  txt_firefox_browser: 'Firefox 浏览器',
  txt_firefox_extension: 'Firefox 扩展',
  txt_folder_created: '文件夹已创建',
  txt_folder_name_is_required: '文件夹名称不能为空',
  txt_ie_browser: 'IE 浏览器',
  txt_invite_code_optional: '邀请码（可选）',
  txt_invite_created: '邀请码已创建',
  txt_invite_revoked: '邀请码已撤销',
  txt_ios: 'iOS',
  txt_item: '项目',
  txt_item_created: '项目已创建',
  txt_item_deleted: '项目已删除',
  txt_item_name_is_required: '项目名称不能为空',
  txt_item_updated: '项目已更新',
  txt_link_copied: '链接已复制',
  txt_linked: '已关联',
  txt_linux_desktop: 'Linux 桌面端',
  txt_login_failed: '登录失败',
  txt_login_success: '登录成功',
  txt_macos_desktop: 'macOS 桌面端',
  txt_master_password_changed_please_login_again: '主密码已修改，请重新登录',
  txt_master_password_is_required: '主密码不能为空',
  txt_master_password_is_required_2: '请输入主密码',
  txt_master_password_must_be_at_least_12_chars: '主密码至少需要 12 个字符',
  txt_moved_selected_items: '已移动所选项目',
  txt_name_is_required: '名称不能为空',
  txt_new_password_must_be_at_least_12_chars: '新密码至少需要 12 个字符',
  txt_new_passwords_do_not_match: '两次输入的新密码不一致',
  txt_no_devices_found: '未找到设备',
  txt_number: '数字',
  txt_opera_browser: 'Opera 浏览器',
  txt_opera_extension: 'Opera 扩展',
  txt_password_is_already_verified: '密码已验证',
  txt_passwords_do_not_match: '两次输入的密码不一致',
  txt_phone: '电话',
  txt_please_input_email_and_password: '请输入邮箱和密码',
  txt_please_input_master_password: '请输入主密码',
  txt_please_input_totp_code: '请输入 TOTP 验证码',
  txt_please_select_a_file: '请选择文件',
  txt_postal_code: '邮政编码',
  txt_profile_unavailable: '资料不可用',
  txt_profile_updated: '资料已更新',
  txt_recover_2fa_failed: '恢复 2FA 失败',
  txt_recovered_but_auto_login_failed_please_sign_in: '已恢复，但自动登录失败，请手动登录',
  txt_recovery_code_copied: '恢复代码已复制',
  txt_recovery_code_is_empty: '恢复代码为空',
  txt_recovery_code_loaded: '恢复代码已加载',
  txt_refresh_in_seconds_s: '{seconds} 秒后刷新',
  txt_registration_succeeded_please_sign_in: '注册成功，请登录',
  txt_remove_device: '移除设备',
  txt_revoke: '撤销',
  txt_revoke_device_authorization: '撤销设备授权',
  txt_save_profile_failed: '保存资料失败',
  txt_secret_and_code_are_required: '密钥和代码不能为空',
  txt_secret_copied: '密钥已复制',
  txt_security_code: '安全码',
  txt_security_code_cvv: '安全码 (CVV)',
  txt_send_created: '发送已创建',
  txt_send_deleted: '发送已删除',
  txt_send_file: '发送文件',
  txt_send_updated: '发送已更新',
  txt_state_province: '省 / 州',
  txt_text_2fa_recovered: '2FA 已恢复',
  txt_text_2fa_recovered_new_recovery_code_code: '2FA 已恢复，新的恢复代码：{code}',
  txt_text_3: '------',
  txt_text_is_required: '文本不能为空',
  txt_this_item_requires_master_password_every_time_before_viewing_details: '每次查看详情前均需输入主密码',
  txt_this_link_is_missing_decryption_key: '此链接缺少解密密钥',
  txt_this_send_is_password_protected: '此发送受密码保护',
  txt_totp_disabled: 'TOTP 已禁用',
  txt_totp_enabled: 'TOTP 已启用',
  txt_totp_is_enabled_for_this_account: '此账户已启用 TOTP。',
  txt_totp_verify_failed: 'TOTP 验证失败',
  txt_trust_this_device_for_30_days: '信任此设备 30 天',
  txt_type_type: '类型 {type}',
  txt_unlock_details: '解锁详情',
  txt_unlock_failed: '解锁失败',
  txt_unlock_failed_master_password_is_incorrect: '解锁失败，主密码不正确。',
  txt_unlocked: '已解锁',
  txt_update_item_failed: '更新项目失败',
  txt_update_send_failed: '更新发送失败',
  txt_use_your_one_time_recovery_code_to_disable_two_step_verification: '使用一次性恢复代码禁用两步验证。',
  txt_user_deleted: '用户已删除',
  txt_user_status_updated: '用户状态已更新',
  txt_vault_synced: '保险库已同步',
  txt_verify: '验证',
  txt_web: '网页',
  txt_windows_desktop: 'Windows 桌面端',
  txt_jwt_warning_title: 'JWT_SECRET 配置警告',
  txt_jwt_warning_subtitle: 'JWT 密钥当前不安全，请先修复后再继续。',
  txt_jwt_title_missing: '未检测到 JWT_SECRET',
  txt_jwt_title_too_short: 'JWT_SECRET 长度过短',
  txt_jwt_title_default: 'JWT_SECRET使用默认值',
  txt_jwt_reason_missing: '未检测到 JWT_SECRET。',
  txt_jwt_reason_default: 'JWT_SECRET 仍在使用默认示例值。',
  txt_jwt_reason_too_short: 'JWT_SECRET 长度过短，至少需要 {min} 位。',
  txt_jwt_how_to_fix_add: '处理步骤（添加 JWT_SECRET）',
  txt_jwt_how_to_fix_replace: '处理步骤（更换 JWT_SECRET）',
  txt_jwt_add_step_1: '使用下方 32 位随机生成器，复制一个新密钥。',
  txt_jwt_add_step_2: '到 Cloudflare 控制台 -> Workers 和 Pages -> 你的服务 -> 设置 -> 变量和机密，新增 JWT_SECRET。',
  txt_jwt_add_step_3: '保存并等待重新部署完成，然后刷新本页确认。',
  txt_jwt_replace_step_1: '使用下方 32 位随机生成器，生成更强的密钥（至少 {min} 位）。',
  txt_jwt_replace_step_2: '到 Cloudflare 控制台 -> Workers 和 Pages -> 你的服务 -> 设置 -> 变量和机密，替换 JWT_SECRET。',
  txt_jwt_replace_step_3: '保存并等待重新部署完成，然后刷新本页确认。',
  txt_how_to_fix: '处理步骤（添加 / 更换）',
  txt_jwt_fix_step_1: '你可以继续下一步，不影响使用。',
  txt_jwt_fix_step_2: '如果当前密钥不是强随机值，建议使用下方 32 位生成器。',
  txt_jwt_fix_step_3: '到 Cloudflare 控制台 -> Workers 和 Pages -> 你的服务 -> 设置 -> 变量和机密，更新 JWT_SECRET。',
  txt_jwt_fix_step_4: '保存并等待重新部署完成，然后刷新本页确认。',
  txt_random_secret_generator: '随机密钥生成器',
  txt_copied: '已复制',
};

zhCNOverrides.txt_lock = '\u9501\u5b9a';

messages['zh-CN'] = { ...messages.en, ...zhCNOverrides };

function resolveInitialLocale(): Locale {
  try {
    const saved = localStorage.getItem(LOCALE_STORAGE_KEY);
    if (saved === 'en' || saved === 'zh-CN') return saved;
  } catch {
    // ignore storage errors
  }
  if (typeof navigator !== 'undefined') {
    const langs = Array.isArray(navigator.languages) ? navigator.languages : [navigator.language];
    for (const lang of langs) {
      if (String(lang || '').toLowerCase().startsWith('zh')) return 'zh-CN';
    }
  }
  return 'en';
}

let locale: Locale = resolveInitialLocale();

export type I18nParams = Record<string, string | number | null | undefined>;

export function t(key: string, params?: I18nParams): string {
  const template = messages[locale][key] ?? key;
  if (!params) return template;
  return template.replace(/\{(\w+)\}/g, (_, name: string) => String(params[name] ?? ''));
}

export function getLocale(): Locale {
  return locale;
}

export function setLocale(next: Locale): void {
  locale = next;
  try {
    localStorage.setItem(LOCALE_STORAGE_KEY, next);
  } catch {
    // ignore storage errors
  }
}
