/**
 * Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved.
 * Node module: @schukai/monster
 *
 * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
 * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
 *
 * For those who do not wish to adhere to the AGPLv3, a commercial license is available.
 * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
 * For more information about purchasing a commercial license, please contact Volker Schukai.
 *
 * SPDX-License-Identifier: AGPL-3.0
 */

import { instanceSymbol } from "../../constants.mjs";
import {
	assembleMethodSymbol,
	registerCustomElement,
} from "../../dom/customelement.mjs";
import { ATTRIBUTE_ROLE } from "../../dom/constants.mjs";
import { fireCustomEvent } from "../../dom/events.mjs";
import { getLocaleOfDocument } from "../../dom/locale.mjs";
import { isFunction, isObject, isString } from "../../types/is.mjs";
import { validateString } from "../../types/validate.mjs";
import { getGlobal } from "../../types/global.mjs";
import { PopperButton } from "./popper-button.mjs";
import { AccessibilityStyleSheet } from "../stylesheet/accessibility.mjs";
import "./form.mjs";
import "./field-set.mjs";
import "./password.mjs";
import "./message-state-button.mjs";

export { CredentialButton };

/**
 * @private
 * @type {symbol}
 */
const passwordElementSymbol = Symbol("passwordElement");
const passwordInputElementSymbol = Symbol("passwordInputElement");
const submitButtonElementSymbol = Symbol("submitButtonElement");
const formElementSymbol = Symbol("formElement");
const fieldSetElementSymbol = Symbol("fieldSetElement");
const inFlightSymbol = Symbol("inFlight");
const wiredSymbol = Symbol("wired");
const mutationObserverSymbol = Symbol("mutationObserver");
const formWiredSymbol = Symbol("formWired");
const passwordWiredSymbol = Symbol("passwordWired");

/**
 * A password credential button control.
 *
 * @fragments /fragments/components/form/credential-button/
 *
 * @example /examples/components/form/credential-button-simple
 * @example /examples/components/form/credential-button-retry
 *
 * @since 3.91.0
 * @copyright Volker Schukai
 * @summary A credential action button that opens a password or secret update flow in a controlled popper.
 * @fires monster-credential-submit
 * @fires monster-credential-successful
 * @fires monster-credential-failed
 */
class CredentialButton extends PopperButton {
	/**
	 * This method is called by the `instanceof` operator.
	 * @return {symbol}
	 */
	static get [instanceSymbol]() {
		return Symbol.for(
			"@schukai/monster/components/form/credential-button@@instance",
		);
	}

	/**
	 * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
	 * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
	 *
	 * The individual configuration values can be found in the table.
	 *
	 * @property {Object} templates Template definitions
	 * @property {string} templates.main Main template
	 * @property {Object} labels Label definitions
	 * @property {string} labels.button Button label
	 * @property {string} labels.title Field-set title
	 * @property {string} labels.password Password label
	 * @property {string} labels.description Description text
	 * @property {string} labels.submit Submit button label
	 * @property {string} labels.messageEmptyPassword Empty password message
	 * @property {string} labels.messageNotConfigured Not configured message
	 * @property {string} labels.messageSuccess Success message
	 * @property {string} labels.messageFailed Failure message
	 * @property {string} url API URL
	 * @property {Object} fetch Fetch options
	 * @property {string} fetch.redirect Fetch redirect option
	 * @property {string} fetch.method Fetch method
	 * @property {string} fetch.mode Fetch mode
	 * @property {string} fetch.credentials Fetch credentials
	 * @property {Object} fetch.headers Fetch headers
	 * @property {Object} mapping Mapping configuration
	 * @property {string} mapping.password Key for the password field in the payload
	 * @property {Object|Function} mapping.data Additional payload data or builder
	 * @property {Object} payload Payload configuration
	 * @property {string} payload.password Key for the password field in the payload
	 * @property {Object|Function} payload.data Additional payload data or builder
	 * @property {Object} placeholder Placeholder configuration
	 * @property {string} placeholder.password Password placeholder
	 * @property {Object} autocomplete Autocomplete configuration
	 * @property {string} autocomplete.password Password autocomplete
	 * @property {Object} classes Class definitions
	 * @property {Object} layout Layout configuration
	 * @property {string} layout.containerStyle Inline style for the container
	 * @property {string} layout.submitStyle Inline style for the submit button
	 * @property {number} timeoutForMessage Duration in milliseconds to show messages
	 * @property {number} timeoutForSuccess Duration in milliseconds for success state
	 * @property {Object} features Feature flags
	 * @property {boolean} features.closeOnSuccess Close popper on success
	 * @property {boolean} features.clearOnSuccess Clear password on success
	 */
	get defaults() {
		const base = super.defaults;
		const labels = getTranslations();
		return Object.assign({}, base, {
			templates: {
				main: getTemplate(),
			},
			labels,
			aria: Object.assign({}, base.aria, {
				label: labels.button,
			}),
			layout: {
				containerStyle: "width: 20rem;",
				submitStyle: "margin-top: var(--monster-space-4);",
			},
			url: "",
			fetch: {
				redirect: "error",
				method: "POST",
				mode: "same-origin",
				credentials: "same-origin",
				headers: {
					accept: "application/json",
					"content-type": "application/json",
				},
			},
			mapping: {},
			payload: {
				password: "password",
				data: null,
			},
			placeholder: {
				password: "",
			},
			autocomplete: {
				password: "new-password",
			},
			timeoutForMessage: 3500,
			timeoutForSuccess: 1200,
			features: {
				closeOnSuccess: true,
				clearOnSuccess: true,
			},
			content: getContentTemplate(labels),
		});
	}

