import * as chai from "chai";
import { chaiDom } from "../../../util/chai-dom.mjs";
import { initJSDOM } from "../../../util/jsdom.mjs";

let expect = chai.expect;
chai.use(chaiDom);

let Login;

describe("Login", function () {
	this.timeout(10000);

	before(function (done) {
		initJSDOM().then(() => {
			import("element-internals-polyfill")
				.then(() => import("../../../../source/components/form/login.mjs"))
				.then((module) => {
					Login = module.Login;
					done();
				})
				.catch((error) => done(error));
		});
	});

	beforeEach(() => {
		document.getElementById("mocks").innerHTML = "";
	});

	afterEach(() => {
		document.getElementById("mocks").innerHTML = "";
	});

	it("should create a monster-login element", function () {
		expect(document.createElement("monster-login")).is.instanceof(Login);
	});

	it("should respect the native hidden attribute on the host", function () {
		const login = document.createElement("monster-login");
		login.setAttribute("hidden", "");
		document.getElementById("mocks").appendChild(login);

		expect(login.hidden).to.be.true;
		expect(login.visible).to.be.false;
		expect(login.isVisible).to.be.false;
	});

	it("should hide and show the host with the public visibility API", function (done) {
		const login = document.createElement("monster-login");
		document.getElementById("mocks").appendChild(login);

		const states = [];
		login.addEventListener("monster-visibility-changed", (event) => {
			states.push(event.detail.visible);
		});

		setTimeout(() => {
			try {
				const username = login.shadowRoot.querySelector("input[name='username']");
				username.focus();

				login.hide();
			} catch (error) {
				done(error);
			}
		}, 150);

		setTimeout(() => {
			try {
				expect(login.hidden).to.be.true;
				expect(login.visible).to.be.false;

				login.show();

				setTimeout(() => {
					try {
						expect(login.hidden).to.be.false;
						expect(login.visible).to.be.true;
						expect(states).to.deep.equal([false, true]);
						done();
					} catch (error) {
						done(error);
					}
				}, 25);
			} catch (error) {
				done(error);
			}
		}, 200);
	});

	it("should keep host visibility separate from openLogin", function (done) {
		const login = document.createElement("monster-login");
		document.getElementById("mocks").appendChild(login);

		setTimeout(() => {
			try {
				login.hide();
				login.openLogin();

				expect(login.hidden).to.be.true;
				expect(login.visible).to.be.false;
				done();
			} catch (error) {
				done(error);
			}
		}, 150);
	});

	it("should show the custom collapse and close the login collapse", function (done) {
		const login = document.createElement("monster-login");
		document.getElementById("mocks").appendChild(login);

		setTimeout(() => {
			try {
				const loginCollapse = login.shadowRoot.querySelector(
					'[data-monster-role="login-collapse"]',
				);
				const customCollapse = login.shadowRoot.querySelector(
					'[data-monster-role="custom-collapse"]',
				);

				expect(loginCollapse.isOpen()).to.be.true;
				expect(customCollapse.isClosed()).to.be.true;

				const button = document.createElement("button");
				button.textContent = "Weiter";

				login.showCustomCollapse({
					header: "Hinweis",
					content: ["Manueller Inhalt", button],
					footer: "Footer",
				});

				setTimeout(() => {
					try {
						expect(customCollapse.isOpen()).to.be.true;
						expect(loginCollapse.isClosed()).to.be.true;
						expect(
							login.shadowRoot.getElementById("customCollapseHeader").textContent,
						).to.equal("Hinweis");
						expect(
							login.shadowRoot
								.getElementById("customCollapseContent")
								.textContent.includes("Manueller Inhalt"),
						).to.be.true;
						expect(
							login.shadowRoot
								.getElementById("customCollapseContent")
								.querySelector("button"),
						).to.equal(button);
						expect(
							login.shadowRoot.getElementById("customCollapseFooter").textContent,
						).to.equal("Footer");
						done();
					} catch (error) {
						done(error);
					}
				}, 700);
			} catch (error) {
				done(error);
			}
		}, 150);
	});
});