	/**
	 * @return {CredentialButton}
	 */
	[assembleMethodSymbol]() {
		super[assembleMethodSymbol]();
		initControlReferences.call(this);
		initEventHandler.call(this);
		return this;
	}

	/**
	 * @return {string}
	 */
	static getTag() {
		return "monster-credential-button";
	}

	/**
	 * @return {CSSStyleSheet[]}
	 */
	static getCSSStyleSheet() {
		const styles = super.getCSSStyleSheet();
		styles.push(AccessibilityStyleSheet);
		return styles;
	}
}

/**
 * @private
 * @return {CredentialButton}
 */
function initControlReferences() {
	this[passwordElementSymbol] = this.shadowRoot.querySelector(
		`[${ATTRIBUTE_ROLE}=password]`,
	);
	this[submitButtonElementSymbol] = this.shadowRoot.querySelector(
		`[${ATTRIBUTE_ROLE}=submit-button]`,
	);
	this[formElementSymbol] = this.shadowRoot.querySelector(
		`[${ATTRIBUTE_ROLE}=form]`,
	);
	this[fieldSetElementSymbol] = this.shadowRoot.querySelector(
		`[${ATTRIBUTE_ROLE}=field-set]`,
	);
	return this;
}

/**
 * @private
 * @return {CredentialButton}
 */
function initEventHandler() {
	const wireUp = () => {
		initControlReferences.call(this);

		if (this[formElementSymbol]) {
			if (!this[formWiredSymbol]) {
				this[formWiredSymbol] = true;
				this[formElementSymbol].addEventListener("keydown", (event) => {
					if (event.key === "Enter") {
						this[submitButtonElementSymbol]?.click?.();
					}
				});
			}
		}

		if (this[fieldSetElementSymbol]) {
			const title = this.getOption("labels.title");
			if (title !== undefined) {
				this[fieldSetElementSymbol].setOption("labels.title", title);
			}
		}

		if (this[passwordElementSymbol]) {
			const input =
				this[passwordElementSymbol]?.shadowRoot?.querySelector?.("input");
			if (input instanceof HTMLElement) {
				this[passwordInputElementSymbol] = input;
			}
			if (this[passwordInputElementSymbol] && !this[passwordWiredSymbol]) {
				this[passwordWiredSymbol] = true;
				const sync = () => {
					const value = this[passwordElementSymbol]?.value ?? "";
					this.value = value;
					fireCustomEvent(this, "monster-change", { value });
					this.dispatchEvent(
						new Event("input", { bubbles: true, composed: true }),
					);
				};
				this[passwordInputElementSymbol].addEventListener("input", sync);
				this[passwordInputElementSymbol].addEventListener("change", () => {
					this.dispatchEvent(
						new Event("change", { bubbles: true, composed: true }),
					);
				});
			}
		}

		if (!this[submitButtonElementSymbol] || this[wiredSymbol]) {
			return;
		}

		this[wiredSymbol] = true;
		this[submitButtonElementSymbol].setOption("actions.click", () => {
			handleSubmit.call(this);
		});
	};

	queueMicrotask(wireUp);

	if (!this[mutationObserverSymbol]) {
		this[mutationObserverSymbol] = new MutationObserver(() => {
			wireUp();
		});
		this[mutationObserverSymbol].observe(this.shadowRoot, {
			childList: true,
			subtree: true,
		});
	}

	return this;
}

/**
 * @private
 */
function handleSubmit() {
	if (this[inFlightSymbol]) {
		return;
	}

	const password = this[passwordElementSymbol]?.value;
	const timeout = this.getOption("timeoutForMessage");

	if (!password) {
		this[submitButtonElementSymbol].setMessage(
			this.getOption("labels.messageEmptyPassword"),
		);
		this[submitButtonElementSymbol].showMessage(timeout);
		this[submitButtonElementSymbol].setState("failed", timeout);
		queueMicrotask(() => this[passwordElementSymbol]?.focus?.());
		return;
	}

	this.value = password;
	this.dispatchEvent(new Event("change", { bubbles: true, composed: true }));

	let url = this.getOption("url") || this.getOption("fetch.url");
	if (isString(url)) {
		url = validateString(url);
	}

	const mapping = this.getOption("mapping");
	const passwordField =
		mapping?.password || this.getOption("payload.password") || "password";
	let payload = { [passwordField]: password };
	let extraPayload = mapping?.data ?? this.getOption("payload.data");
	if (isFunction(extraPayload)) {
		extraPayload = extraPayload({ password, element: this });
	}
	if (isObject(extraPayload)) {
		payload = Object.assign({}, extraPayload, payload);
	}

	if (!url) {
		const timeoutSuccess = this.getOption("timeoutForSuccess");
		this[submitButtonElementSymbol].setState("successful", timeoutSuccess);
		const successMessage = this.getOption("labels.messageSuccess");
		if (successMessage) {
			this[submitButtonElementSymbol].setMessage(successMessage);
			this[submitButtonElementSymbol].showMessage(timeout);
		}
		if (this.getOption("features.clearOnSuccess")) {
			this[passwordElementSymbol].value = "";
		}
		if (this.getOption("features.closeOnSuccess")) {
			setTimeout(() => {
				this.hideDialog();
			}, timeoutSuccess);
		}
		fireCustomEvent(this, "monster-credential-successful", {
			password,
			payload,
			url: null,
			local: true,
		});
		return;
	}

	const fetchOptions = Object.assign({}, this.getOption("fetch"));
	if (fetchOptions.url) {
		delete fetchOptions.url;
	}
	fetchOptions.headers = isObject(fetchOptions.headers)
		? Object.assign({}, fetchOptions.headers)
		: {};
	if (!fetchOptions.headers.accept) {
		fetchOptions.headers.accept = "application/json";
	}
	if (!fetchOptions.headers["content-type"]) {
		fetchOptions.headers["content-type"] = "application/json";
	}
	fetchOptions.body = JSON.stringify(payload);

	this[inFlightSymbol] = true;
	this[submitButtonElementSymbol].setState("activity");

	fireCustomEvent(this, "monster-credential-submit", {
		password,
		payload,
		url,
	});

	const global = getGlobal();
	global
		.fetch(url, fetchOptions)
		.then((response) => {
			if (!response.ok) {
				return Promise.reject(response);
			}

			const timeoutSuccess = this.getOption("timeoutForSuccess");
			this[submitButtonElementSymbol].setState("successful", timeoutSuccess);

			const successMessage = this.getOption("labels.messageSuccess");
			if (successMessage) {
				this[submitButtonElementSymbol].setMessage(successMessage);
				this[submitButtonElementSymbol].showMessage(timeout);
			}

			if (this.getOption("features.clearOnSuccess")) {
				this[passwordElementSymbol].value = "";
			}

			if (this.getOption("features.closeOnSuccess")) {
				setTimeout(() => {
					this.hideDialog();
				}, timeoutSuccess);
			}

			fireCustomEvent(this, "monster-credential-successful", {
				password,
				payload,
				url,
				response,
			});

			return response;
		})
		.catch((error) => {
			const message = this.getOption("labels.messageFailed");
			this[submitButtonElementSymbol].setMessage(message);
			this[submitButtonElementSymbol].showMessage(timeout);
			this[submitButtonElementSymbol].setState("failed", timeout);

			fireCustomEvent(this, "monster-credential-failed", {
				password,
				payload,
				url,
				error,
			});
		})
		.finally(() => {
			this[inFlightSymbol] = false;
		});
}

function getTranslations() {
	const locale = getLocaleOfDocument();
	switch (locale.language) {
		case "de":
			return {
				button: "Passwort ändern",
				title: "Passwort ändern",
				password: "Neues Passwort",
				description:
					"Wählen Sie ein sicheres Passwort, damit Ihr Konto gut geschützt ist. Es könnte aus Groß- und Kleinbuchstaben, Zahlen und Sonderzeichen bestehen. Auch wäre es besser, kein leicht zu erratendes Wort wie einen Namen oder ein Geburtsdatum zu verwenden.",
				submit: "Passwort ändern",
				messageEmptyPassword: "Bitte geben Sie ein neues Passwort ein",
				messageNotConfigured: "Dieses Formular ist nicht konfiguriert.",
				messageSuccess: "Passwort wurde erfolgreich geändert.",
				messageFailed:
					"Etwas ist schief gelaufen, bitte versuchen Sie es später erneut",
			};
		case "es":
			return {
				button: "Cambiar contraseña",
				title: "Cambiar contraseña",
				password: "Nueva contraseña",
				description:
					"Elige una contraseña segura para proteger tu cuenta. Usa una combinación de mayúsculas, minúsculas, números y símbolos. Evita palabras fáciles de adivinar como nombres o fechas de nacimiento.",
				submit: "Cambiar contraseña",
				messageEmptyPassword: "Por favor ingrese una nueva contraseña",
				messageNotConfigured: "Este formulario no está configurado.",
				messageSuccess: "La contraseña se cambió correctamente.",
				messageFailed: "Algo salió mal, por favor intenta de nuevo más tarde.",
			};
		case "zh":
			return {
				button: "更改密码",
				title: "更改密码",
				password: "新密码",
				description:
					"请选择一个安全密码以保护您的账户。建议包含大小写字母、数字和符号。避免使用容易猜到的词语，例如姓名或生日。",
				submit: "更改密码",
				messageEmptyPassword: "请输入新密码",
				messageNotConfigured: "此表单尚未配置。",
				messageSuccess: "密码修改成功。",
				messageFailed: "出了点问题，请稍后再试。",
			};
		case "hi":
			return {
				button: "पासवर्ड बदलें",
				title: "पासवर्ड बदलें",
				password: "नया पासवर्ड",
				description:
					"अपने खाते की सुरक्षा के लिए एक मजबूत पासवर्ड चुनें। इसमें बड़े/छोटे अक्षर, संख्या और प्रतीक शामिल करें। नाम या जन्मतिथि जैसे आसानी से अनुमानित शब्दों से बचें।",
				submit: "पासवर्ड बदलें",
				messageEmptyPassword: "कृपया नया पासवर्ड दर्ज करें",
				messageNotConfigured: "यह फॉर्म कॉन्फ़िगर नहीं है।",
				messageSuccess: "पासवर्ड सफलतापूर्वक बदल दिया गया है।",
				messageFailed: "कुछ गलत हुआ, कृपया बाद में फिर से प्रयास करें।",
			};
		case "bn":
			return {
				button: "পাসওয়ার্ড পরিবর্তন করুন",
				title: "পাসওয়ার্ড পরিবর্তন করুন",
				password: "নতুন পাসওয়ার্ড",
				description:
					"আপনার অ্যাকাউন্ট সুরক্ষিত রাখতে একটি শক্তিশালী পাসওয়ার্ড বেছে নিন। বড় ও ছোট হাতের অক্ষর, সংখ্যা এবং প্রতীক ব্যবহার করুন। নাম বা জন্মতারিখের মতো সহজে অনুমানযোগ্য শব্দ এড়িয়ে চলুন।",
				submit: "পাসওয়ার্ড পরিবর্তন করুন",
				messageEmptyPassword: "অনুগ্রহ করে একটি নতুন পাসওয়ার্ড লিখুন",
				messageNotConfigured: "এই ফর্মটি কনফিগার করা হয়নি।",
				messageSuccess: "পাসওয়ার্ড সফলভাবে পরিবর্তন হয়েছে।",
				messageFailed: "কিছু ভুল হয়েছে, পরে আবার চেষ্টা করুন।",
			};
		case "pt":
			return {
				button: "Alterar senha",
				title: "Alterar senha",
				password: "Nova senha",
				description:
					"Escolha uma senha forte para manter sua conta segura. Use letras maiúsculas e minúsculas, números e símbolos. Evite palavras fáceis de adivinhar, como nomes ou datas de nascimento.",
				submit: "Alterar senha",
				messageEmptyPassword: "Por favor, insira uma nova senha",
				messageNotConfigured: "Este formulário não está configurado.",
				messageSuccess: "Senha alterada com sucesso.",
				messageFailed: "Algo deu errado, tente novamente mais tarde.",
			};
		case "ru":
			return {
				button: "Изменить пароль",
				title: "Изменить пароль",
				password: "Новый пароль",
				description:
					"Выберите надежный пароль, чтобы защитить учетную запись. Используйте заглавные и строчные буквы, цифры и символы. Избегайте легко угадываемых слов, таких как имена или даты рождения.",
				submit: "Изменить пароль",
				messageEmptyPassword: "Пожалуйста, введите новый пароль",
				messageNotConfigured: "Эта форма не настроена.",
				messageSuccess: "Пароль успешно изменен.",
				messageFailed: "Что-то пошло не так, попробуйте позже.",
			};
		case "ja":
			return {
				button: "パスワードを変更",
				title: "パスワードを変更",
				password: "新しいパスワード",
				description:
					"アカウントを安全に保つため、強力なパスワードを設定してください。大文字・小文字、数字、記号を組み合わせ、名前や誕生日など推測しやすい語は避けてください。",
				submit: "パスワードを変更",
				messageEmptyPassword: "新しいパスワードを入力してください",
				messageNotConfigured: "このフォームは設定されていません。",
				messageSuccess: "パスワードを変更しました。",
				messageFailed: "問題が発生しました。後でもう一度お試しください。",
			};
		case "pa":
			return {
				button: "ਪਾਸਵਰਡ ਬਦਲੋ",
				title: "ਪਾਸਵਰਡ ਬਦਲੋ",
				password: "ਨਵਾਂ ਪਾਸਵਰਡ",
				description:
					"ਆਪਣਾ ਖਾਤਾ ਸੁਰੱਖਿਅਤ ਰੱਖਣ ਲਈ ਇੱਕ ਮਜ਼ਬੂਤ ਪਾਸਵਰਡ ਚੁਣੋ। ਵੱਡੇ/ਛੋਟੇ ਅੱਖਰ, ਅੰਕ ਅਤੇ ਚਿੰਨ੍ਹ ਵਰਤੋ। ਨਾਮ ਜਾਂ ਜਨਮ ਤਾਰੀਖ ਵਰਗੇ ਆਸਾਨੀ ਨਾਲ ਅਨੁਮਾਨਯੋਗ ਸ਼ਬਦਾਂ ਤੋਂ ਬਚੋ।",
				submit: "ਪਾਸਵਰਡ ਬਦਲੋ",
				messageEmptyPassword: "ਕਿਰਪਾ ਕਰਕੇ ਨਵਾਂ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ",
				messageNotConfigured: "ਇਹ ਫਾਰਮ ਸੰਰਚਿਤ ਨਹੀਂ ਹੈ।",
				messageSuccess: "ਪਾਸਵਰਡ ਸਫਲਤਾਪੂਰਵਕ ਬਦਲਿਆ ਗਿਆ।",
				messageFailed: "ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ, ਕਿਰਪਾ ਕਰਕੇ ਬਾਅਦ ਵਿੱਚ ਕੋਸ਼ਿਸ਼ ਕਰੋ।",
			};
		case "mr":
			return {
				button: "पासवर्ड बदला",
				title: "पासवर्ड बदला",
				password: "नवीन पासवर्ड",
				description:
					"आपले खाते सुरक्षित ठेवण्यासाठी मजबूत पासवर्ड निवडा. मोठी/लहान अक्षरे, संख्या आणि चिन्हे वापरा. नाव किंवा जन्मतारीखसारखे सहज अंदाज लावता येणारे शब्द टाळा.",
				submit: "पासवर्ड बदला",
				messageEmptyPassword: "कृपया नवीन पासवर्ड प्रविष्ट करा",
				messageNotConfigured: "हा फॉर्म कॉन्फिगर केलेला नाही.",
				messageSuccess: "पासवर्ड यशस्वीरित्या बदलला.",
				messageFailed: "काहीतरी चूक झाली, कृपया नंतर पुन्हा प्रयत्न करा.",
			};
		case "fr":
			return {
				button: "Changer le mot de passe",
				title: "Changer le mot de passe",
				password: "Nouveau mot de passe",
				description:
					"Choisissez un mot de passe fort pour protéger votre compte. Utilisez des majuscules, minuscules, chiffres et symboles. Évitez les mots faciles à deviner comme des noms ou des dates de naissance.",
				submit: "Changer le mot de passe",
				messageEmptyPassword: "Veuillez saisir un nouveau mot de passe",
				messageNotConfigured: "Ce formulaire n'est pas configuré.",
				messageSuccess: "Mot de passe modifié avec succès.",
				messageFailed:
					"Une erreur s'est produite, veuillez réessayer plus tard.",
			};
		case "it":
			return {
				button: "Cambia password",
				title: "Cambia password",
				password: "Nuova password",
				description:
					"Scegli una password sicura per proteggere il tuo account. Usa lettere maiuscole e minuscole, numeri e simboli. Evita parole facili da indovinare come nomi o date di nascita.",
				submit: "Cambia password",
				messageEmptyPassword: "Per favore, inserisci una nuova password",
				messageNotConfigured: "Questo modulo non è configurato.",
				messageSuccess: "Password aggiornata con successo.",
				messageFailed: "Qualcosa è andato storto, riprova più tardi.",
			};
		case "nl":
			return {
				button: "Wachtwoord wijzigen",
				title: "Wachtwoord wijzigen",
				password: "Nieuw wachtwoord",
				description:
					"Kies een sterk wachtwoord om je account te beveiligen. Gebruik hoofdletters, kleine letters, cijfers en symbolen. Vermijd gemakkelijk te raden woorden zoals namen of geboortedata.",
				submit: "Wachtwoord wijzigen",
				messageEmptyPassword: "Voer een nieuw wachtwoord in",
				messageNotConfigured: "Dit formulier is niet geconfigureerd.",
				messageSuccess: "Wachtwoord succesvol gewijzigd.",
				messageFailed: "Er is iets misgegaan, probeer het later opnieuw.",
			};
		case "sv":
			return {
				button: "Ändra lösenord",
				title: "Ändra lösenord",
				password: "Nytt lösenord",
				description:
					"Välj ett starkt lösenord för att skydda ditt konto. Använd stora och små bokstäver, siffror och symboler. Undvik lättgissade ord som namn eller födelsedatum.",
				submit: "Ändra lösenord",
				messageEmptyPassword: "Ange ett nytt lösenord",
				messageNotConfigured: "Det här formuläret är inte konfigurerat.",
				messageSuccess: "Lösenordet har ändrats.",
				messageFailed: "Något gick fel, försök igen senare.",
			};
		case "pl":
			return {
				button: "Zmień hasło",
				title: "Zmień hasło",
				password: "Nowe hasło",
				description:
					"Wybierz silne hasło, aby chronić swoje konto. Używaj wielkich i małych liter, cyfr oraz symboli. Unikaj łatwych do odgadnięcia słów, takich jak imiona czy daty urodzenia.",
				submit: "Zmień hasło",
				messageEmptyPassword: "Wpisz nowe hasło",
				messageNotConfigured: "Ten formularz nie jest skonfigurowany.",
				messageSuccess: "Hasło zostało zmienione.",
				messageFailed: "Coś poszło nie tak, spróbuj ponownie później.",
			};
		case "da":
			return {
				button: "Skift adgangskode",
				title: "Skift adgangskode",
				password: "Ny adgangskode",
				description:
					"Vælg en stærk adgangskode for at beskytte din konto. Brug store og små bogstaver, tal og symboler. Undgå let gættelige ord som navne eller fødselsdatoer.",
				submit: "Skift adgangskode",
				messageEmptyPassword: "Indtast en ny adgangskode",
				messageNotConfigured: "Denne formular er ikke konfigureret.",
				messageSuccess: "Adgangskoden er ændret.",
				messageFailed: "Noget gik galt, prøv igen senere.",
			};
		case "no":
			return {
				button: "Endre passord",
				title: "Endre passord",
				password: "Nytt passord",
				description:
					"Velg et sterkt passord for å beskytte kontoen din. Bruk store og små bokstaver, tall og symboler. Unngå lett gjettelige ord som navn eller fødselsdato.",
				submit: "Endre passord",
				messageEmptyPassword: "Skriv inn et nytt passord",
				messageNotConfigured: "Dette skjemaet er ikke konfigurert.",
				messageSuccess: "Passordet er endret.",
				messageFailed: "Noe gikk galt, prøv igjen senere.",
			};
		case "cs":
			return {
				button: "Změnit heslo",
				title: "Změnit heslo",
				password: "Nové heslo",
				description:
					"Zvolte silné heslo, aby byl váš účet v bezpečí. Použijte velká a malá písmena, čísla a symboly. Vyhněte se snadno uhodnutelným slovům, jako jsou jména nebo data narození.",
				submit: "Změnit heslo",
				messageEmptyPassword: "Zadejte nové heslo",
				messageNotConfigured: "Tento formulář není nakonfigurován.",
				messageSuccess: "Heslo bylo úspěšně změněno.",
				messageFailed: "Něco se pokazilo, zkuste to prosím později.",
			};
		default:
		case "en":
			return {
				button: "Change password",
				title: "Change password",
				password: "New password",
				description:
					"Choose a strong password to keep your account secure. Use a mix of upper- and lowercase letters, numbers, and symbols. Avoid easy-to-guess words like names or birthdays.",
				submit: "Change password",
				messageEmptyPassword: "Please enter a new password",
				messageNotConfigured: "This form is not configured.",
				messageSuccess: "Password updated successfully.",
				messageFailed: "Something went wrong. Please try again later.",
			};
	}
}

/**
 * @private
 * @return {string}
 */
function getContentTemplate(labels) {
	const title = labels?.title ?? "";
	const password = labels?.password ?? "";
	const description = labels?.description ?? "";
	const submit = labels?.submit ?? "";
	// language=HTML
	return `
        <div data-monster-role="container" part="container"
             data-monster-attributes="style path:layout.containerStyle">
            <monster-form data-monster-role="form">
                <monster-field-set
                    part="field-set"
                    data-monster-role="field-set"
                    data-monster-option-labels-title="${title}">
                    <label part="password-label">${password}</label>
                    <monster-password part="password"
                        data-monster-role="password"
                        data-monster-attributes="data-monster-option-placeholder path:placeholder.password,
                                                data-monster-option-autocomplete path:autocomplete.password">
                    </monster-password>
                    <p part="description">${description}</p>
                    <monster-message-state-button
                        data-monster-role="submit-button"
                        part="submit-button"
                        data-monster-attributes="style path:layout.submitStyle">
                        ${submit}
                    </monster-message-state-button>
                </monster-field-set>
            </monster-form>
        </div>
    `;
}

/**
 * @private
 * @return {string}
 */
function getTemplate() {
	return `
        <div data-monster-role="control" part="control">
            <button data-monster-attributes="disabled path:disabled | if:true, class path:classes.button"
                    data-monster-role="button"
                    part="button"
                    aria-labelledby="monster-credential-button-aria-label"
                    data-monster-replace="path:labels.button"></button>
            <div id="monster-credential-button-aria-label"
                 class="visually-hidden" data-monster-replace="path:aria.label">change password</div>

            <div data-monster-role="popper" part="popper" tabindex="-1" class="monster-color-primary-1">
                <div data-monster-role="arrow"></div>
                <div part="content" class="flex" data-monster-replace="path:content"></div>
            </div>
        </div>
    `;
}

registerCustomElement(CredentialButton);
